Restructure Cloud messaging

This commit restructures the cloud messaging group by removing binder
specific checkbox for Spring Cloud Bus and Spring Cloud Stream. A new
"Messaging" group is added with RabbitMQ, Kafka and JMS.

To create a new cloud messaging project, the user should now select the
technology and a binder. To support Spring Cloud Stream with Kafka
streams, a dedicated "Kafka Streams" has been introduced.

Closes gh-557
This commit is contained in:
Stephane Nicoll 2018-02-01 16:00:36 +01:00
parent aad08e0c21
commit e827a99ac7
4 changed files with 327 additions and 83 deletions

View File

@ -0,0 +1,67 @@
/*
* Copyright 2012-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES 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.initializr.service.extension;
import io.spring.initializr.generator.ProjectRequest;
import io.spring.initializr.metadata.Dependency;
import io.spring.initializr.metadata.InitializrMetadata;
import org.springframework.stereotype.Component;
/**
* Determine the appropriate Spring Cloud stream dependency to use based on the
* selected messaging technology.
* <p>
* Does not replace the messaging technology jar by the relevant binder. If more than
* one tech is selected, it is far more easier to remove the unnecessary binder jar than
* to figure out the name of the tech jar to add to keep support for that technology.
*
* @author Stephane Nicoll
*/
@Component
public class SpringCloudMessagingRequestPostProcessor
extends AbstractProjectRequestPostProcessor {
static final Dependency KAFKA_BINDER = Dependency.withId("cloud-stream-binder-kafka",
"org.springframework.cloud", "spring-cloud-stream-binder-kafka");
static final Dependency RABBIT_BINDER = Dependency.withId(
"cloud-stream-binder-rabbit", "org.springframework.cloud",
"spring-cloud-stream-binder-rabbit");
@Override
public void postProcessAfterResolution(ProjectRequest request,
InitializrMetadata metadata) {
boolean hasSpringCloudStream = hasDependency(request, "cloud-stream");
boolean hasReactiveSpringCloudStream = hasDependency(request,
"reactive-cloud-stream");
boolean hasSpringCloudBus = hasDependency(request, "cloud-bus");
boolean hasSpringCloudTurbineStream = hasDependency(request,
"cloud-turbine-stream");
if (hasSpringCloudStream || hasReactiveSpringCloudStream || hasSpringCloudBus
|| hasSpringCloudTurbineStream) {
if (hasDependencies(request, "amqp")) {
request.getResolvedDependencies().add(RABBIT_BINDER);
}
if (hasDependencies(request, "kafka")) {
request.getResolvedDependencies().add(KAFKA_BINDER);
}
}
}
}

View File

@ -722,6 +722,63 @@ initializr:
description: Accessing Data with GemFire
- rel: reference
href: http://docs.spring.io/spring-boot/docs/{bootVersion}/reference/htmlsingle/#boot-features-gemfire
- name: Messaging
content:
- name: RabbitMQ
id: amqp
description: Advanced Message Queuing Protocol via spring-rabbit
weight: 100
keywords:
- messaging
links:
- rel: guide
href: https://spring.io/guides/gs/messaging-rabbitmq/
description: Messaging with RabbitMQ
- rel: reference
href: http://docs.spring.io/spring-boot/docs/{bootVersion}/reference/htmlsingle/#boot-features-amqp
- name: Kafka
id: kafka
weight: 100
description: Kafka messaging support using Spring Kafka
versionRange: 1.5.0.RC1
groupId: org.springframework.kafka
artifactId: spring-kafka
starter: false
keywords:
- messaging
links:
- rel: reference
href: http://docs.spring.io/spring-boot/docs/{bootVersion}/reference/htmlsingle/#boot-features-kafka
- name: JMS (ActiveMQ)
id: activemq
description: Java Message Service API via Apache ActiveMQ
versionRange: 1.4.0.RC1
links:
- rel: guide
href: https://spring.io/guides/gs/messaging-jms/
description: Messaging with JMS
- rel: reference
href: http://docs.spring.io/spring-boot/docs/{bootVersion}/reference/htmlsingle/#boot-features-activemq
- name: JMS (Artemis)
id: artemis
description: Java Message Service API via Apache Artemis
versionRange: 1.3.0.RELEASE
links:
- rel: guide
href: https://spring.io/guides/gs/messaging-jms/
description: Messaging with JMS
- rel: reference
href: http://docs.spring.io/spring-boot/docs/{bootVersion}/reference/htmlsingle/#boot-features-artemis
- name: JMS (HornetQ)
id: hornetq
description: Java Message Service API via HornetQ
versionRange: "[1.1.0.RELEASE,1.4.0.RC1)"
links:
- rel: guide
href: https://spring.io/guides/gs/messaging-jms/
description: Messaging with JMS
- rel: reference
href: http://docs.spring.io/spring-boot/docs/{bootVersion}/reference/htmlsingle/#boot-features-hornetq
- name: Cloud Core
bom: spring-cloud
versionRange: 1.2.3.RELEASE
@ -748,7 +805,7 @@ initializr:
artifactId: spring-cloud-starter-oauth2
- name: Cloud Task
id: cloud-task
description: Task result tracking along with integration with batch and streams
description: Task result tracking and integration with Spring Batch
groupId: org.springframework.cloud
artifactId: spring-cloud-starter-task
versionRange: "1.3.0.RELEASE"
@ -927,7 +984,7 @@ initializr:
- versionRange: "1.5.0.BUILD-SNAPSHOT"
- name: Turbine Stream
id: cloud-turbine-stream
description: Circuit breaker metric aggregation using spring-cloud-netflix with Turbine and Spring Cloud Stream (choose a specific Stream binder implementation to complement this)
description: Circuit breaker metric aggregation using spring-cloud-netflix with Turbine and Spring Cloud Stream (requires a binder, e.g. Kafka or RabbitMQ)
versionRange: 1.3.0.RELEASE
groupId: org.springframework.cloud
artifactId: spring-cloud-starter-netflix-turbine-stream
@ -974,41 +1031,25 @@ initializr:
bom: spring-cloud
versionRange: 1.2.3.RELEASE
content:
- name: Cloud Bus AMQP
id: cloud-bus-amqp
description: A simple control bus with AMQP and spring-cloud-bus-amqp
- name: Cloud Bus
id: cloud-bus
description: A simple control bus using Spring Cloud Stream (requires a binder, e.g. Kafka or RabbitMQ)
groupId: org.springframework.cloud
artifactId: spring-cloud-starter-bus-amqp
- name: Cloud Bus Kafka
id: cloud-bus-kafka
description: A simple control bus with Kafka and spring-cloud-bus
versionRange: "1.3.0.RELEASE"
groupId: org.springframework.cloud
artifactId: spring-cloud-starter-bus-kafka
- name: Stream Binder Rabbit
id: cloud-stream-binder-rabbit
description: Messaging microservices with RabbitMQ
artifactId: spring-cloud-bus
- name: Cloud Stream
id: cloud-stream
description: Messaging microservices with Spring Cloud Stream (requires a binder, e.g. Kafka or RabbitMQ)
versionRange: 1.3.0.RELEASE
weight: 90
groupId: org.springframework.cloud
artifactId: spring-cloud-starter-stream-rabbit
- name: Stream Binder Kafka
id: cloud-stream-binder-kafka
description: Messaging microservices with Kafka
versionRange: 1.3.0.RELEASE
artifactId: spring-cloud-stream
- name: Reactive Cloud Stream
id: reactive-cloud-stream
description: Reactive messaging microservices with Spring Cloud Stream (requires a binder, e.g. Kafka or RabbitMQ)
versionRange: 2.0.0.BUILD-SNAPSHOT
weight: 90
groupId: org.springframework.cloud
artifactId: spring-cloud-stream-binder-kafka
- name: Stream Binder "Kafka Streams"
id: cloud-stream-binder-kafka-streams
description: Stream processing microservices with Kafka Streams API
versionRange: 1.5.7.RELEASE
groupId: org.springframework.cloud
artifactId: spring-cloud-stream-binder-kstream
links:
- rel: guide
href: https://github.com/spring-cloud/spring-cloud-stream-samples/tree/master/kstream
description: Samples for using Kafka Streams with Spring Cloud stream
- rel: reference
href: https://docs.spring.io/spring-cloud-stream/docs/current/reference/htmlsingle/#_kafka_streams_binding_capabilities_of_spring_cloud_stream
artifactId: spring-cloud-stream-reactive
- name: Cloud AWS
bom: spring-cloud
versionRange: 1.2.3.RELEASE
@ -1177,56 +1218,6 @@ initializr:
links:
- rel: reference
href: http://docs.spring.io/spring-boot/docs/{bootVersion}/reference/htmlsingle/#boot-features-email
- name: AMQP
id: amqp
description: Advanced Message Queuing Protocol via spring-rabbit
links:
- rel: guide
href: https://spring.io/guides/gs/messaging-rabbitmq/
description: Messaging with RabbitMQ
- rel: reference
href: http://docs.spring.io/spring-boot/docs/{bootVersion}/reference/htmlsingle/#boot-features-amqp
- name: Kafka
id: kafka
weight: 100
description: Kafka messaging support using Spring Kafka
versionRange: 1.5.0.RC1
groupId: org.springframework.kafka
artifactId: spring-kafka
starter: false
links:
- rel: reference
href: http://docs.spring.io/spring-boot/docs/{bootVersion}/reference/htmlsingle/#boot-features-kafka
- name: JMS (ActiveMQ)
id: activemq
description: Java Message Service API via Apache ActiveMQ
versionRange: 1.4.0.RC1
links:
- rel: guide
href: https://spring.io/guides/gs/messaging-jms/
description: Messaging with JMS
- rel: reference
href: http://docs.spring.io/spring-boot/docs/{bootVersion}/reference/htmlsingle/#boot-features-activemq
- name: JMS (Artemis)
id: artemis
description: Java Message Service API via Apache Artemis
versionRange: 1.3.0.RELEASE
links:
- rel: guide
href: https://spring.io/guides/gs/messaging-jms/
description: Messaging with JMS
- rel: reference
href: http://docs.spring.io/spring-boot/docs/{bootVersion}/reference/htmlsingle/#boot-features-artemis
- name: JMS (HornetQ)
id: hornetq
description: Java Message Service API via HornetQ
versionRange: "[1.1.0.RELEASE,1.4.0.RC1)"
links:
- rel: guide
href: https://spring.io/guides/gs/messaging-jms/
description: Messaging with JMS
- rel: reference
href: http://docs.spring.io/spring-boot/docs/{bootVersion}/reference/htmlsingle/#boot-features-hornetq
- name: Apache Camel
id: camel
versionRange: "[1.4.0.RELEASE,2.0.0.M1)"

View File

@ -21,6 +21,7 @@ import java.util.Arrays;
import io.spring.initializr.generator.ProjectGenerator;
import io.spring.initializr.generator.ProjectRequest;
import io.spring.initializr.generator.ProjectRequestPostProcessor;
import io.spring.initializr.metadata.Dependency;
import io.spring.initializr.metadata.InitializrMetadataProvider;
import io.spring.initializr.test.generator.GradleBuildAssert;
import io.spring.initializr.test.generator.PomAssert;
@ -45,6 +46,10 @@ public abstract class AbstractRequestPostProcessorTests {
@Autowired
private InitializrMetadataProvider metadataProvider;
protected Dependency getDependency(String id) {
return this.metadataProvider.get().getDependencies().get(id);
}
protected PomAssert generateMavenPom(ProjectRequest request) {
request.setType("maven-build");
String content = new String(projectGenerator.generateMavenPom(request));

View File

@ -0,0 +1,181 @@
/*
* Copyright 2012-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES 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.initializr.service.extension;
import io.spring.initializr.generator.ProjectRequest;
import org.junit.Test;
import static io.spring.initializr.service.extension.SpringCloudMessagingRequestPostProcessor.KAFKA_BINDER;
import static io.spring.initializr.service.extension.SpringCloudMessagingRequestPostProcessor.RABBIT_BINDER;
/**
* Tests for {@link SpringCloudMessagingRequestPostProcessor}.
*
* @author Stephane Nicoll
*/
public class SpringCloudMessagingRequestPostProcessorTests
extends AbstractRequestPostProcessorTests {
@Test
public void springCloudStreamWithRabbit() {
ProjectRequest request = createProjectRequest("cloud-stream", "amqp");
generateMavenPom(request)
.hasDependency(getDependency("cloud-stream"))
.hasDependency(getDependency("amqp"))
.hasDependency(RABBIT_BINDER)
.hasSpringBootStarterTest()
.hasDependenciesCount(4);
}
@Test
public void springCloudStreamWithKafka() {
ProjectRequest request = createProjectRequest("cloud-stream", "kafka");
generateMavenPom(request)
.hasDependency(getDependency("cloud-stream"))
.hasDependency(getDependency("kafka"))
.hasDependency(KAFKA_BINDER)
.hasSpringBootStarterTest()
.hasDependenciesCount(4);
}
@Test
public void springCloudStreamWithAllBinders() {
ProjectRequest request = createProjectRequest("cloud-stream", "amqp", "kafka");
generateMavenPom(request)
.hasDependency(getDependency("cloud-stream"))
.hasDependency(getDependency("amqp"))
.hasDependency(getDependency("kafka"))
.hasDependency(RABBIT_BINDER)
.hasDependency(KAFKA_BINDER)
.hasSpringBootStarterTest()
.hasDependenciesCount(6);
}
@Test
public void reactiveSpringCloudStreamWithRabbit() {
ProjectRequest request = createProjectRequest("reactive-cloud-stream", "amqp");
request.setBootVersion("2.0.0.BUILD-SNAPSHOT");
generateMavenPom(request)
.hasDependency(getDependency("reactive-cloud-stream"))
.hasDependency(getDependency("amqp"))
.hasDependency(RABBIT_BINDER)
.hasSpringBootStarterTest()
.hasDependenciesCount(4);
}
@Test
public void reactiveSpringCloudStreamWithKafka() {
ProjectRequest request = createProjectRequest("reactive-cloud-stream", "kafka");
request.setBootVersion("2.0.0.BUILD-SNAPSHOT");
generateMavenPom(request)
.hasDependency(getDependency("reactive-cloud-stream"))
.hasDependency(getDependency("kafka"))
.hasDependency(KAFKA_BINDER)
.hasSpringBootStarterTest()
.hasDependenciesCount(4);
}
@Test
public void reactiveSpringCloudStreamWithAllBinders() {
ProjectRequest request = createProjectRequest("reactive-cloud-stream", "amqp",
"kafka");
request.setBootVersion("2.0.0.BUILD-SNAPSHOT");
generateMavenPom(request)
.hasDependency(getDependency("reactive-cloud-stream"))
.hasDependency(getDependency("amqp"))
.hasDependency(getDependency("kafka"))
.hasDependency(RABBIT_BINDER)
.hasDependency(KAFKA_BINDER)
.hasSpringBootStarterTest()
.hasDependenciesCount(6);
}
@Test
public void springCloudBusWithRabbit() {
ProjectRequest request = createProjectRequest("cloud-bus", "amqp");
generateMavenPom(request)
.hasDependency(getDependency("cloud-bus"))
.hasDependency(getDependency("amqp"))
.hasDependency(RABBIT_BINDER)
.hasSpringBootStarterTest()
.hasDependenciesCount(4);
}
@Test
public void springCloudBusWithKafka() {
ProjectRequest request = createProjectRequest("cloud-bus", "amqp");
generateMavenPom(request)
.hasDependency(getDependency("cloud-bus"))
.hasDependency(getDependency("amqp"))
.hasDependency(RABBIT_BINDER)
.hasSpringBootStarterTest()
.hasDependenciesCount(4);
}
@Test
public void springCloudBusWithAllBinders() {
ProjectRequest request = createProjectRequest("cloud-bus", "amqp", "kafka");
generateMavenPom(request)
.hasDependency(getDependency("cloud-bus"))
.hasDependency(getDependency("amqp"))
.hasDependency(getDependency("kafka"))
.hasDependency(RABBIT_BINDER)
.hasDependency(KAFKA_BINDER)
.hasSpringBootStarterTest()
.hasDependenciesCount(6);
}
@Test
public void springCloudTurbineStreamWithRabbit() {
ProjectRequest request = createProjectRequest("cloud-turbine-stream", "amqp");
request.setBootVersion("2.0.0.BUILD-SNAPSHOT");
generateMavenPom(request)
.hasDependency(getDependency("cloud-turbine-stream"))
.hasDependency(getDependency("amqp"))
.hasDependency(RABBIT_BINDER)
.hasSpringBootStarterTest()
.hasDependenciesCount(4);
}
@Test
public void springCloudTurbineStreamWithKafka() {
ProjectRequest request = createProjectRequest("cloud-turbine-stream", "kafka");
request.setBootVersion("2.0.0.BUILD-SNAPSHOT");
generateMavenPom(request)
.hasDependency(getDependency("cloud-turbine-stream"))
.hasDependency(getDependency("kafka"))
.hasDependency(KAFKA_BINDER)
.hasSpringBootStarterTest()
.hasDependenciesCount(4);
}
@Test
public void springCloudTurbineStreamWithAllBinders() {
ProjectRequest request = createProjectRequest("cloud-turbine-stream", "amqp",
"kafka");
request.setBootVersion("2.0.0.BUILD-SNAPSHOT");
generateMavenPom(request)
.hasDependency(getDependency("cloud-turbine-stream"))
.hasDependency(getDependency("amqp"))
.hasDependency(getDependency("kafka"))
.hasDependency(RABBIT_BINDER)
.hasDependency(KAFKA_BINDER)
.hasSpringBootStarterTest()
.hasDependenciesCount(6);
}
}