A publish/subscribe demo using Solace PubSub+ and Spring Cloud Stream. A REST API publishes news events to topic ps/news/{type}/{country}/{city}, with consumer instances filtering by news type, country or city to showcase topic-based routing.
On ivangfr.github.io, I have compiled my Proof-of-Concepts (PoCs) and articles. You can easily search for the technology you are interested in by using the filter. Who knows, perhaps I have already implemented a PoC or written an article about what you are looking for.
- [Medium] Solace PubSub+ vs Kafka: Different Approaches to Topic Routing
- [Medium] Solace PubSub+ and Spring Boot: Implementing News Producer and Consumer Apps
- [Medium] Solace PubSub+ and Spring Boot: Implementing Unit Tests for News Producer and Consumer Apps
- [Medium] Solace PubSub+ and Spring Boot: Implementing End-to-End Tests for News Producer and Consumer Apps
- [Medium] Solace PubSub+ and Spring Boot: Running News Producer and Consumer Apps in Minikube (Kubernetes)
flowchart TB
subgraph users ["Users"]
HTTP["REST Clients"]
Browser["Browser"]
end
subgraph producer-service ["producer-service:9080 (Spring Boot)"]
RestCtrl["NewsController /api/news"]
NewsProducer["NewsEventProducer (StreamBridge)"]
end
subgraph solace ["Solace PubSub+"]
Broker["Message Broker ps/news/*/*/*"]
Manager["PubSub+ Manager http://localhost:8080"]
end
subgraph consumer-service ["consumer-service:9081 (Spring Boot)"]
direction TB
Consumer1["NewsEventConsumer instance-1\n(BR subscription)\nps/news/*/BR/>"]
Consumer2["NewsEventConsumer instance-2\n(HEALTH subscription)\nps/news/HEALTH/>"]
end
HTTP -->|"POST /api/news"| RestCtrl
HTTP -->|"POST /api/news/random"| RestCtrl
Browser -->|"accesses"| Manager
RestCtrl -->|"delegates"| NewsProducer
NewsProducer -->|"publishes news events"| Broker
Broker -->|"delivers to matching topics"| Consumer1
Broker -->|"delivers to matching topics"| Consumer2
-
Spring Bootapplication that exposes a REST API to submitnewsevents. It publishes news to the following destination with the format:ps/news/{type}/{country}/{city}Endpoints
POST /api/news {"type": [SPORT|ECONOMY|HEALTH], "country": "...", "city": "...", "title": "..."} POST /api/news/random {"number": ..., "delay": ...} -
Spring Bootapplication that consumes thenewsevents published byproducer-service.
Open a terminal and inside the spring-cloud-stream-solace-pubsub root folder run:
docker compose up -d-
producer-service
- In a terminal, make sure you are in the
spring-cloud-stream-solace-pubsubroot folder. - Run the commands below:
./mvnw clean spring-boot:run --projects producer-service
- In a terminal, make sure you are in the
-
consumer-service-1
- It subscribes to all news from
Brazil. - Open a new terminal and navigate to the
spring-cloud-stream-solace-pubsubroot folder. - Run the commands below:
export NEWS_SUBSCRIPTION="ps/news/*/BR/>" ./mvnw clean spring-boot:run --projects consumer-service
- It subscribes to all news from
-
consumer-service-2
- It subscribes to all news related to
HEALTH. - Open a new terminal and navigate to the
spring-cloud-stream-solace-pubsubroot folder. - Run the commands below:
export SERVER_PORT=9082 export NEWS_SUBSCRIPTION="ps/news/HEALTH/>" ./mvnw spring-boot:run --projects consumer-service
- It subscribes to all news related to
-
- In a terminal, make sure you are inside the
spring-cloud-stream-solace-pubsubroot folder. - Run the following script to build the Docker images:
./build-docker-images.sh
- In a terminal, make sure you are inside the
-
-
producer-service
Environment Variable Description SOLACE_HOSTSpecify host of the Solace PubSub+message broker to use (defaultlocalhost)SOLACE_PORTSpecify port of the Solace PubSub+message broker to use (default55556) -
consumer-service
Environment Variable Description SOLACE_HOSTSpecify host of the Solace PubSub+message broker to use (defaultlocalhost)SOLACE_PORTSpecify port of the Solace PubSub+message broker to use (default55556)
-
-
-
producer-service
Run the following command in a terminal:
docker run --rm --name producer-service \ -p 9080:9080 \ -e SOLACE_HOST=solace -e SOLACE_PORT=55555 \ --network=spring-cloud-stream-solace-pubsub_default \ ivanfranchin/producer-service:1.0.0
-
consumer-service-1
- It subscribes to all news from
Brazil. - Open a new terminal and run the following command:
docker run --rm --name consumer-service-1 \ -p 9081:9081 \ -e SOLACE_HOST=solace -e SOLACE_PORT=55555 \ -e NEWS_SUBSCRIPTION="ps/news/*/BR/>" \ --network=spring-cloud-stream-solace-pubsub_default \ ivanfranchin/consumer-service:1.0.0
- It subscribes to all news from
-
consumer-service-2
- It subscribes to all news related to
HEALTH. - Open a new terminal and run the following command:
docker run --rm --name consumer-service-2 \ -p 9082:9081 \ -e SOLACE_HOST=solace -e SOLACE_PORT=55555 \ -e NEWS_SUBSCRIPTION="ps/news/HEALTH/>" \ --network=spring-cloud-stream-solace-pubsub_default \ ivanfranchin/consumer-service:1.0.0
- It subscribes to all news related to
-
In a terminal, submit the following POST requests to producer-service and check its logs and consumer-service logs.
Note: HTTPie is being used in the calls below
-
Sending
newsone by one-
Just
consumer-service-1should consume:http :9080/api/news type="SPORT" country="BR" city="SaoPaulo" title="..." -
Just
consumer-service-2should consume:http :9080/api/news type="HEALTH" country="PT" city="Porto" title="..." -
Neither
consumer-service-1norconsumer-service-2should consume:http :9080/api/news type="ECONOMY" country="DE" city="Berlin" title="..." -
Both
consumer-service-1andconsumer-service-2should consume:http :9080/api/news type="HEALTH" country="BR" city="Brasilia" title="..."
-
-
Sending a number of
newsrandomly with a specified delay in milliseconds:http :9080/api/news/random number=10 delayInMillis=1000 --stream
-
Solace
Solacecan be accessed at http://localhost:8080. Enteradminfor both the username and password.
- To stop applications, go to the terminals where they are running and press
Ctrl+C. - To stop and remove docker compose containers, network and volumes, go to a terminal and, inside the
spring-cloud-stream-solace-pubsubroot folder, run the following command:docker compose down -v
In a terminal, make sure you are inside the spring-cloud-stream-solace-pubsub root folder:
-
producer-service
./mvnw clean test --projects producer-service -
consumer-service
./mvnw clean test --projects consumer-service
To remove the Docker images created by this project, go to a terminal and, inside the spring-cloud-stream-solace-pubsub root folder, run the following script:
./remove-docker-images.sh
This project enforces consistent Java formatting using the Spotless Maven plugin with google-java-format (GOOGLE style).
-
Check formatting:
./mvnw spotless:check
-
Auto-fix formatting:
./mvnw spotless:apply
Formatting is enforced automatically during ./mvnw test.
The default Solace SMF port 55555 is not working, at least on my Mac machine. The problem is explained in this issue. For now, I've changed the mapping port from 55555 to 55556.
If you find this useful, consider buying me a coffee:
This project is licensed under the MIT License.
