From 8d7ae8a9a4370a1abe6f7677bf6c3d0634d62c29 Mon Sep 17 00:00:00 2001 From: Chris Bono Date: Fri, 8 Sep 2023 14:57:44 -0500 Subject: [PATCH 1/2] Enable Spring Pulsar with Spring Boot 3.2.x * Split the Pulsar dependencies into Spring Boot 3.0.x/3.1.x and 3.2.x variants * Add DockerCompose and Testcontainers support * Enhance the tests for Pulsar See gh-1296 --- .../SimpleDockerServiceResolver.java | 10 + ...gPulsarProjectGenerationConfiguration.java | 42 ++- start-site/src/main/resources/application.yml | 28 +- ...pringPulsarBinderBuildCustomizerTests.java | 62 ----- ...arProjectGenerationConfigurationTests.java | 249 ++++++++++++++++++ .../src/test/resources/compose/pulsar.yaml | 7 + 6 files changed, 322 insertions(+), 76 deletions(-) delete mode 100644 start-site/src/test/java/io/spring/start/site/extension/dependency/springpulsar/SpringPulsarBinderBuildCustomizerTests.java create mode 100644 start-site/src/test/java/io/spring/start/site/extension/dependency/springpulsar/SpringPulsarProjectGenerationConfigurationTests.java create mode 100644 start-site/src/test/resources/compose/pulsar.yaml diff --git a/start-site/src/main/java/io/spring/start/site/container/SimpleDockerServiceResolver.java b/start-site/src/main/java/io/spring/start/site/container/SimpleDockerServiceResolver.java index 7efbf0cdbb7..0be1c0f4341 100644 --- a/start-site/src/main/java/io/spring/start/site/container/SimpleDockerServiceResolver.java +++ b/start-site/src/main/java/io/spring/start/site/container/SimpleDockerServiceResolver.java @@ -42,6 +42,7 @@ public SimpleDockerServiceResolver() { this.dockerServices.put("mysql", mysql()); this.dockerServices.put("oracle", oracle()); this.dockerServices.put("postgres", postgres()); + this.dockerServices.put("pulsar", pulsar()); this.dockerServices.put("rabbit", rabbit()); this.dockerServices.put("redis", redis()); this.dockerServices.put("sqlServer", sqlServer()); @@ -103,6 +104,15 @@ private static DockerService postgres() { .build(); } + private static DockerService pulsar() { + // The latest tag they provide is not the 'latest' GA + return DockerService.withImageAndTag("apachepulsar/pulsar:3.1.0") + .website("https://hub.docker.com/r/apachepulsar/pulsar") + .command("bin/pulsar standalone") + .ports(8080, 6650) + .build(); + } + private static DockerService rabbit() { return DockerService.withImageAndTag("rabbitmq") .website("https://hub.docker.com/_/rabbitmq") diff --git a/start-site/src/main/java/io/spring/start/site/extension/dependency/springpulsar/SpringPulsarProjectGenerationConfiguration.java b/start-site/src/main/java/io/spring/start/site/extension/dependency/springpulsar/SpringPulsarProjectGenerationConfiguration.java index 38fc039d8b5..39a7ef91d7c 100644 --- a/start-site/src/main/java/io/spring/start/site/extension/dependency/springpulsar/SpringPulsarProjectGenerationConfiguration.java +++ b/start-site/src/main/java/io/spring/start/site/extension/dependency/springpulsar/SpringPulsarProjectGenerationConfiguration.java @@ -16,12 +16,21 @@ package io.spring.start.site.extension.dependency.springpulsar; +import io.spring.initializr.generator.condition.ConditionalOnPlatformVersion; import io.spring.initializr.generator.condition.ConditionalOnRequestedDependency; +import io.spring.initializr.generator.condition.ProjectGenerationCondition; import io.spring.initializr.generator.project.ProjectDescription; import io.spring.initializr.generator.project.ProjectGenerationConfiguration; import io.spring.initializr.metadata.InitializrMetadata; +import io.spring.start.site.container.ComposeFileCustomizer; +import io.spring.start.site.container.DockerServiceResolver; +import io.spring.start.site.container.ServiceConnections; +import io.spring.start.site.container.ServiceConnectionsCustomizer; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ConditionContext; +import org.springframework.context.annotation.Conditional; +import org.springframework.core.type.AnnotatedTypeMetadata; /** * Configuration for generation of projects that depend on Pulsar. @@ -29,14 +38,45 @@ * @author Chris Bono */ @ProjectGenerationConfiguration -@ConditionalOnRequestedDependency("pulsar") +@Conditional(SpringPulsarProjectGenerationConfiguration.OnPulsarRequestedDependencyCondition.class) class SpringPulsarProjectGenerationConfiguration { + private static final String TESTCONTAINERS_CLASS_NAME = "org.testcontainers.containers.PulsarContainer"; + + @Bean + @ConditionalOnPlatformVersion("3.2.0-SNAPSHOT") + @ConditionalOnRequestedDependency("testcontainers") + ServiceConnectionsCustomizer pulsarServiceConnectionsCustomizer(DockerServiceResolver serviceResolver) { + return (serviceConnections) -> serviceResolver.doWith("pulsar", + (service) -> serviceConnections.addServiceConnection(ServiceConnections.ServiceConnection + .ofContainer("pulsar", service, TESTCONTAINERS_CLASS_NAME, false))); + } + @Bean + @ConditionalOnPlatformVersion("3.2.0-SNAPSHOT") + @ConditionalOnRequestedDependency("docker-compose") + ComposeFileCustomizer pulsarComposeFileCustomizer(DockerServiceResolver serviceResolver) { + return (composeFile) -> serviceResolver.doWith("pulsar", + (service) -> composeFile.services().add("pulsar", service)); + } + + @Bean + @ConditionalOnPlatformVersion("[3.0.0,3.2.0-M1)") @ConditionalOnRequestedDependency("cloud-stream") SpringPulsarBinderBuildCustomizer pulsarBinderBuildCustomizer(InitializrMetadata metadata, ProjectDescription description) { return new SpringPulsarBinderBuildCustomizer(metadata, description); } + static class OnPulsarRequestedDependencyCondition extends ProjectGenerationCondition { + + @Override + protected boolean matches(ProjectDescription description, ConditionContext context, + AnnotatedTypeMetadata metadata) { + return description.getRequestedDependencies().containsKey("pulsar") + || description.getRequestedDependencies().containsKey("pulsar-reactive"); + } + + } + } diff --git a/start-site/src/main/resources/application.yml b/start-site/src/main/resources/application.yml index 1535c828c69..0cc52470bf2 100644 --- a/start-site/src/main/resources/application.yml +++ b/start-site/src/main/resources/application.yml @@ -786,30 +786,32 @@ initializr: href: https://docs.spring.io/spring-boot/docs/{bootVersion}/reference/htmlsingle/index.html#messaging.jms.artemis - name: Spring for Apache Pulsar id: pulsar - compatibilityRange: "[3.0.0,3.2.0-M1)" - mappings: - - compatibilityRange: "[3.0.0,3.2.0-M1)" - version: 0.2.0 + compatibilityRange: "[3.0.0,3.2.0-SNAPSHOT]" description: Build messaging applications with Apache Pulsar - groupId: org.springframework.pulsar - artifactId: spring-pulsar-spring-boot-starter links: - rel: reference - href: https://docs.spring.io/spring-pulsar/docs/0.2.x/reference/html/ - - name: Spring for Apache Pulsar (Reactive) - id: pulsar-reactive - compatibilityRange: "[3.0.0,3.2.0-M1)" + href: https://docs.spring.io/spring-boot/docs/{bootVersion}/reference/htmlsingle/index.html#messaging.pulsar mappings: - compatibilityRange: "[3.0.0,3.2.0-M1)" version: 0.2.0 + groupId: org.springframework.pulsar + artifactId: spring-pulsar-spring-boot-starter + starter: false + - name: Spring for Apache Pulsar (Reactive) + id: pulsar-reactive + compatibilityRange: "[3.0.0,3.2.0-SNAPSHOT]" description: Build reactive messaging applications with Apache Pulsar facets: - reactive - groupId: org.springframework.pulsar - artifactId: spring-pulsar-reactive-spring-boot-starter links: - rel: reference - href: https://docs.spring.io/spring-pulsar/docs/0.2.x/reference/html/#reactive-pulsar + href: https://docs.spring.io/spring-boot/docs/{bootVersion}/reference/htmlsingle/index.html#messaging.pulsar + mappings: + - compatibilityRange: "[3.0.0,3.2.0-M1)" + version: 0.2.0 + groupId: org.springframework.pulsar + artifactId: spring-pulsar-reactive-spring-boot-starter + starter: false - name: WebSocket id: websocket description: Build Servlet-based WebSocket applications with SockJS and STOMP. diff --git a/start-site/src/test/java/io/spring/start/site/extension/dependency/springpulsar/SpringPulsarBinderBuildCustomizerTests.java b/start-site/src/test/java/io/spring/start/site/extension/dependency/springpulsar/SpringPulsarBinderBuildCustomizerTests.java deleted file mode 100644 index 62c7b2ac408..00000000000 --- a/start-site/src/test/java/io/spring/start/site/extension/dependency/springpulsar/SpringPulsarBinderBuildCustomizerTests.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2012-2023 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.spring.start.site.extension.dependency.springpulsar; - -import io.spring.initializr.generator.test.project.ProjectStructure; -import io.spring.initializr.web.project.ProjectRequest; -import io.spring.start.site.extension.AbstractExtensionTests; -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link SpringPulsarBinderBuildCustomizer}. - * - * @author Chris Bono - */ -class SpringPulsarBinderBuildCustomizerTests extends AbstractExtensionTests { - - @Test - void binderNotAddedWhenPulsarNotSelected() { - ProjectStructure project = generateProject(createProjectRequest("cloud-stream")); - assertNoBinder(project); - } - - @Test - void binderNotAddedWhenCloudStreamNotSelected() { - ProjectRequest request = createProjectRequest("pulsar"); - request.setBootVersion("3.0.4"); - ProjectStructure project = generateProject(request); - assertNoBinder(project); - assertThat(project).mavenBuild().hasDependency(getDependency("pulsar")); - } - - @Test - void binderAddedWhenPulsarAndCloudStreamSelected() { - ProjectRequest request = createProjectRequest("pulsar", "cloud-stream"); - request.setBootVersion("3.0.4"); - ProjectStructure project = generateProject(request); - assertThat(project).mavenBuild() - .hasDependency("org.springframework.pulsar", "spring-pulsar-spring-cloud-stream-binder", "0.2.0"); - } - - private void assertNoBinder(ProjectStructure project) { - assertThat(project).mavenBuild() - .doesNotHaveDependency("org.springframework.pulsar", "spring-pulsar-spring-cloud-stream-binder"); - } - -} diff --git a/start-site/src/test/java/io/spring/start/site/extension/dependency/springpulsar/SpringPulsarProjectGenerationConfigurationTests.java b/start-site/src/test/java/io/spring/start/site/extension/dependency/springpulsar/SpringPulsarProjectGenerationConfigurationTests.java new file mode 100644 index 00000000000..d3d15139255 --- /dev/null +++ b/start-site/src/test/java/io/spring/start/site/extension/dependency/springpulsar/SpringPulsarProjectGenerationConfigurationTests.java @@ -0,0 +1,249 @@ +/* + * Copyright 2012-2023 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.spring.start.site.extension.dependency.springpulsar; + +import io.spring.initializr.generator.buildsystem.Dependency; +import io.spring.initializr.generator.project.MutableProjectDescription; +import io.spring.initializr.generator.test.project.ProjectAssetTester; +import io.spring.initializr.generator.test.project.ProjectStructure; +import io.spring.initializr.generator.version.Version; +import io.spring.initializr.web.project.ProjectRequest; +import io.spring.start.site.container.DockerServiceResolver; +import io.spring.start.site.container.ServiceConnections; +import io.spring.start.site.container.ServiceConnectionsCustomizer; +import io.spring.start.site.container.SimpleDockerServiceResolver; +import io.spring.start.site.extension.AbstractExtensionTests; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +import org.springframework.core.io.ClassPathResource; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; + +/** + * Tests for {@link SpringPulsarProjectGenerationConfiguration}. + * + * @author Chris Bono + */ +class SpringPulsarProjectGenerationConfigurationTests extends AbstractExtensionTests { + + @Nested + class PulsarDependencyConfigurationTests { + + @ParameterizedTest + @ValueSource(strings = { "3.0.0", "3.1.3" }) + void pulsarLegacyStarterUsedWhenBoot30orBoot31Selected(String bootVersion) { + ProjectRequest request = createProjectRequest("pulsar"); + request.setBootVersion(bootVersion); + ProjectStructure project = generateProject(request); + assertThat(project).mavenBuild() + .hasDependency("org.springframework.pulsar", "spring-pulsar-spring-boot-starter"); + } + + @ParameterizedTest + @ValueSource(strings = { "3.0.0", "3.1.3" }) + void pulsarReactiveLegacyStarterUsedWhenBoot30orBoot31Selected(String bootVersion) { + ProjectRequest request = createProjectRequest("pulsar-reactive"); + request.setBootVersion(bootVersion); + ProjectStructure project = generateProject(request); + assertThat(project).mavenBuild() + .hasDependency("org.springframework.pulsar", "spring-pulsar-reactive-spring-boot-starter"); + } + + @Test + void pulsarBootStarterUsedWhenBoot32Selected() { + ProjectRequest request = createProjectRequest("pulsar"); + request.setBootVersion("3.2.0-SNAPSHOT"); + ProjectStructure project = generateProject(request); + assertThat(project).mavenBuild().hasDependency("org.springframework.boot", "spring-boot-starter-pulsar"); + } + + @Test + void pulsarReactiveBootStarterUsedWhenBoot32Selected() { + ProjectRequest request = createProjectRequest("pulsar-reactive"); + request.setBootVersion("3.2.0-SNAPSHOT"); + ProjectStructure project = generateProject(request); + assertThat(project).mavenBuild() + .hasDependency("org.springframework.boot", "spring-boot-starter-pulsar-reactive"); + } + + } + + @Nested + class DockerComposeConfigurationTests { + + @Test + void serviceNotCreatedWhenDockerComposeNotSelected() { + ProjectRequest request = createProjectRequest("pulsar"); + request.setBootVersion("3.2.0-SNAPSHOT"); + ProjectStructure structure = generateProject(request); + assertThat(structure.getProjectDirectory().resolve("compose.yaml")).doesNotExist(); + } + + @ParameterizedTest + @ValueSource(strings = { "3.1.3", "3.2.0-M2" }) + void serviceNotCreatedWhenIncompatibleBootVersionSelected(String bootVersion) { + ProjectRequest request = createProjectRequest("docker-compose", "pulsar"); + request.setBootVersion(bootVersion); + assertThat(composeFile(request)).doesNotContain("pulsar"); + } + + @ParameterizedTest + @ValueSource(strings = { "pulsar", "pulsar-reactive" }) + void serviceCreatedWhenDockerComposeSelectedWithCompatibleBootVersion(String pulsarDependencyId) { + ProjectRequest request = createProjectRequest("docker-compose", pulsarDependencyId); + request.setBootVersion("3.2.0-SNAPSHOT"); + assertThat(composeFile(request)).hasSameContentAs(new ClassPathResource("compose/pulsar.yaml")); + } + + } + + @Nested + class ServiceConnectionConfigurationTests { + + private final ProjectAssetTester projectTester = new ProjectAssetTester() + .withConfiguration(SpringPulsarProjectGenerationConfiguration.class) + .withBean(DockerServiceResolver.class, () -> new SimpleDockerServiceResolver()); + + @Test + void connectionNotAddedWhenTestcontainersNotSelected() { + MutableProjectDescription description = new MutableProjectDescription(); + description.setPlatformVersion(Version.parse("3.2.0-SNAPSHOT")); + description.addDependency("pulsar", mock(Dependency.class)); + this.projectTester.configure(description, + (context) -> assertThat(context).doesNotHaveBean("pulsarServiceConnectionsCustomizer")); + } + + @Test + void connectionNotAddedWhenPulsarNotSelected() { + MutableProjectDescription description = new MutableProjectDescription(); + description.setPlatformVersion(Version.parse("3.2.0-SNAPSHOT")); + description.addDependency("testcontainers", mock(Dependency.class)); + this.projectTester.configure(description, + (context) -> assertThat(context).doesNotHaveBean("pulsarServiceConnectionsCustomizer")); + } + + @ParameterizedTest + @ValueSource(strings = { "3.0.0", "3.1.3" }) + void connectionNotAddedWhenIncompatibleBootVersionSelected(String bootVersion) { + MutableProjectDescription description = new MutableProjectDescription(); + description.setPlatformVersion(Version.parse(bootVersion)); + description.addDependency("pulsar", mock(Dependency.class)); + description.addDependency("testcontainers", mock(Dependency.class)); + this.projectTester.configure(description, + (context) -> assertThat(context).doesNotHaveBean("pulsarServiceConnectionsCustomizer")); + } + + @ParameterizedTest + @ValueSource(strings = { "pulsar", "pulsar-reactive" }) + void connectionAddedWhenTestcontainersAndPulsarSelectedWithCompatibleBootVersion(String pulsarDependencyId) { + MutableProjectDescription description = new MutableProjectDescription(); + description.setPlatformVersion(Version.parse("3.2.0-SNAPSHOT")); + description.addDependency("testcontainers", mock(Dependency.class)); + description.addDependency(pulsarDependencyId, mock(Dependency.class)); + this.projectTester.configure(description, + (context) -> assertThat(context) + .getBean("pulsarServiceConnectionsCustomizer", ServiceConnectionsCustomizer.class) + .satisfies((customizer) -> { + ServiceConnections connections = new ServiceConnections(); + customizer.customize(connections); + assertPulsarServiceConnectionAddded(connections); + })); + } + + private void assertPulsarServiceConnectionAddded(ServiceConnections connections) { + assertThat(connections.values()).first().satisfies((connection) -> { + assertThat(connection.id()).isEqualTo("pulsar"); + assertThat(connection.containerClassName()).isEqualTo("org.testcontainers.containers.PulsarContainer"); + assertThat(connection.isGenericContainer()).isFalse(); + assertThat(connection.containerClassNameGeneric()).isFalse(); + assertThat(connection.dockerService()).satisfies((dockerService) -> { + assertThat(dockerService.getImage()).isEqualTo("apachepulsar/pulsar"); + assertThat(dockerService.getImageTag()).isEqualTo("3.1.0"); + assertThat(dockerService.getWebsite()).isEqualTo("https://hub.docker.com/r/apachepulsar/pulsar"); + assertThat(dockerService.getCommand()).isEqualTo("bin/pulsar standalone"); + assertThat(dockerService.getPorts()).containsExactlyInAnyOrder(8080, 6650); + }); + }); + } + + } + + @Nested + class SpringPulsarBinderConfigurationTests { + + @Test + void binderNotAddedWhenCloudStreamNotSelected() { + ProjectRequest request = createProjectRequest("pulsar"); + request.setBootVersion("3.1.3"); + ProjectStructure project = generateProject(request); + assertNoBinder(project); + assertThat(project).mavenBuild() + .hasDependency("org.springframework.pulsar", "spring-pulsar-spring-boot-starter"); + } + + @Test + void binderNotAddedWhenPulsarNotSelected() { + ProjectRequest request = createProjectRequest("cloud-stream"); + request.setBootVersion("3.1.3"); + ProjectStructure project = generateProject(request); + assertNoBinder(project); + } + + @ParameterizedTest + @ValueSource(strings = { "3.2.0-M1", "3.2.0-SNAPSHOT" }) + void binderNotAddedWhenPulsarAndCloudStreamSelectedWithIncompatibleBootVersion(String bootVersion) { + ProjectRequest request = createProjectRequest("pulsar", "cloud-stream"); + request.setBootVersion(bootVersion); + ProjectStructure project = generateProject(request); + assertNoBinder(project); + } + + @ParameterizedTest + @ValueSource(strings = { "3.0.0", "3.1.3", "3.1.4-SNAPSHOT" }) + void binderAddedWhenPulsarAndCloudStreamSelectedWithCompatibleBootVersion(String bootVersion) { + ProjectRequest request = createProjectRequest("pulsar", "cloud-stream"); + request.setBootVersion(bootVersion); + ProjectStructure project = generateProject(request); + assertBinder(project); + } + + @ParameterizedTest + @ValueSource(strings = { "3.0.0", "3.1.3", "3.1.4-SNAPSHOT" }) + void binderAddedWhenPulsarReactiveAndCloudStreamSelectedWithCompatibleBootVersion(String bootVersion) { + ProjectRequest request = createProjectRequest("pulsar-reactive", "cloud-stream"); + request.setBootVersion(bootVersion); + ProjectStructure project = generateProject(request); + assertBinder(project); + } + + private void assertNoBinder(ProjectStructure project) { + assertThat(project).mavenBuild() + .doesNotHaveDependency("org.springframework.pulsar", "spring-pulsar-spring-cloud-stream-binder"); + } + + private void assertBinder(ProjectStructure project) { + assertThat(project).mavenBuild() + .hasDependency("org.springframework.pulsar", "spring-pulsar-spring-cloud-stream-binder", "0.2.0"); + } + + } + +} diff --git a/start-site/src/test/resources/compose/pulsar.yaml b/start-site/src/test/resources/compose/pulsar.yaml new file mode 100644 index 00000000000..1bca13fe254 --- /dev/null +++ b/start-site/src/test/resources/compose/pulsar.yaml @@ -0,0 +1,7 @@ +services: + pulsar: + image: 'apachepulsar/pulsar:3.1.0' + ports: + - '6650' + - '8080' + command: 'bin/pulsar standalone' From a74c15e14a882249167bace384fca0c032099edf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Nicoll?= Date: Fri, 15 Sep 2023 09:57:25 +0200 Subject: [PATCH 2/2] Polish "Enable Spring Pulsar with Spring Boot 3.2.x" See gh-1296 --- ...gPulsarProjectGenerationConfiguration.java | 16 +++++++----- start-site/src/main/resources/application.yml | 8 +++--- ...arProjectGenerationConfigurationTests.java | 26 +++++++++---------- ...rsProjectGenerationConfigurationTests.java | 3 ++- 4 files changed, 28 insertions(+), 25 deletions(-) diff --git a/start-site/src/main/java/io/spring/start/site/extension/dependency/springpulsar/SpringPulsarProjectGenerationConfiguration.java b/start-site/src/main/java/io/spring/start/site/extension/dependency/springpulsar/SpringPulsarProjectGenerationConfiguration.java index 39a7ef91d7c..2760490fe6a 100644 --- a/start-site/src/main/java/io/spring/start/site/extension/dependency/springpulsar/SpringPulsarProjectGenerationConfiguration.java +++ b/start-site/src/main/java/io/spring/start/site/extension/dependency/springpulsar/SpringPulsarProjectGenerationConfiguration.java @@ -16,6 +16,9 @@ package io.spring.start.site.extension.dependency.springpulsar; +import java.util.Map; + +import io.spring.initializr.generator.buildsystem.Dependency; import io.spring.initializr.generator.condition.ConditionalOnPlatformVersion; import io.spring.initializr.generator.condition.ConditionalOnRequestedDependency; import io.spring.initializr.generator.condition.ProjectGenerationCondition; @@ -26,6 +29,7 @@ import io.spring.start.site.container.DockerServiceResolver; import io.spring.start.site.container.ServiceConnections; import io.spring.start.site.container.ServiceConnectionsCustomizer; +import io.spring.start.site.extension.dependency.springpulsar.SpringPulsarProjectGenerationConfiguration.OnPulsarDependencyCondition; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ConditionContext; @@ -38,13 +42,13 @@ * @author Chris Bono */ @ProjectGenerationConfiguration -@Conditional(SpringPulsarProjectGenerationConfiguration.OnPulsarRequestedDependencyCondition.class) +@Conditional(OnPulsarDependencyCondition.class) class SpringPulsarProjectGenerationConfiguration { private static final String TESTCONTAINERS_CLASS_NAME = "org.testcontainers.containers.PulsarContainer"; @Bean - @ConditionalOnPlatformVersion("3.2.0-SNAPSHOT") + @ConditionalOnPlatformVersion("3.2.0-M3") @ConditionalOnRequestedDependency("testcontainers") ServiceConnectionsCustomizer pulsarServiceConnectionsCustomizer(DockerServiceResolver serviceResolver) { return (serviceConnections) -> serviceResolver.doWith("pulsar", @@ -53,7 +57,7 @@ ServiceConnectionsCustomizer pulsarServiceConnectionsCustomizer(DockerServiceRes } @Bean - @ConditionalOnPlatformVersion("3.2.0-SNAPSHOT") + @ConditionalOnPlatformVersion("3.2.0-M3") @ConditionalOnRequestedDependency("docker-compose") ComposeFileCustomizer pulsarComposeFileCustomizer(DockerServiceResolver serviceResolver) { return (composeFile) -> serviceResolver.doWith("pulsar", @@ -68,13 +72,13 @@ SpringPulsarBinderBuildCustomizer pulsarBinderBuildCustomizer(InitializrMetadata return new SpringPulsarBinderBuildCustomizer(metadata, description); } - static class OnPulsarRequestedDependencyCondition extends ProjectGenerationCondition { + static class OnPulsarDependencyCondition extends ProjectGenerationCondition { @Override protected boolean matches(ProjectDescription description, ConditionContext context, AnnotatedTypeMetadata metadata) { - return description.getRequestedDependencies().containsKey("pulsar") - || description.getRequestedDependencies().containsKey("pulsar-reactive"); + Map requestedDependencies = description.getRequestedDependencies(); + return requestedDependencies.containsKey("pulsar") || requestedDependencies.containsKey("pulsar-reactive"); } } diff --git a/start-site/src/main/resources/application.yml b/start-site/src/main/resources/application.yml index 0cc52470bf2..91f7138ad57 100644 --- a/start-site/src/main/resources/application.yml +++ b/start-site/src/main/resources/application.yml @@ -786,20 +786,19 @@ initializr: href: https://docs.spring.io/spring-boot/docs/{bootVersion}/reference/htmlsingle/index.html#messaging.jms.artemis - name: Spring for Apache Pulsar id: pulsar - compatibilityRange: "[3.0.0,3.2.0-SNAPSHOT]" + compatibilityRange: "3.0.0" description: Build messaging applications with Apache Pulsar links: - rel: reference href: https://docs.spring.io/spring-boot/docs/{bootVersion}/reference/htmlsingle/index.html#messaging.pulsar mappings: - - compatibilityRange: "[3.0.0,3.2.0-M1)" + - compatibilityRange: "[3.0.0,3.2.0-M3)" version: 0.2.0 groupId: org.springframework.pulsar artifactId: spring-pulsar-spring-boot-starter - starter: false - name: Spring for Apache Pulsar (Reactive) id: pulsar-reactive - compatibilityRange: "[3.0.0,3.2.0-SNAPSHOT]" + compatibilityRange: "3.0.0" description: Build reactive messaging applications with Apache Pulsar facets: - reactive @@ -811,7 +810,6 @@ initializr: version: 0.2.0 groupId: org.springframework.pulsar artifactId: spring-pulsar-reactive-spring-boot-starter - starter: false - name: WebSocket id: websocket description: Build Servlet-based WebSocket applications with SockJS and STOMP. diff --git a/start-site/src/test/java/io/spring/start/site/extension/dependency/springpulsar/SpringPulsarProjectGenerationConfigurationTests.java b/start-site/src/test/java/io/spring/start/site/extension/dependency/springpulsar/SpringPulsarProjectGenerationConfigurationTests.java index d3d15139255..9a6090f01db 100644 --- a/start-site/src/test/java/io/spring/start/site/extension/dependency/springpulsar/SpringPulsarProjectGenerationConfigurationTests.java +++ b/start-site/src/test/java/io/spring/start/site/extension/dependency/springpulsar/SpringPulsarProjectGenerationConfigurationTests.java @@ -70,7 +70,7 @@ void pulsarReactiveLegacyStarterUsedWhenBoot30orBoot31Selected(String bootVersio @Test void pulsarBootStarterUsedWhenBoot32Selected() { ProjectRequest request = createProjectRequest("pulsar"); - request.setBootVersion("3.2.0-SNAPSHOT"); + request.setBootVersion("3.2.0-M3"); ProjectStructure project = generateProject(request); assertThat(project).mavenBuild().hasDependency("org.springframework.boot", "spring-boot-starter-pulsar"); } @@ -78,7 +78,7 @@ void pulsarBootStarterUsedWhenBoot32Selected() { @Test void pulsarReactiveBootStarterUsedWhenBoot32Selected() { ProjectRequest request = createProjectRequest("pulsar-reactive"); - request.setBootVersion("3.2.0-SNAPSHOT"); + request.setBootVersion("3.2.0-M3"); ProjectStructure project = generateProject(request); assertThat(project).mavenBuild() .hasDependency("org.springframework.boot", "spring-boot-starter-pulsar-reactive"); @@ -92,7 +92,7 @@ class DockerComposeConfigurationTests { @Test void serviceNotCreatedWhenDockerComposeNotSelected() { ProjectRequest request = createProjectRequest("pulsar"); - request.setBootVersion("3.2.0-SNAPSHOT"); + request.setBootVersion("3.2.0-M3"); ProjectStructure structure = generateProject(request); assertThat(structure.getProjectDirectory().resolve("compose.yaml")).doesNotExist(); } @@ -109,7 +109,7 @@ void serviceNotCreatedWhenIncompatibleBootVersionSelected(String bootVersion) { @ValueSource(strings = { "pulsar", "pulsar-reactive" }) void serviceCreatedWhenDockerComposeSelectedWithCompatibleBootVersion(String pulsarDependencyId) { ProjectRequest request = createProjectRequest("docker-compose", pulsarDependencyId); - request.setBootVersion("3.2.0-SNAPSHOT"); + request.setBootVersion("3.2.0-M3"); assertThat(composeFile(request)).hasSameContentAs(new ClassPathResource("compose/pulsar.yaml")); } @@ -120,12 +120,12 @@ class ServiceConnectionConfigurationTests { private final ProjectAssetTester projectTester = new ProjectAssetTester() .withConfiguration(SpringPulsarProjectGenerationConfiguration.class) - .withBean(DockerServiceResolver.class, () -> new SimpleDockerServiceResolver()); + .withBean(DockerServiceResolver.class, SimpleDockerServiceResolver::new); @Test void connectionNotAddedWhenTestcontainersNotSelected() { MutableProjectDescription description = new MutableProjectDescription(); - description.setPlatformVersion(Version.parse("3.2.0-SNAPSHOT")); + description.setPlatformVersion(Version.parse("3.2.0-M3")); description.addDependency("pulsar", mock(Dependency.class)); this.projectTester.configure(description, (context) -> assertThat(context).doesNotHaveBean("pulsarServiceConnectionsCustomizer")); @@ -134,7 +134,7 @@ void connectionNotAddedWhenTestcontainersNotSelected() { @Test void connectionNotAddedWhenPulsarNotSelected() { MutableProjectDescription description = new MutableProjectDescription(); - description.setPlatformVersion(Version.parse("3.2.0-SNAPSHOT")); + description.setPlatformVersion(Version.parse("3.2.0-M3")); description.addDependency("testcontainers", mock(Dependency.class)); this.projectTester.configure(description, (context) -> assertThat(context).doesNotHaveBean("pulsarServiceConnectionsCustomizer")); @@ -155,7 +155,7 @@ void connectionNotAddedWhenIncompatibleBootVersionSelected(String bootVersion) { @ValueSource(strings = { "pulsar", "pulsar-reactive" }) void connectionAddedWhenTestcontainersAndPulsarSelectedWithCompatibleBootVersion(String pulsarDependencyId) { MutableProjectDescription description = new MutableProjectDescription(); - description.setPlatformVersion(Version.parse("3.2.0-SNAPSHOT")); + description.setPlatformVersion(Version.parse("3.2.0-M3")); description.addDependency("testcontainers", mock(Dependency.class)); description.addDependency(pulsarDependencyId, mock(Dependency.class)); this.projectTester.configure(description, @@ -164,11 +164,11 @@ void connectionAddedWhenTestcontainersAndPulsarSelectedWithCompatibleBootVersion .satisfies((customizer) -> { ServiceConnections connections = new ServiceConnections(); customizer.customize(connections); - assertPulsarServiceConnectionAddded(connections); + assertPulsarServiceConnectionAdded(connections); })); } - private void assertPulsarServiceConnectionAddded(ServiceConnections connections) { + private void assertPulsarServiceConnectionAdded(ServiceConnections connections) { assertThat(connections.values()).first().satisfies((connection) -> { assertThat(connection.id()).isEqualTo("pulsar"); assertThat(connection.containerClassName()).isEqualTo("org.testcontainers.containers.PulsarContainer"); @@ -208,7 +208,7 @@ void binderNotAddedWhenPulsarNotSelected() { } @ParameterizedTest - @ValueSource(strings = { "3.2.0-M1", "3.2.0-SNAPSHOT" }) + @ValueSource(strings = { "3.2.0-M1", "3.2.0-M3" }) void binderNotAddedWhenPulsarAndCloudStreamSelectedWithIncompatibleBootVersion(String bootVersion) { ProjectRequest request = createProjectRequest("pulsar", "cloud-stream"); request.setBootVersion(bootVersion); @@ -217,7 +217,7 @@ void binderNotAddedWhenPulsarAndCloudStreamSelectedWithIncompatibleBootVersion(S } @ParameterizedTest - @ValueSource(strings = { "3.0.0", "3.1.3", "3.1.4-SNAPSHOT" }) + @ValueSource(strings = { "3.0.0", "3.1.3" }) void binderAddedWhenPulsarAndCloudStreamSelectedWithCompatibleBootVersion(String bootVersion) { ProjectRequest request = createProjectRequest("pulsar", "cloud-stream"); request.setBootVersion(bootVersion); @@ -226,7 +226,7 @@ void binderAddedWhenPulsarAndCloudStreamSelectedWithCompatibleBootVersion(String } @ParameterizedTest - @ValueSource(strings = { "3.0.0", "3.1.3", "3.1.4-SNAPSHOT" }) + @ValueSource(strings = { "3.0.0", "3.1.3" }) void binderAddedWhenPulsarReactiveAndCloudStreamSelectedWithCompatibleBootVersion(String bootVersion) { ProjectRequest request = createProjectRequest("pulsar-reactive", "cloud-stream"); request.setBootVersion(bootVersion); diff --git a/start-site/src/test/java/io/spring/start/site/extension/dependency/testcontainers/TestcontainersProjectGenerationConfigurationTests.java b/start-site/src/test/java/io/spring/start/site/extension/dependency/testcontainers/TestcontainersProjectGenerationConfigurationTests.java index fd87356cb0f..cfb811a1358 100644 --- a/start-site/src/test/java/io/spring/start/site/extension/dependency/testcontainers/TestcontainersProjectGenerationConfigurationTests.java +++ b/start-site/src/test/java/io/spring/start/site/extension/dependency/testcontainers/TestcontainersProjectGenerationConfigurationTests.java @@ -20,6 +20,7 @@ import io.spring.initializr.generator.test.io.TextAssert; import io.spring.initializr.generator.test.project.ProjectStructure; +import io.spring.initializr.generator.version.Version; import io.spring.initializr.web.project.ProjectRequest; import io.spring.start.site.extension.AbstractExtensionTests; import org.junit.jupiter.api.Test; @@ -51,7 +52,7 @@ void buildWithOnlyTestContainers() { void buildWithSupportedEntries(String springBootDependencyId, String testcontainersArtifactId) { assertThat(generateProject("3.0.0", "testcontainers", springBootDependencyId)).mavenBuild() .hasBom("org.testcontainers", "testcontainers-bom", "${testcontainers.version}") - .hasDependency(getDependency(springBootDependencyId)) + .hasDependency(getDependency(springBootDependencyId).resolve(Version.parse("3.0.0"))) .hasDependency("org.testcontainers", testcontainersArtifactId, null, "test") .hasDependency(getDependency("testcontainers")); }