├── LICENSE
├── README.md
├── amqp-to-webflux
├── .gitignore
├── .mvn
│ └── wrapper
│ │ ├── maven-wrapper.jar
│ │ └── maven-wrapper.properties
├── README.adoc
├── mvnw
├── mvnw.cmd
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── org
│ │ │ └── springframework
│ │ │ └── amqp
│ │ │ └── webflux
│ │ │ └── so49662157
│ │ │ └── AmqpToWebFluxApplication.java
│ └── resources
│ │ └── application.properties
│ └── test
│ └── java
│ └── org
│ └── springframework
│ └── amqp
│ └── webflux
│ └── so49662157
│ └── AmqpToWebfluxApplicationTests.java
├── cloud-stream-kinesis-to-webflux
├── .gitignore
├── .mvn
│ └── wrapper
│ │ ├── maven-wrapper.jar
│ │ └── maven-wrapper.properties
├── README.adoc
├── mvnw
├── mvnw.cmd
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── org
│ │ │ └── springframework
│ │ │ └── cloud
│ │ │ └── stream
│ │ │ └── kinesis
│ │ │ └── webflux
│ │ │ └── so51669324
│ │ │ └── CloudStreamKinesisToWebfluxApplication.java
│ └── resources
│ │ └── application.yml
│ └── test
│ └── java
│ └── org
│ └── springframework
│ └── cloud
│ └── stream
│ └── kinesis
│ └── webflux
│ └── so51669324
│ └── CloudStreamKinesisToWebfluxApplicationTests.java
├── graph-sample-all-components
├── .gitignore
├── .mvn
│ └── wrapper
│ │ ├── MavenWrapperDownloader.java
│ │ ├── maven-wrapper.jar
│ │ └── maven-wrapper.properties
├── mvnw
├── mvnw.cmd
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── org
│ │ │ └── springframework
│ │ │ └── integration
│ │ │ └── graphsample
│ │ │ └── GraphSampleAllComponentsApplication.java
│ └── resources
│ │ └── application.properties
│ └── test
│ └── java
│ └── org
│ └── springframework
│ └── integration
│ └── graphsample
│ └── GraphSampleAllComponentsApplicationTests.java
├── http-reply-and-process
├── .gitignore
├── .mvn
│ └── wrapper
│ │ ├── MavenWrapperDownloader.java
│ │ ├── maven-wrapper.jar
│ │ └── maven-wrapper.properties
├── mvnw
├── mvnw.cmd
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── org
│ │ │ └── springframework
│ │ │ └── integration
│ │ │ └── stackoverflow
│ │ │ └── httpreplyandprocess
│ │ │ └── HttpReplyAndProcessApplication.java
│ └── resources
│ │ └── application.properties
│ └── test
│ └── java
│ └── org
│ └── springframework
│ └── integration
│ └── stackoverflow
│ └── httpreplyandprocess
│ └── HttpReplyAndProcessApplicationTests.java
├── images
└── IntegrationGraph.png
├── kinesis-binder-observation-demo
├── .gitignore
├── .mvn
│ └── wrapper
│ │ ├── maven-wrapper.jar
│ │ └── maven-wrapper.properties
├── README.adoc
├── mvnw
├── mvnw.cmd
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── com
│ │ │ └── example
│ │ │ └── kinesisbinderobservationdemo
│ │ │ └── KinesisBinderObservationDemoApplication.java
│ └── resources
│ │ └── application.properties
│ └── test
│ └── java
│ └── com
│ └── example
│ └── kinesisbinderobservationdemo
│ ├── KinesisBinderObservationDemoApplicationTests.java
│ └── LocalstackContainerTest.java
├── leader-election
├── .gitignore
├── .mvn
│ └── wrapper
│ │ ├── maven-wrapper.jar
│ │ └── maven-wrapper.properties
├── README.adoc
├── mvnw
├── mvnw.cmd
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── org
│ │ │ └── springframework
│ │ │ └── integration
│ │ │ └── leaderelection
│ │ │ └── LeaderElectionApplication.java
│ └── resources
│ │ └── application.properties
│ └── test
│ └── java
│ └── org
│ └── springframework
│ └── integration
│ └── leaderelection
│ └── LeaderElectionApplicationTests.java
├── lock-on-oracle
├── .gitignore
├── .mvn
│ └── wrapper
│ │ ├── MavenWrapperDownloader.java
│ │ ├── maven-wrapper.jar
│ │ └── maven-wrapper.properties
├── mvnw
├── mvnw.cmd
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── org
│ │ │ └── springframework
│ │ │ └── integration
│ │ │ └── jdbc
│ │ │ └── lock
│ │ │ └── oracle
│ │ │ └── LockOnOracleApplication.java
│ └── resources
│ │ └── application.properties
│ └── test
│ ├── java
│ └── org
│ │ └── springframework
│ │ └── integration
│ │ └── jdbc
│ │ └── lock
│ │ └── oracle
│ │ └── LockOnOracleApplicationTests.java
│ └── resources
│ └── schema.sql
├── null-away-issue
├── .gitattributes
├── .gitignore
├── README.md
├── build.gradle
├── gradle
│ └── wrapper
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── settings.gradle
└── src
│ └── main
│ └── java
│ └── org
│ └── springframework
│ └── example
│ └── nullawayissue
│ ├── NullAwayIssueApplication.java
│ └── package-info.java
├── observation-over-stream-rabbit-binder
├── .gitignore
├── .mvn
│ └── wrapper
│ │ ├── maven-wrapper.jar
│ │ └── maven-wrapper.properties
├── mvnw
├── mvnw.cmd
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── com
│ │ │ └── example
│ │ │ └── stream
│ │ │ └── rabbit
│ │ │ └── binder
│ │ │ └── observation
│ │ │ └── ObservationOverStreamRabbitBinderApplication.java
│ └── resources
│ │ └── application.properties
│ └── test
│ └── java
│ └── com
│ └── example
│ └── stream
│ └── rabbit
│ └── binder
│ └── observation
│ └── ObservationOverStreamRabbitBinderApplicationTests.java
├── postgres-channel-observation
├── .gitignore
├── README.adoc
├── build.gradle
├── gradle
│ └── wrapper
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── settings.gradle
└── src
│ ├── main
│ ├── java
│ │ └── org
│ │ │ └── springframework
│ │ │ └── integration
│ │ │ └── postgreschannelobservation
│ │ │ └── PostgresChannelObservationApplication.java
│ └── resources
│ │ ├── application.properties
│ │ └── schema.sql
│ └── test
│ └── java
│ └── org
│ └── springframework
│ └── integration
│ └── postgreschannelobservation
│ └── PostgresChannelObservationApplicationTests.java
├── so-65667450
├── .gitignore
├── .mvn
│ └── wrapper
│ │ ├── MavenWrapperDownloader.java
│ │ ├── maven-wrapper.jar
│ │ └── maven-wrapper.properties
├── README.md
├── mvnw
├── mvnw.cmd
├── pom.xml
└── src
│ ├── main
│ ├── kotlin
│ │ └── stackoverflow
│ │ │ └── so65667450
│ │ │ └── So65667450Application.kt
│ └── resources
│ │ └── application.properties
│ └── test
│ └── kotlin
│ └── stackoverflow
│ └── so65667450
│ └── So65667450ApplicationTests.kt
├── so-79334692
├── .gitattributes
├── .gitignore
├── README.md
├── build.gradle
├── gradle
│ └── wrapper
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── settings.gradle
└── src
│ ├── main
│ ├── java
│ │ └── org
│ │ │ └── springframework
│ │ │ └── integration
│ │ │ └── example
│ │ │ └── so79334692
│ │ │ └── So79334692Application.java
│ └── resources
│ │ └── application.properties
│ └── test
│ └── java
│ └── org
│ └── springframework
│ └── integration
│ └── example
│ └── so79334692
│ └── So79334692ApplicationTests.java
├── so-79382434
├── .gitattributes
├── .gitignore
├── build.gradle
├── gradle
│ └── wrapper
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── settings.gradle
└── src
│ ├── main
│ ├── java
│ │ └── org
│ │ │ └── springframework
│ │ │ └── cloud
│ │ │ └── stream
│ │ │ └── example
│ │ │ └── so79382434
│ │ │ └── So79382434Application.java
│ └── resources
│ │ └── application.yml
│ └── test
│ └── java
│ └── org
│ └── springframework
│ └── cloud
│ └── stream
│ └── example
│ └── so79382434
│ └── So79382434ApplicationTests.java
├── so57889424
├── .gitignore
├── .mvn
│ └── wrapper
│ │ ├── MavenWrapperDownloader.java
│ │ ├── maven-wrapper.jar
│ │ └── maven-wrapper.properties
├── mvnw
├── mvnw.cmd
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── org
│ │ │ └── springframework
│ │ │ └── kafka
│ │ │ └── so57889424
│ │ │ └── So57889424Application.java
│ └── resources
│ │ └── application.properties
│ └── test
│ └── java
│ └── org
│ └── springframework
│ └── kafka
│ └── so57889424
│ └── So57889424ApplicationTests.java
├── spring-amqp-observation
├── .gitignore
├── build.gradle
├── gradle
│ └── wrapper
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── settings.gradle
└── src
│ ├── main
│ ├── java
│ │ └── org
│ │ │ └── springframework
│ │ │ └── amqp
│ │ │ └── sample
│ │ │ └── tracing
│ │ │ └── SpringAmqpObservationApplication.java
│ └── resources
│ │ └── application.properties
│ └── test
│ └── java
│ └── org
│ └── springframework
│ └── amqp
│ └── sample
│ └── tracing
│ └── SpringAmqpObservationApplicationTests.java
├── spring-boot-reactor-kafka-tracing
├── .gitignore
├── .mvn
│ └── wrapper
│ │ ├── maven-wrapper.jar
│ │ └── maven-wrapper.properties
├── mvnw
├── mvnw.cmd
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── com
│ │ │ └── example
│ │ │ └── springbootreactorkafkatracing
│ │ │ └── SpringBootReactorKafkaTracingApplication.java
│ └── resources
│ │ └── application.properties
│ └── test
│ └── java
│ └── com
│ └── example
│ └── springbootreactorkafkatracing
│ └── SpringBootReactorKafkaTracingApplicationTests.java
├── spring-cloud-stream-rabbit-dlq
├── .gitignore
├── build.gradle
├── gradle
│ └── wrapper
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── settings.gradle
└── src
│ └── test
│ ├── java
│ └── org
│ │ └── springframework
│ │ └── cloud
│ │ └── stream
│ │ └── rabbitdlq
│ │ └── SpringCloudStreamRabbitDlqApplicationTests.java
│ └── resources
│ └── application.properties
├── spring-integration-enricher
├── .gitignore
├── .mvn
│ └── wrapper
│ │ ├── MavenWrapperDownloader.java
│ │ ├── maven-wrapper.jar
│ │ └── maven-wrapper.properties
├── mvnw
├── mvnw.cmd
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── org
│ │ │ └── springframework
│ │ │ └── integration
│ │ │ └── stackoverflow
│ │ │ └── enricher
│ │ │ └── SpringIntegrationEnricherApplication.java
│ └── resources
│ │ └── application.properties
│ └── test
│ └── java
│ └── org
│ └── springframework
│ └── integration
│ └── stackoverflow
│ └── enricher
│ └── SpringIntegrationEnricherApplicationTests.java
├── spring-integration-mqtt-share-demo
├── .gitignore
├── README.adoc
├── build.gradle
├── gradle
│ └── wrapper
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── settings.gradle
└── src
│ ├── main
│ ├── java
│ │ └── org
│ │ │ └── springframework
│ │ │ └── cloud
│ │ │ └── stream
│ │ │ └── springintegrationmqttsharedemo
│ │ │ └── SpringIntegrationMqttShareDemoApplication.java
│ └── resources
│ │ └── application.properties
│ └── test
│ └── java
│ └── org
│ └── springframework
│ └── cloud
│ └── stream
│ └── springintegrationmqttsharedemo
│ └── SpringIntegrationMqttShareDemoApplicationTests.java
├── spring-integration-performance
├── .gitignore
├── .mvn
│ └── wrapper
│ │ ├── MavenWrapperDownloader.java
│ │ ├── maven-wrapper.jar
│ │ └── maven-wrapper.properties
├── README.md
├── mvnw
├── mvnw.cmd
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── org
│ │ │ └── springframework
│ │ │ └── integration
│ │ │ └── performance
│ │ │ └── SpringIntegrationPerformanceApplication.java
│ └── resources
│ │ └── application.properties
│ └── test
│ └── java
│ └── org
│ └── springframework
│ └── integration
│ └── performance
│ └── SpringIntegrationPerformanceApplicationTests.java
├── spring-integration-reactor-kafka
├── .gitignore
├── .mvn
│ └── wrapper
│ │ ├── MavenWrapperDownloader.java
│ │ ├── maven-wrapper.jar
│ │ └── maven-wrapper.properties
├── mvnw
├── mvnw.cmd
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── com
│ │ │ └── example
│ │ │ └── spring
│ │ │ └── integration
│ │ │ └── reactor
│ │ │ └── kafka
│ │ │ └── SpringIntegrationReactorKafkaApplication.java
│ └── resources
│ │ └── application.properties
│ └── test
│ └── java
│ └── com
│ └── example
│ └── spring
│ └── integration
│ └── reactor
│ └── kafka
│ └── SpringIntegrationReactorKafkaApplicationTests.java
├── spring-integration-security-context-propagation
├── .gitignore
├── HELP.md
├── build.gradle
├── gradle
│ └── wrapper
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── settings.gradle
└── src
│ ├── main
│ ├── java
│ │ └── org
│ │ │ └── springframework
│ │ │ └── integration
│ │ │ └── security
│ │ │ └── sample
│ │ │ └── springintegrationsecuritycontextpropagation
│ │ │ └── SpringIntegrationSecurityContextPropagationApplication.java
│ └── resources
│ │ └── application.properties
│ └── test
│ └── java
│ └── org
│ └── springframework
│ └── integration
│ └── security
│ └── sample
│ └── springintegrationsecuritycontextpropagation
│ └── SpringIntegrationSecurityContextPropagationApplicationTests.java
├── spring-integration-websocket-reactive
├── .gitignore
├── .mvn
│ └── wrapper
│ │ ├── maven-wrapper.jar
│ │ └── maven-wrapper.properties
├── README.adoc
├── mvnw
├── mvnw.cmd
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── org
│ │ │ └── springframework
│ │ │ └── integration
│ │ │ └── socket
│ │ │ └── stackoverflow
│ │ │ └── springintegrationwebsocketreactive
│ │ │ └── SpringIntegrationWebsocketReactiveApplication.java
│ └── resources
│ │ └── application.properties
│ └── test
│ └── java
│ └── org
│ └── springframework
│ └── integration
│ └── socket
│ └── stackoverflow
│ └── springintegrationwebsocketreactive
│ └── SpringIntegrationWebsocketReactiveApplicationTests.java
├── spring-integration-with-hystrix
├── .gitignore
├── .mvn
│ └── wrapper
│ │ ├── maven-wrapper.jar
│ │ └── maven-wrapper.properties
├── README.adoc
├── mvnw
├── mvnw.cmd
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── org
│ │ │ └── springframework
│ │ │ └── integration
│ │ │ └── hystrix
│ │ │ └── SpringIntegrationWithHystrixApplication.java
│ └── resources
│ │ └── application.properties
│ └── test
│ └── java
│ └── org
│ └── springframework
│ └── integration
│ └── hystrix
│ └── SpringIntegrationWithHystrixApplicationTests.java
├── spring-kafka-retry-demo
├── .gitattributes
├── .gitignore
├── build.gradle
├── gradle
│ └── wrapper
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── settings.gradle
└── src
│ ├── main
│ ├── java
│ │ └── org
│ │ │ └── springframework
│ │ │ └── kafka
│ │ │ └── example
│ │ │ └── retry
│ │ │ └── SpringKafkaRetryDemoApplication.java
│ └── resources
│ │ └── application.properties
│ └── test
│ └── java
│ └── org
│ └── springframework
│ └── kafka
│ └── example
│ └── retry
│ └── SpringKafkaRetryDemoApplicationTests.java
└── websocket-over-webflux
├── .gitignore
├── .mvn
└── wrapper
│ ├── maven-wrapper.jar
│ └── maven-wrapper.properties
├── README.md
├── mvnw
├── mvnw.cmd
├── pom.xml
└── src
├── main
├── java
│ └── org
│ │ └── springframework
│ │ └── webflux
│ │ └── websocket
│ │ └── webfluxwebsocketdemo
│ │ └── WebFluxWebSocketDemoApplication.java
└── resources
│ └── application.properties
└── test
└── java
└── org
└── springframework
└── webflux
└── websocket
└── webfluxwebsocketdemo
└── WebFluxWebSocketDemoApplicationTests.java
/README.md:
--------------------------------------------------------------------------------
1 | # Artem Bilan's Sendbox
2 |
3 | In this repository you can find various small projects for some Proof of Concepts, as Samples for mixed concerns or answers to StackOverflow questions.
4 |
5 | Mostly they are about:
6 |
7 | * [Spring Integration](https://projects.spring.io/spring-integration/)
8 | * [Spring AMQP](https://projects.spring.io/spring-amqp/)
9 | * [Spring Kafka](https://projects.spring.io/spring-kafka/)
10 | * [Project Reactor](https://projectreactor.io/)
11 | * [Spring Cloud](https://projects.spring.io/spring-cloud/)
12 | * [Spring Boot](https://projects.spring.io/spring-boot/)
13 |
--------------------------------------------------------------------------------
/amqp-to-webflux/.gitignore:
--------------------------------------------------------------------------------
1 | target/
2 | !.mvn/wrapper/maven-wrapper.jar
3 |
4 | ### STS ###
5 | .apt_generated
6 | .classpath
7 | .factorypath
8 | .project
9 | .settings
10 | .springBeans
11 | .sts4-cache
12 |
13 | ### IntelliJ IDEA ###
14 | .idea
15 | *.iws
16 | *.iml
17 | *.ipr
18 |
19 | ### NetBeans ###
20 | nbproject/private/
21 | build/
22 | nbbuild/
23 | dist/
24 | nbdist/
25 | .nb-gradle/
--------------------------------------------------------------------------------
/amqp-to-webflux/.mvn/wrapper/maven-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/artembilan/sandbox/df95ea33d5189ac11b6d7f6149df9f803eff514b/amqp-to-webflux/.mvn/wrapper/maven-wrapper.jar
--------------------------------------------------------------------------------
/amqp-to-webflux/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.3/apache-maven-3.5.3-bin.zip
2 |
--------------------------------------------------------------------------------
/amqp-to-webflux/README.adoc:
--------------------------------------------------------------------------------
1 | == RabbitMQ Listener to SSE via WebFlux
2 |
3 | This sample demonstrate a simple bridging of message from the RabbitMQ queue to the Server Side Events subscribers via Project Reactor `UnicastProcessor` with `share` mode.
4 |
5 |
--------------------------------------------------------------------------------
/amqp-to-webflux/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | org.springframework.amqp.webflux.so49662157
7 | amqp-to-webflux
8 | 0.0.1-SNAPSHOT
9 | jar
10 |
11 | amqp-to-webflux
12 | Demo project for Spring Boot
13 |
14 |
15 | org.springframework.boot
16 | spring-boot-starter-parent
17 | 2.0.0.RELEASE
18 |
19 |
20 |
21 |
22 | UTF-8
23 | UTF-8
24 | 1.8
25 |
26 |
27 |
28 |
29 | org.springframework.boot
30 | spring-boot-starter-amqp
31 |
32 |
33 | org.springframework.boot
34 | spring-boot-starter-webflux
35 |
36 |
37 |
38 | org.springframework.boot
39 | spring-boot-starter-test
40 | test
41 |
42 |
43 | io.projectreactor
44 | reactor-test
45 | test
46 |
47 |
48 |
49 |
50 |
51 |
52 | org.springframework.boot
53 | spring-boot-maven-plugin
54 |
55 |
56 |
57 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/amqp-to-webflux/src/main/java/org/springframework/amqp/webflux/so49662157/AmqpToWebFluxApplication.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.amqp.webflux.so49662157;
18 |
19 | import org.springframework.amqp.core.Queue;
20 | import org.springframework.amqp.rabbit.annotation.RabbitListener;
21 | import org.springframework.boot.SpringApplication;
22 | import org.springframework.boot.autoconfigure.SpringBootApplication;
23 | import org.springframework.context.annotation.Bean;
24 | import org.springframework.http.MediaType;
25 | import org.springframework.web.bind.annotation.GetMapping;
26 | import org.springframework.web.bind.annotation.RestController;
27 |
28 | import reactor.core.publisher.Flux;
29 | import reactor.core.publisher.UnicastProcessor;
30 |
31 | /**
32 | * @author Artem Bilan
33 | */
34 | @SpringBootApplication
35 | @RestController
36 | public class AmqpToWebFluxApplication {
37 |
38 | private final UnicastProcessor sseFluxProcessor = UnicastProcessor.create();
39 |
40 | private final Flux sseFlux = this.sseFluxProcessor.share();
41 |
42 | @GetMapping(value = "/sseFromAmqp", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
43 | public Flux getSeeFromAmqp() {
44 | return this.sseFlux;
45 | }
46 |
47 | @Bean
48 | public Queue queueForSee() {
49 | return new Queue("queueForSee");
50 | }
51 |
52 | @RabbitListener(queues = "queueForSee")
53 | public void handleAmqpMessages(String message) {
54 | this.sseFluxProcessor.onNext(message);
55 | }
56 |
57 | public static void main(String[] args) {
58 | SpringApplication.run(AmqpToWebFluxApplication.class, args);
59 | }
60 |
61 | }
62 |
--------------------------------------------------------------------------------
/amqp-to-webflux/src/main/resources/application.properties:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/artembilan/sandbox/df95ea33d5189ac11b6d7f6149df9f803eff514b/amqp-to-webflux/src/main/resources/application.properties
--------------------------------------------------------------------------------
/amqp-to-webflux/src/test/java/org/springframework/amqp/webflux/so49662157/AmqpToWebfluxApplicationTests.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.amqp.webflux.so49662157;
18 |
19 | import org.junit.Test;
20 | import org.junit.runner.RunWith;
21 |
22 | import org.springframework.amqp.core.Queue;
23 | import org.springframework.amqp.rabbit.core.RabbitTemplate;
24 | import org.springframework.beans.factory.annotation.Autowired;
25 | import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
26 | import org.springframework.boot.test.context.SpringBootTest;
27 | import org.springframework.test.context.junit4.SpringRunner;
28 | import org.springframework.test.web.reactive.server.WebTestClient;
29 |
30 | import reactor.core.publisher.Flux;
31 | import reactor.test.StepVerifier;
32 |
33 | @RunWith(SpringRunner.class)
34 | @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
35 | @AutoConfigureWebTestClient
36 | public class AmqpToWebfluxApplicationTests {
37 |
38 | @Autowired
39 | private WebTestClient webTestClient;
40 |
41 | @Autowired
42 | private RabbitTemplate rabbitTemplate;
43 |
44 | @Autowired
45 | private Queue queueForSee;
46 |
47 | @Test
48 | public void testSeeFromAmqp() {
49 | this.rabbitTemplate.convertAndSend(this.queueForSee.getName(), "foo");
50 | this.rabbitTemplate.convertAndSend(this.queueForSee.getName(), "bar");
51 | this.rabbitTemplate.convertAndSend(this.queueForSee.getName(), "baz");
52 |
53 | Flux flux1 =
54 | this.webTestClient.get().uri("/sseFromAmqp")
55 | .exchange()
56 | .returnResult(String.class)
57 | .getResponseBody();
58 |
59 | StepVerifier
60 | .create(flux1)
61 | .expectNext("foo", "bar", "baz")
62 | .thenCancel()
63 | .verify();
64 | }
65 |
66 | }
67 |
--------------------------------------------------------------------------------
/cloud-stream-kinesis-to-webflux/.gitignore:
--------------------------------------------------------------------------------
1 | /target/
2 | !.mvn/wrapper/maven-wrapper.jar
3 |
4 | ### STS ###
5 | .apt_generated
6 | .classpath
7 | .factorypath
8 | .project
9 | .settings
10 | .springBeans
11 | .sts4-cache
12 |
13 | ### IntelliJ IDEA ###
14 | .idea
15 | *.iws
16 | *.iml
17 | *.ipr
18 |
19 | ### NetBeans ###
20 | /nbproject/private/
21 | /build/
22 | /nbbuild/
23 | /dist/
24 | /nbdist/
25 | /.nb-gradle/
--------------------------------------------------------------------------------
/cloud-stream-kinesis-to-webflux/.mvn/wrapper/maven-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/artembilan/sandbox/df95ea33d5189ac11b6d7f6149df9f803eff514b/cloud-stream-kinesis-to-webflux/.mvn/wrapper/maven-wrapper.jar
--------------------------------------------------------------------------------
/cloud-stream-kinesis-to-webflux/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.3/apache-maven-3.5.3-bin.zip
2 |
--------------------------------------------------------------------------------
/cloud-stream-kinesis-to-webflux/README.adoc:
--------------------------------------------------------------------------------
1 | == Reactive Spring Cloud Stream AWS Kinesis Binder to SSE via WebFlux
2 |
3 | This sample demonstrate a simple bridging of AWS Kinesis stream records to the Server Side Events subscribers.
4 | The `@StreamListener` sink side is based on the Spring Cloud Stream Reactive support streaming incoming message to the `Flux` argument which, in turn, is used as a source for the `@GetMapping` controller.
5 |
6 |
--------------------------------------------------------------------------------
/cloud-stream-kinesis-to-webflux/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | org.springframework.cloud.stream.kinesis.webflux.so51669324
7 | cloud-stream-kinesis-to-webflux
8 | 0.0.1-SNAPSHOT
9 | jar
10 |
11 | cloud-stream-kinesis-to-webflux
12 | Demo project for Spring Boot
13 |
14 |
15 | org.springframework.boot
16 | spring-boot-starter-parent
17 | 2.0.4.RELEASE
18 |
19 |
20 |
21 |
22 | UTF-8
23 | UTF-8
24 | 1.8
25 | Finchley.SR1
26 |
27 |
28 |
29 |
30 | org.springframework.boot
31 | spring-boot-starter-webflux
32 |
33 |
34 | org.springframework.cloud
35 | spring-cloud-stream-reactive
36 |
37 |
38 | org.springframework.cloud
39 | spring-cloud-stream-binder-kinesis
40 | 1.0.0.RC1
41 |
42 |
43 |
44 | org.springframework.boot
45 | spring-boot-starter-test
46 | test
47 |
48 |
49 | io.projectreactor
50 | reactor-test
51 | test
52 |
53 |
54 |
55 |
56 |
57 |
58 | org.springframework.cloud
59 | spring-cloud-dependencies
60 | ${spring-cloud.version}
61 | pom
62 | import
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 | org.springframework.boot
71 | spring-boot-maven-plugin
72 |
73 |
74 |
75 |
76 |
77 |
78 | spring-milestones
79 | Spring Milestones
80 | https://repo.spring.io/libs-milestone-local
81 |
82 | false
83 |
84 |
85 |
86 | spring-releases
87 | Spring Releases
88 | https://repo.spring.io/release
89 |
90 | false
91 |
92 |
93 |
94 |
95 |
96 |
--------------------------------------------------------------------------------
/cloud-stream-kinesis-to-webflux/src/main/java/org/springframework/cloud/stream/kinesis/webflux/so51669324/CloudStreamKinesisToWebfluxApplication.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cloud.stream.kinesis.webflux.so51669324;
18 |
19 | import java.nio.charset.StandardCharsets;
20 | import java.util.List;
21 |
22 | import org.springframework.boot.SpringApplication;
23 | import org.springframework.boot.autoconfigure.SpringBootApplication;
24 | import org.springframework.cloud.stream.annotation.EnableBinding;
25 | import org.springframework.cloud.stream.annotation.StreamListener;
26 | import org.springframework.cloud.stream.messaging.Sink;
27 | import org.springframework.http.MediaType;
28 | import org.springframework.web.bind.annotation.GetMapping;
29 | import org.springframework.web.bind.annotation.RestController;
30 |
31 | import com.amazonaws.services.kinesis.model.Record;
32 | import reactor.core.publisher.ConnectableFlux;
33 | import reactor.core.publisher.Flux;
34 | import reactor.core.publisher.UnicastProcessor;
35 |
36 | @SpringBootApplication
37 | @EnableBinding(Sink.class)
38 | @RestController
39 | public class CloudStreamKinesisToWebfluxApplication {
40 |
41 | private volatile Flux recordFlux;
42 |
43 | @GetMapping(value = "/sseFromKinesis", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
44 | public Flux getSeeFromKinesis() {
45 | return this.recordFlux;
46 | }
47 |
48 | @StreamListener(Sink.INPUT)
49 | public void kinesisSink(Flux> recordFlux) {
50 | this.recordFlux = recordFlux
51 | .flatMap(Flux::fromIterable)
52 | .map(record -> new String(record.getData().array(), StandardCharsets.UTF_8));
53 | }
54 |
55 |
56 | public static void main(String[] args) {
57 | SpringApplication.run(CloudStreamKinesisToWebfluxApplication.class, args);
58 | }
59 |
60 | }
61 |
--------------------------------------------------------------------------------
/cloud-stream-kinesis-to-webflux/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | cloud:
3 | stream:
4 | bindings:
5 | input:
6 | destination: SSE_DATA
7 | group: kinesis-to-sse
8 | contentType: application/octet-stream
9 | consumer:
10 | headerMode: none
11 | kinesis:
12 | bindings:
13 | input:
14 | consumer:
15 | listenerMode: rawRecords
16 |
17 | cloud:
18 | aws:
19 | region:
20 | static: eu-west-1
21 |
--------------------------------------------------------------------------------
/graph-sample-all-components/.gitignore:
--------------------------------------------------------------------------------
1 | HELP.md
2 | target/
3 | !.mvn/wrapper/maven-wrapper.jar
4 | !**/src/main/**
5 | !**/src/test/**
6 |
7 | ### STS ###
8 | .apt_generated
9 | .classpath
10 | .factorypath
11 | .project
12 | .settings
13 | .springBeans
14 | .sts4-cache
15 |
16 | ### IntelliJ IDEA ###
17 | .idea
18 | *.iws
19 | *.iml
20 | *.ipr
21 |
22 | ### NetBeans ###
23 | /nbproject/private/
24 | /nbbuild/
25 | /dist/
26 | /nbdist/
27 | /.nb-gradle/
28 | build/
29 |
30 | ### VS Code ###
31 | .vscode/
32 |
--------------------------------------------------------------------------------
/graph-sample-all-components/.mvn/wrapper/maven-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/artembilan/sandbox/df95ea33d5189ac11b6d7f6149df9f803eff514b/graph-sample-all-components/.mvn/wrapper/maven-wrapper.jar
--------------------------------------------------------------------------------
/graph-sample-all-components/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.2/apache-maven-3.6.2-bin.zip
2 | wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar
3 |
--------------------------------------------------------------------------------
/graph-sample-all-components/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | org.springframework.boot
7 | spring-boot-starter-parent
8 | 2.2.2.RELEASE
9 |
10 |
11 | org.springframework.integration
12 | graph-sample-all-components
13 | 0.0.1-SNAPSHOT
14 | graph-sample-all-components
15 | Demo project for Spring Integration Graph
16 |
17 |
18 | 1.8
19 | 5.3.0.BUILD-SNAPSHOT
20 |
21 |
22 |
23 |
24 | org.springframework.boot
25 | spring-boot-starter-integration
26 |
27 |
28 | org.springframework.boot
29 | spring-boot-starter-web
30 |
31 |
32 | org.springframework.integration
33 | spring-integration-http
34 |
35 |
36 |
37 | org.springframework.boot
38 | spring-boot-starter-test
39 | test
40 |
41 |
42 | org.junit.vintage
43 | junit-vintage-engine
44 |
45 |
46 |
47 |
48 | org.springframework.amqp
49 | spring-rabbit-test
50 | test
51 |
52 |
53 |
54 |
55 |
56 |
57 | org.springframework.boot
58 | spring-boot-maven-plugin
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 | spring-snapshots
67 | Spring Snapshots
68 | https://repo.spring.io/libs-snapshot-local
69 |
70 | true
71 |
72 |
73 | false
74 |
75 |
76 |
77 | spring-milestones
78 | Spring Milestones
79 | https://repo.spring.io/libs-milestone-local
80 |
81 | false
82 |
83 |
84 |
85 | spring-releases
86 | Spring Releases
87 | https://repo.spring.io/release
88 |
89 | false
90 |
91 |
92 |
93 |
94 |
95 |
--------------------------------------------------------------------------------
/graph-sample-all-components/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | spring.application.name=testApplication
2 | spring.jackson.serialization.indent-output=true
3 |
--------------------------------------------------------------------------------
/graph-sample-all-components/src/test/java/org/springframework/integration/graphsample/GraphSampleAllComponentsApplicationTests.java:
--------------------------------------------------------------------------------
1 | package org.springframework.integration.graphsample;
2 |
3 | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
4 | import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
5 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
6 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.handler;
7 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
8 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
9 |
10 | import org.junit.jupiter.api.Test;
11 |
12 | import org.springframework.beans.factory.annotation.Autowired;
13 | import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
14 | import org.springframework.boot.test.context.SpringBootTest;
15 | import org.springframework.http.MediaType;
16 | import org.springframework.integration.http.management.IntegrationGraphController;
17 | import org.springframework.test.annotation.DirtiesContext;
18 | import org.springframework.test.web.servlet.MockMvc;
19 |
20 | @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK)
21 | @AutoConfigureMockMvc
22 | @DirtiesContext
23 | class GraphSampleAllComponentsApplicationTests {
24 |
25 | @Test
26 | void testIntegrationGraphGet(@Autowired MockMvc mockMvc) throws Exception {
27 | mockMvc.perform(get("/integration")
28 | .accept(MediaType.APPLICATION_JSON))
29 | .andExpect(status().isOk())
30 | .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
31 | .andExpect(handler().handlerType(IntegrationGraphController.class))
32 | .andExpect(handler().methodName("getGraph"))
33 | .andExpect(jsonPath("$.contentDescriptor.name").value("testApplication"))
34 | .andExpect(jsonPath("$.links").exists())
35 | .andDo(print());
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/http-reply-and-process/.gitignore:
--------------------------------------------------------------------------------
1 | HELP.md
2 | target/
3 | !.mvn/wrapper/maven-wrapper.jar
4 | !**/src/main/**
5 | !**/src/test/**
6 |
7 | ### STS ###
8 | .apt_generated
9 | .classpath
10 | .factorypath
11 | .project
12 | .settings
13 | .springBeans
14 | .sts4-cache
15 |
16 | ### IntelliJ IDEA ###
17 | .idea
18 | *.iws
19 | *.iml
20 | *.ipr
21 |
22 | ### NetBeans ###
23 | /nbproject/private/
24 | /nbbuild/
25 | /dist/
26 | /nbdist/
27 | /.nb-gradle/
28 | build/
29 |
30 | ### VS Code ###
31 | .vscode/
32 |
--------------------------------------------------------------------------------
/http-reply-and-process/.mvn/wrapper/maven-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/artembilan/sandbox/df95ea33d5189ac11b6d7f6149df9f803eff514b/http-reply-and-process/.mvn/wrapper/maven-wrapper.jar
--------------------------------------------------------------------------------
/http-reply-and-process/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.0/apache-maven-3.6.0-bin.zip
2 |
--------------------------------------------------------------------------------
/http-reply-and-process/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | org.springframework.boot
7 | spring-boot-starter-parent
8 | 2.2.0.RC1
9 |
10 |
11 | org.springframework.integration.stackoverflow
12 | http-reply-and-process
13 | 0.0.1-SNAPSHOT
14 | http-reply-and-process
15 | Demo project for SO58134243
16 |
17 |
18 | 1.8
19 |
20 |
21 |
22 |
23 | org.springframework.boot
24 | spring-boot-starter-activemq
25 |
26 |
27 | org.springframework.boot
28 | spring-boot-starter-integration
29 |
30 |
31 | org.springframework.integration
32 | spring-integration-http
33 |
34 |
35 | org.springframework.integration
36 | spring-integration-jms
37 |
38 |
39 | org.springframework.boot
40 | spring-boot-starter-web
41 |
42 |
43 |
44 | org.springframework.boot
45 | spring-boot-starter-test
46 | test
47 |
48 |
49 | org.junit.vintage
50 | junit-vintage-engine
51 |
52 |
53 |
54 |
55 | org.springframework.integration
56 | spring-integration-test
57 | test
58 |
59 |
60 |
61 |
62 |
63 |
64 | org.springframework.boot
65 | spring-boot-maven-plugin
66 |
67 |
68 |
69 |
70 |
71 |
72 | spring-milestones
73 | Spring Milestones
74 | https://repo.spring.io/milestone
75 |
76 |
77 |
78 |
79 | spring-milestones
80 | Spring Milestones
81 | https://repo.spring.io/milestone
82 |
83 |
84 |
85 |
86 |
--------------------------------------------------------------------------------
/http-reply-and-process/src/main/java/org/springframework/integration/stackoverflow/httpreplyandprocess/HttpReplyAndProcessApplication.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.integration.stackoverflow.httpreplyandprocess;
18 |
19 | import java.util.Collections;
20 |
21 | import javax.jms.ConnectionFactory;
22 |
23 | import org.springframework.boot.SpringApplication;
24 | import org.springframework.boot.autoconfigure.SpringBootApplication;
25 | import org.springframework.context.annotation.Bean;
26 | import org.springframework.http.HttpStatus;
27 | import org.springframework.integration.dsl.IntegrationFlow;
28 | import org.springframework.integration.dsl.IntegrationFlows;
29 | import org.springframework.integration.http.HttpHeaders;
30 | import org.springframework.integration.http.dsl.Http;
31 | import org.springframework.integration.jms.dsl.Jms;
32 | import org.springframework.jms.core.JmsTemplate;
33 |
34 | /**
35 | * @author Artem Bilan
36 | */
37 | @SpringBootApplication
38 | public class HttpReplyAndProcessApplication {
39 |
40 | public static void main(String[] args) {
41 | SpringApplication.run(HttpReplyAndProcessApplication.class, args);
42 | }
43 |
44 | @Bean
45 | public IntegrationFlow replyAndProcessFlow(JmsTemplate jmsTemplate) {
46 | return IntegrationFlows.from(Http.inboundGateway("/replyAndProcess"))
47 | .publishSubscribeChannel(publishSubscribeSpec ->
48 | publishSubscribeSpec.subscribe(flow -> flow
49 | .transform((payload) -> "OK")
50 | .enrichHeaders(Collections.singletonMap(HttpHeaders.STATUS_CODE, HttpStatus.ACCEPTED))))
51 | .transform(String::toUpperCase)
52 | .handle(Jms.outboundAdapter(jmsTemplate).destination("resultQueue"))
53 | .get();
54 | }
55 |
56 | }
57 |
--------------------------------------------------------------------------------
/http-reply-and-process/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/http-reply-and-process/src/test/java/org/springframework/integration/stackoverflow/httpreplyandprocess/HttpReplyAndProcessApplicationTests.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.integration.stackoverflow.httpreplyandprocess;
18 |
19 | import static org.assertj.core.api.Assertions.assertThat;
20 |
21 | import javax.jms.JMSException;
22 | import javax.jms.Message;
23 | import javax.jms.TextMessage;
24 |
25 | import org.junit.jupiter.api.Test;
26 |
27 | import org.springframework.beans.factory.annotation.Autowired;
28 | import org.springframework.boot.test.context.SpringBootTest;
29 | import org.springframework.boot.test.web.client.TestRestTemplate;
30 | import org.springframework.integration.dsl.IntegrationFlow;
31 | import org.springframework.integration.dsl.context.IntegrationFlowContext;
32 | import org.springframework.integration.http.dsl.Http;
33 | import org.springframework.jms.core.JmsTemplate;
34 | import org.springframework.test.annotation.DirtiesContext;
35 |
36 | @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
37 | @DirtiesContext
38 | class HttpReplyAndProcessApplicationTests {
39 |
40 | @Autowired
41 | private TestRestTemplate testRestTemplate;
42 |
43 | @Autowired
44 | private IntegrationFlowContext integrationFlowContext;
45 |
46 | @Autowired
47 | private JmsTemplate jmsTemplate;
48 |
49 | @Test
50 | void testReplyAndProcess() throws JMSException {
51 |
52 | IntegrationFlow clientFlow =
53 | (flow) -> flow
54 | .handle(
55 | Http.outboundGateway(this.testRestTemplate.getRootUri() + "/replyAndProcess",
56 | this.testRestTemplate.getRestTemplate())
57 | .expectedResponseType(String.class));
58 |
59 | IntegrationFlowContext.IntegrationFlowRegistration registration =
60 | this.integrationFlowContext
61 | .registration(clientFlow).register();
62 |
63 | String reply = registration.getMessagingTemplate().convertSendAndReceive("test", String.class);
64 | assertThat(reply).isEqualTo("OK");
65 |
66 | Message result = this.jmsTemplate.receive("resultQueue");
67 |
68 | assertThat(result).isNotNull();
69 |
70 | String payload = ((TextMessage) result).getText();
71 | assertThat(payload).isEqualTo("TEST");
72 | }
73 |
74 | }
75 |
--------------------------------------------------------------------------------
/images/IntegrationGraph.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/artembilan/sandbox/df95ea33d5189ac11b6d7f6149df9f803eff514b/images/IntegrationGraph.png
--------------------------------------------------------------------------------
/kinesis-binder-observation-demo/.gitignore:
--------------------------------------------------------------------------------
1 | HELP.md
2 | target/
3 | !.mvn/wrapper/maven-wrapper.jar
4 | !**/src/main/**/target/
5 | !**/src/test/**/target/
6 |
7 | ### STS ###
8 | .apt_generated
9 | .classpath
10 | .factorypath
11 | .project
12 | .settings
13 | .springBeans
14 | .sts4-cache
15 |
16 | ### IntelliJ IDEA ###
17 | .idea
18 | *.iws
19 | *.iml
20 | *.ipr
21 |
22 | ### NetBeans ###
23 | /nbproject/private/
24 | /nbbuild/
25 | /dist/
26 | /nbdist/
27 | /.nb-gradle/
28 | build/
29 | !**/src/main/**/build/
30 | !**/src/test/**/build/
31 |
32 | ### VS Code ###
33 | .vscode/
34 |
--------------------------------------------------------------------------------
/kinesis-binder-observation-demo/.mvn/wrapper/maven-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/artembilan/sandbox/df95ea33d5189ac11b6d7f6149df9f803eff514b/kinesis-binder-observation-demo/.mvn/wrapper/maven-wrapper.jar
--------------------------------------------------------------------------------
/kinesis-binder-observation-demo/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.6/apache-maven-3.8.6-bin.zip
2 | wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar
3 |
--------------------------------------------------------------------------------
/kinesis-binder-observation-demo/README.adoc:
--------------------------------------------------------------------------------
1 | == Observation over Spring Cloud Stream AWS Kinesis Binder
2 |
3 | This sample demonstrates an observation and tracing propagation over Spring Cloud Stream destination.
4 |
5 | In this case the application is a WebFlux server to receive `GET` request on a `/test`.
6 | Such a request then handled by Spring Cloud Stream `Supplier` bound to the `my-event` AWS Kinesis stream.
7 | A `name` request param becomes a payload of a message sent to the binder.
8 |
9 | To enable observation we added:
10 |
11 | 1. A `io.micrometer:micrometer-tracing-bridge-brave` dependency to handle tracing via Brave library;
12 | 2. A configuration property `spring.integration.management.observation-patterns=httpSupplier-out-0` to enable observation on a `MessageChannel` tied to the `httpSupplier-out-0` binding;
13 | 3. A configuration property `spring.cloud.stream.kinesis.binder.headers=traceparent` to ensure that W3C tracing header is embedded into Kinesis record for propagation over Kinesis stream.
14 |
15 | The unit test with Localstack Testcontainers environment ensures that HTTP request produced to our application propagates a tracing data over Kinesis stream which we check with a `KinesisMessageDrivenChannelAdapter` subscribed on the mentioned `my-event` bound destination.
16 | This `KinesisMessageDrivenChannelAdapter` is configured to use the same Spring Cloud Stream API for embedded headers for protocol like AWS Kinesis which don't support headers abstraction in their events.
17 |
--------------------------------------------------------------------------------
/kinesis-binder-observation-demo/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | org.springframework.boot
7 | spring-boot-starter-parent
8 | 3.0.1
9 |
10 |
11 | com.example
12 | kinesis-binder-observation-demo
13 | 0.0.1-SNAPSHOT
14 | kinesis-binder-observation-demo
15 | kinesis-binder-observation-demo
16 |
17 | 17
18 | 2022.0.1
19 |
20 |
21 |
22 | org.springframework.cloud
23 | spring-cloud-stream
24 |
25 |
26 | org.springframework.cloud
27 | spring-cloud-stream-binder-kinesis
28 | 3.0.0
29 |
30 |
31 | org.springframework.boot
32 | spring-boot-starter-test
33 | test
34 |
35 |
36 | org.testcontainers
37 | junit-jupiter
38 | 1.17.6
39 | test
40 |
41 |
42 | org.testcontainers
43 | localstack
44 | 1.17.6
45 | test
46 |
47 |
48 |
49 |
50 |
51 | org.springframework.cloud
52 | spring-cloud-dependencies
53 | ${spring-cloud.version}
54 | pom
55 | import
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 | org.springframework.boot
64 | spring-boot-maven-plugin
65 |
66 |
67 |
68 |
69 |
70 |
--------------------------------------------------------------------------------
/kinesis-binder-observation-demo/src/main/java/com/example/kinesisbinderobservationdemo/KinesisBinderObservationDemoApplication.java:
--------------------------------------------------------------------------------
1 | package com.example.kinesisbinderobservationdemo;
2 |
3 | import java.util.function.Consumer;
4 |
5 | import org.springframework.boot.SpringApplication;
6 | import org.springframework.boot.autoconfigure.SpringBootApplication;
7 | import org.springframework.cloud.stream.binder.EmbeddedHeaderUtils;
8 | import org.springframework.cloud.stream.binder.MessageValues;
9 | import org.springframework.cloud.stream.binder.kinesis.properties.KinesisProducerProperties;
10 | import org.springframework.cloud.stream.binding.NewDestinationBindingCallback;
11 | import org.springframework.context.annotation.Bean;
12 | import org.springframework.integration.channel.DirectChannel;
13 | import org.springframework.integration.channel.QueueChannel;
14 | import org.springframework.integration.support.MessageBuilder;
15 | import org.springframework.messaging.Message;
16 | import org.springframework.messaging.MessageChannel;
17 | import org.springframework.messaging.support.ChannelInterceptor;
18 |
19 | @SpringBootApplication
20 | public class KinesisBinderObservationDemoApplication {
21 |
22 | public static void main(String[] args) {
23 | SpringApplication.run(KinesisBinderObservationDemoApplication.class, args);
24 | }
25 |
26 | @Bean
27 | public Consumer> kinesisConsumer(QueueChannel testBuffer) {
28 | return testBuffer::send;
29 | }
30 |
31 | @Bean
32 | public QueueChannel testBuffer() {
33 | return new QueueChannel();
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/kinesis-binder-observation-demo/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | spring.cloud.stream.bindings.kinesisConsumer-in-0.destination=my-event
2 | spring.cloud.stream.bindings.kinesisConsumer-in-0.group=my-group
3 | spring.cloud.stream.kinesis.binder.headers=X-B3-TraceId,my-name
4 |
--------------------------------------------------------------------------------
/kinesis-binder-observation-demo/src/test/java/com/example/kinesisbinderobservationdemo/KinesisBinderObservationDemoApplicationTests.java:
--------------------------------------------------------------------------------
1 | package com.example.kinesisbinderobservationdemo;
2 |
3 | import com.amazonaws.services.dynamodbv2.AmazonDynamoDBAsync;
4 | import com.amazonaws.services.kinesis.AmazonKinesisAsync;
5 | import org.junit.jupiter.api.Test;
6 |
7 | import org.springframework.beans.factory.annotation.Autowired;
8 | import org.springframework.boot.test.context.SpringBootTest;
9 | import org.springframework.boot.test.context.TestConfiguration;
10 | import org.springframework.cloud.stream.function.StreamBridge;
11 | import org.springframework.context.annotation.Bean;
12 | import org.springframework.integration.channel.QueueChannel;
13 | import org.springframework.integration.support.MessageBuilder;
14 | import org.springframework.messaging.Message;
15 | import org.springframework.test.annotation.DirtiesContext;
16 | import org.springframework.test.context.DynamicPropertyRegistry;
17 | import org.springframework.test.context.DynamicPropertySource;
18 |
19 | import static org.assertj.core.api.Assertions.assertThat;
20 |
21 | @SpringBootTest
22 | @DirtiesContext
23 | class KinesisBinderObservationDemoApplicationTests {
24 |
25 | @Autowired
26 | StreamBridge streamBridge;
27 |
28 | @Autowired
29 | QueueChannel testBuffer;
30 |
31 | @Test
32 | void tracesArePropagateOverKinesis() {
33 | this.streamBridge.send("my-event",
34 | MessageBuilder.withPayload("test data")
35 | .setHeader("my-name", "Test Test")
36 | .setHeader("spring.cloud.function.definition", "myConsumer")
37 | .setHeader("X-B3-TraceId", "123")
38 | .build());
39 |
40 | Message> receive = this.testBuffer.receive(60_000);
41 | assertThat(receive).isNotNull();
42 | assertThat(receive.getPayload()).isEqualTo("test data");
43 | assertThat(receive.getHeaders())
44 | .containsKeys("my-name", "X-B3-TraceId")
45 | .doesNotContainKey("spring.cloud.function.definition");
46 | }
47 |
48 | }
49 |
--------------------------------------------------------------------------------
/leader-election/.gitignore:
--------------------------------------------------------------------------------
1 | HELP.md
2 | target/
3 | !.mvn/wrapper/maven-wrapper.jar
4 | !**/src/main/**/target/
5 | !**/src/test/**/target/
6 |
7 | ### STS ###
8 | .apt_generated
9 | .classpath
10 | .factorypath
11 | .project
12 | .settings
13 | .springBeans
14 | .sts4-cache
15 |
16 | ### IntelliJ IDEA ###
17 | .idea
18 | *.iws
19 | *.iml
20 | *.ipr
21 |
22 | ### NetBeans ###
23 | /nbproject/private/
24 | /nbbuild/
25 | /dist/
26 | /nbdist/
27 | /.nb-gradle/
28 | build/
29 | !**/src/main/**/build/
30 | !**/src/test/**/build/
31 |
32 | ### VS Code ###
33 | .vscode/
34 |
--------------------------------------------------------------------------------
/leader-election/.mvn/wrapper/maven-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/artembilan/sandbox/df95ea33d5189ac11b6d7f6149df9f803eff514b/leader-election/.mvn/wrapper/maven-wrapper.jar
--------------------------------------------------------------------------------
/leader-election/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.6/apache-maven-3.8.6-bin.zip
2 | wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar
3 |
--------------------------------------------------------------------------------
/leader-election/README.adoc:
--------------------------------------------------------------------------------
1 | == Leader Election with Zookeeper
2 |
3 | This sample demonstrate a distributed leader election and role control via Zookeeper.
4 |
5 | A `SourcePollingChannelAdapter` in the application context is marked as not started from the beginning and supplied with a `myRole` role.
6 | This role is used as a leadership election key in the `LeaderInitiatorFactoryBean` for Zookeeper server.
7 |
8 | An embedded `TestingServer` from Curator Framework is started in a JUnit test class.
9 | The unit test method starts two application context and verifies the `applicationEvents.txt` file content.
10 | When both application context are active, we see events only from one of them since exactly this one is a leader.
11 | When we stop the first application, the second takes a leadership, starts its endpoint and emits events for its environment.
12 | So, in the end we start seeing those events in the end of `applicationEvents.txt` file.
13 |
--------------------------------------------------------------------------------
/leader-election/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | org.springframework.boot
7 | spring-boot-starter-parent
8 | 3.0.1
9 |
10 |
11 | org.springframework.integration
12 | leader-election
13 | 0.0.1-SNAPSHOT
14 | leader-election
15 | leader-election
16 |
17 | 17
18 |
19 |
20 |
21 | org.springframework.boot
22 | spring-boot-starter-integration
23 |
24 |
25 |
26 | org.springframework.boot
27 | spring-boot-starter-test
28 | test
29 |
30 |
31 | org.springframework.integration
32 | spring-integration-zookeeper
33 |
34 |
35 | org.springframework.integration
36 | spring-integration-file
37 |
38 |
39 | org.springframework.integration
40 | spring-integration-test
41 | test
42 |
43 |
44 | org.apache.curator
45 | curator-test
46 | 5.4.0
47 | test
48 |
49 |
50 |
51 |
52 |
53 |
54 | org.springframework.boot
55 | spring-boot-maven-plugin
56 |
57 |
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/leader-election/src/main/java/org/springframework/integration/leaderelection/LeaderElectionApplication.java:
--------------------------------------------------------------------------------
1 | package org.springframework.integration.leaderelection;
2 |
3 | import java.io.File;
4 |
5 | import org.apache.curator.framework.CuratorFramework;
6 |
7 | import org.springframework.beans.factory.annotation.Value;
8 | import org.springframework.boot.SpringApplication;
9 | import org.springframework.boot.autoconfigure.SpringBootApplication;
10 | import org.springframework.context.annotation.Bean;
11 | import org.springframework.integration.dsl.IntegrationFlow;
12 | import org.springframework.integration.file.dsl.Files;
13 | import org.springframework.integration.file.support.FileExistsMode;
14 | import org.springframework.integration.zookeeper.config.LeaderInitiatorFactoryBean;
15 |
16 | @SpringBootApplication
17 | public class LeaderElectionApplication {
18 |
19 | public static void main(String[] args) {
20 | SpringApplication.run(LeaderElectionApplication.class, args);
21 | }
22 |
23 | @Bean
24 | LeaderInitiatorFactoryBean leaderInitiator(CuratorFramework client) {
25 | return new LeaderInitiatorFactoryBean()
26 | .setClient(client)
27 | .setPath("/someZkPath/")
28 | .setRole("myRole");
29 | }
30 |
31 | @Bean
32 | IntegrationFlow someFlow(@Value("${spring.application.name}") String applicationName,
33 | @Value("${output.directory}") File destinationDirectory) {
34 |
35 | return IntegrationFlow
36 | .fromSupplier(() -> applicationName,
37 | e -> e.role("myRole")
38 | .autoStartup(false)
39 | .poller(poller -> poller.fixedDelay(100)))
40 | .handle(Files.outboundAdapter(destinationDirectory)
41 | .fileNameGenerator(m -> "applicationEvents.txt")
42 | .fileExistsMode(FileExistsMode.APPEND)
43 | .appendNewLine(true))
44 | .get();
45 | }
46 |
47 | }
48 |
--------------------------------------------------------------------------------
/leader-election/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | logging.level.org.springframework.integration=debug
2 |
--------------------------------------------------------------------------------
/leader-election/src/test/java/org/springframework/integration/leaderelection/LeaderElectionApplicationTests.java:
--------------------------------------------------------------------------------
1 | package org.springframework.integration.leaderelection;
2 |
3 | import java.io.File;
4 | import java.io.IOException;
5 | import java.nio.file.Files;
6 | import java.util.List;
7 | import java.util.Map;
8 |
9 | import org.apache.curator.framework.CuratorFramework;
10 | import org.apache.curator.framework.CuratorFrameworkFactory;
11 | import org.apache.curator.retry.BoundedExponentialBackoffRetry;
12 | import org.apache.curator.test.TestingServer;
13 | import org.junit.jupiter.api.AfterAll;
14 | import org.junit.jupiter.api.BeforeAll;
15 | import org.junit.jupiter.api.Test;
16 | import org.junit.jupiter.api.io.TempDir;
17 |
18 | import org.springframework.boot.builder.SpringApplicationBuilder;
19 | import org.springframework.context.ConfigurableApplicationContext;
20 | import org.springframework.context.annotation.Bean;
21 | import org.springframework.context.annotation.Configuration;
22 |
23 | import static org.assertj.core.api.Assertions.assertThat;
24 |
25 | class LeaderElectionApplicationTests {
26 |
27 | @TempDir
28 | static File tmpDir;
29 |
30 | static TestingServer testingServer;
31 |
32 | @BeforeAll
33 | public static void setUpClass() throws Exception {
34 | testingServer = new TestingServer(true);
35 | }
36 |
37 | @AfterAll
38 | public static void tearDownClass() throws IOException {
39 | testingServer.stop();
40 | }
41 |
42 | @Test
43 | void distributedLeaderElectionOverZk() throws Exception {
44 | ConfigurableApplicationContext applicationContext1 =
45 | new SpringApplicationBuilder()
46 | .sources(CuratorClientConfiguration.class, LeaderElectionApplication.class)
47 | .properties(
48 | Map.of("spring.application.name", "application #1",
49 | "output.directory", tmpDir.getAbsolutePath()))
50 | .run();
51 |
52 | Thread.sleep(100); // Give the first application a chance to take a leadership
53 |
54 | ConfigurableApplicationContext applicationContext2 =
55 | new SpringApplicationBuilder()
56 | .sources(CuratorClientConfiguration.class, LeaderElectionApplication.class)
57 | .properties(
58 | Map.of("spring.application.name", "application #2",
59 | "output.directory", tmpDir.getAbsolutePath()))
60 | .run();
61 |
62 | Thread.sleep(1000); // Give applications a chance to generate some events.
63 |
64 | File eventsFile = new File(tmpDir, "applicationEvents.txt");
65 |
66 | List lines = Files.readAllLines(eventsFile.toPath());
67 |
68 | assertThat(lines).containsOnly("application #1");
69 |
70 | applicationContext1.close();
71 |
72 | Thread.sleep(1000); // Give the second application a chance to obtain a leadership and generate some events.
73 |
74 | lines = Files.readAllLines(eventsFile.toPath());
75 |
76 | assertThat(lines).containsOnly("application #1", "application #2");
77 |
78 | applicationContext2.close();
79 | }
80 |
81 | @Configuration
82 | public static class CuratorClientConfiguration {
83 |
84 | @Bean
85 | public CuratorFramework client() {
86 | CuratorFramework client = CuratorFrameworkFactory.newClient(testingServer.getConnectString(),
87 | new BoundedExponentialBackoffRetry(100, 1000, 3));
88 | client.start();
89 | return client;
90 | }
91 |
92 | }
93 |
94 | }
95 |
--------------------------------------------------------------------------------
/lock-on-oracle/.gitignore:
--------------------------------------------------------------------------------
1 | HELP.md
2 | target/
3 | !.mvn/wrapper/maven-wrapper.jar
4 | !**/src/main/**
5 | !**/src/test/**
6 |
7 | ### STS ###
8 | .apt_generated
9 | .classpath
10 | .factorypath
11 | .project
12 | .settings
13 | .springBeans
14 | .sts4-cache
15 |
16 | ### IntelliJ IDEA ###
17 | .idea
18 | *.iws
19 | *.iml
20 | *.ipr
21 |
22 | ### NetBeans ###
23 | /nbproject/private/
24 | /nbbuild/
25 | /dist/
26 | /nbdist/
27 | /.nb-gradle/
28 | build/
29 |
30 | ### VS Code ###
31 | .vscode/
32 |
--------------------------------------------------------------------------------
/lock-on-oracle/.mvn/wrapper/maven-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/artembilan/sandbox/df95ea33d5189ac11b6d7f6149df9f803eff514b/lock-on-oracle/.mvn/wrapper/maven-wrapper.jar
--------------------------------------------------------------------------------
/lock-on-oracle/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.2/apache-maven-3.6.2-bin.zip
2 | wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar
3 |
--------------------------------------------------------------------------------
/lock-on-oracle/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | org.springframework.boot
7 | spring-boot-starter-parent
8 | 2.2.2.RELEASE
9 |
10 |
11 | org.springframework.integration
12 | lock-on-oracle
13 | 0.0.1-SNAPSHOT
14 | lock-on-oracle
15 | Demo project for Spring Integration JDBC Lock
16 |
17 |
18 | 1.8
19 |
20 |
21 |
22 |
23 | org.springframework.boot
24 | spring-boot-starter-jdbc
25 |
26 |
27 |
28 | org.hsqldb
29 | hsqldb
30 | runtime
31 |
32 |
37 |
38 | org.springframework.boot
39 | spring-boot-starter-test
40 | test
41 |
42 |
43 | org.junit.vintage
44 | junit-vintage-engine
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 | org.springframework.boot
54 | spring-boot-maven-plugin
55 |
56 |
57 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/lock-on-oracle/src/main/java/org/springframework/integration/jdbc/lock/oracle/LockOnOracleApplication.java:
--------------------------------------------------------------------------------
1 | package org.springframework.integration.jdbc.lock.oracle;
2 |
3 | import java.util.Date;
4 | import java.util.UUID;
5 |
6 | import org.springframework.beans.factory.annotation.Autowired;
7 | import org.springframework.boot.SpringApplication;
8 | import org.springframework.boot.autoconfigure.SpringBootApplication;
9 | import org.springframework.dao.DuplicateKeyException;
10 | import org.springframework.jdbc.core.JdbcTemplate;
11 | import org.springframework.transaction.annotation.Isolation;
12 | import org.springframework.transaction.annotation.Transactional;
13 |
14 | @SpringBootApplication
15 | public class LockOnOracleApplication {
16 |
17 | public static void main(String[] args) {
18 | SpringApplication.run(LockOnOracleApplication.class, args);
19 | }
20 |
21 | private final String insertQuery = "INSERT INTO INT_LOCK (REGION, LOCK_KEY, CLIENT_ID, CREATED_DATE) VALUES (?, ?, ?, ?)";
22 |
23 | private final String updateQuery = "UPDATE INT_LOCK SET CREATED_DATE=? WHERE REGION=? AND LOCK_KEY=? AND CLIENT_ID=?";
24 |
25 | private final String region = "DEFAULT";
26 |
27 | private final String id = UUID.randomUUID().toString();
28 |
29 | @Autowired
30 | private JdbcTemplate jdbcTemplate;
31 |
32 | @Transactional(isolation = Isolation.SERIALIZABLE)
33 | public boolean acquire(String lock) {
34 | if (this.jdbcTemplate.update(this.updateQuery, new Date(), this.region, lock, this.id) > 0) {
35 | return true;
36 | }
37 | try {
38 | return this.jdbcTemplate.update(this.insertQuery, this.region, lock, this.id, new Date()) > 0;
39 | }
40 | catch (DuplicateKeyException e) {
41 | return false;
42 | }
43 | }
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/lock-on-oracle/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | logging.level.org.springframework.jdbc.core=trace
2 |
--------------------------------------------------------------------------------
/lock-on-oracle/src/test/java/org/springframework/integration/jdbc/lock/oracle/LockOnOracleApplicationTests.java:
--------------------------------------------------------------------------------
1 | package org.springframework.integration.jdbc.lock.oracle;
2 |
3 | import static org.assertj.core.api.Assertions.assertThat;
4 |
5 | import java.util.Date;
6 |
7 | import org.junit.jupiter.api.BeforeAll;
8 | import org.junit.jupiter.api.BeforeEach;
9 | import org.junit.jupiter.api.Test;
10 |
11 | import org.springframework.beans.factory.annotation.Autowired;
12 | import org.springframework.boot.test.context.SpringBootTest;
13 | import org.springframework.dao.DuplicateKeyException;
14 | import org.springframework.jdbc.core.JdbcTemplate;
15 | import org.springframework.transaction.annotation.Isolation;
16 | import org.springframework.transaction.annotation.Transactional;
17 |
18 | @SpringBootTest
19 | class LockOnOracleApplicationTests {
20 |
21 | @Autowired
22 | JdbcTemplate jdbcTemplate;
23 |
24 | @Autowired
25 | LockOnOracleApplication lockOnOracleApplication;
26 |
27 | @BeforeEach
28 | void setup() {
29 | this.jdbcTemplate.update("TRUNCATE TABLE INT_LOCK");
30 | }
31 |
32 | @Test
33 | void contextLoads() {
34 | assertThat(this.lockOnOracleApplication.acquire("foo")).isTrue();
35 | assertThat(this.lockOnOracleApplication.acquire("foo")).isTrue();
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/lock-on-oracle/src/test/resources/schema.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE INT_LOCK (
2 | LOCK_KEY CHAR(36) NOT NULL,
3 | REGION VARCHAR(100) NOT NULL,
4 | CLIENT_ID CHAR(36),
5 | CREATED_DATE TIMESTAMP NOT NULL,
6 | constraint INT_LOCK_PK primary key (LOCK_KEY, REGION)
7 | );
8 |
--------------------------------------------------------------------------------
/null-away-issue/.gitattributes:
--------------------------------------------------------------------------------
1 | /gradlew text eol=lf
2 | *.bat text eol=crlf
3 | *.jar binary
4 |
--------------------------------------------------------------------------------
/null-away-issue/.gitignore:
--------------------------------------------------------------------------------
1 | HELP.md
2 | .gradle
3 | build/
4 | !gradle/wrapper/gradle-wrapper.jar
5 | !**/src/main/**/build/
6 | !**/src/test/**/build/
7 |
8 | ### STS ###
9 | .apt_generated
10 | .classpath
11 | .factorypath
12 | .project
13 | .settings
14 | .springBeans
15 | .sts4-cache
16 | bin/
17 | !**/src/main/**/bin/
18 | !**/src/test/**/bin/
19 |
20 | ### IntelliJ IDEA ###
21 | .idea
22 | *.iws
23 | *.iml
24 | *.ipr
25 | out/
26 | !**/src/main/**/out/
27 | !**/src/test/**/out/
28 |
29 | ### NetBeans ###
30 | /nbproject/private/
31 | /nbbuild/
32 | /dist/
33 | /nbdist/
34 | /.nb-gradle/
35 |
36 | ### VS Code ###
37 | .vscode/
38 |
--------------------------------------------------------------------------------
/null-away-issue/README.md:
--------------------------------------------------------------------------------
1 | Just run `./gradlew check` and you'll see an error like:
2 | ```
3 | C:\SpringIO\sandbox\null-away-issue\src\main\java\org\springframework\example\nullawayissue\NullAwayIssueApplication.java:14: error: [NullAway] Cannot pass parameter of type @Nullable String[], as formal parameter has type Object[], which has mismatched type parameter nullability
4 | if (!ObjectUtils.isEmpty(args)) {
5 | ^
6 | (see http://t.uber.com/nullaway )
7 | C:\SpringIO\sandbox\null-away-issue\src\main\java\org\springframework\example\nullawayissue\NullAwayIssueApplication.java:20: error: [NullAway] Cannot pass parameter of type @Nullable Object[], as formal parameter has type Object[], which has mismatched type parameter nullability
8 | if (!ObjectUtils.isEmpty(application.someArgs)) {
9 | ^
10 | (see http://t.uber.com/nullaway )
11 | 2 errors
12 | ```
13 |
14 | Which is not expected by the `@NullMarked` in the `package-info.java` and `ObjectUtils.isEmpty()` contract.
--------------------------------------------------------------------------------
/null-away-issue/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'java'
3 | id 'org.springframework.boot' version '3.5.0-SNAPSHOT'
4 | id 'io.spring.dependency-management' version '1.1.7'
5 | id 'net.ltgt.errorprone' version '3.1.0'
6 | }
7 |
8 | group = 'org.springframework.example'
9 | version = '0.0.1-SNAPSHOT'
10 |
11 | java {
12 | toolchain {
13 | languageVersion = JavaLanguageVersion.of(17)
14 | }
15 | }
16 |
17 | repositories {
18 | mavenCentral()
19 | maven { url 'https://repo.spring.io/milestone' }
20 | maven { url 'https://repo.spring.io/snapshot' }
21 | }
22 |
23 | ext {
24 | set('spring-framework.version', '7.0.0-SNAPSHOT')
25 | }
26 |
27 | dependencies {
28 | implementation 'org.springframework.boot:spring-boot-starter'
29 | testImplementation 'org.springframework.boot:spring-boot-starter-test'
30 | testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
31 |
32 | errorprone 'com.uber.nullaway:nullaway:0.12.3'
33 | errorprone 'com.google.errorprone:error_prone_core:2.35.1'
34 | }
35 |
36 | tasks.named('test') {
37 | useJUnitPlatform()
38 | }
39 |
40 |
41 | tasks.withType(JavaCompile).configureEach {
42 | options.errorprone {
43 | disableAllChecks = true
44 | option('NullAway:OnlyNullMarked', 'true')
45 | option('NullAway:CustomContractAnnotations', 'org.springframework.lang.Contract')
46 | option('NullAway:JSpecifyMode', 'true')
47 | }
48 | }
49 |
50 | tasks.compileJava {
51 | // The check defaults to a warning, bump it up to an error for the main sources
52 | options.errorprone.error('NullAway')
53 | }
--------------------------------------------------------------------------------
/null-away-issue/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/artembilan/sandbox/df95ea33d5189ac11b6d7f6149df9f803eff514b/null-away-issue/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/null-away-issue/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.12.1-bin.zip
4 | networkTimeout=10000
5 | validateDistributionUrl=true
6 | zipStoreBase=GRADLE_USER_HOME
7 | zipStorePath=wrapper/dists
8 |
--------------------------------------------------------------------------------
/null-away-issue/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 | @rem SPDX-License-Identifier: Apache-2.0
17 | @rem
18 |
19 | @if "%DEBUG%"=="" @echo off
20 | @rem ##########################################################################
21 | @rem
22 | @rem Gradle startup script for Windows
23 | @rem
24 | @rem ##########################################################################
25 |
26 | @rem Set local scope for the variables with windows NT shell
27 | if "%OS%"=="Windows_NT" setlocal
28 |
29 | set DIRNAME=%~dp0
30 | if "%DIRNAME%"=="" set DIRNAME=.
31 | @rem This is normally unused
32 | set APP_BASE_NAME=%~n0
33 | set APP_HOME=%DIRNAME%
34 |
35 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
36 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
37 |
38 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
39 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
40 |
41 | @rem Find java.exe
42 | if defined JAVA_HOME goto findJavaFromJavaHome
43 |
44 | set JAVA_EXE=java.exe
45 | %JAVA_EXE% -version >NUL 2>&1
46 | if %ERRORLEVEL% equ 0 goto execute
47 |
48 | echo. 1>&2
49 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
50 | echo. 1>&2
51 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2
52 | echo location of your Java installation. 1>&2
53 |
54 | goto fail
55 |
56 | :findJavaFromJavaHome
57 | set JAVA_HOME=%JAVA_HOME:"=%
58 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
59 |
60 | if exist "%JAVA_EXE%" goto execute
61 |
62 | echo. 1>&2
63 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
64 | echo. 1>&2
65 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2
66 | echo location of your Java installation. 1>&2
67 |
68 | goto fail
69 |
70 | :execute
71 | @rem Setup the command line
72 |
73 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
74 |
75 |
76 | @rem Execute Gradle
77 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
78 |
79 | :end
80 | @rem End local scope for the variables with windows NT shell
81 | if %ERRORLEVEL% equ 0 goto mainEnd
82 |
83 | :fail
84 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
85 | rem the _cmd.exe /c_ return code!
86 | set EXIT_CODE=%ERRORLEVEL%
87 | if %EXIT_CODE% equ 0 set EXIT_CODE=1
88 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
89 | exit /b %EXIT_CODE%
90 |
91 | :mainEnd
92 | if "%OS%"=="Windows_NT" endlocal
93 |
94 | :omega
95 |
--------------------------------------------------------------------------------
/null-away-issue/settings.gradle:
--------------------------------------------------------------------------------
1 | pluginManagement {
2 | repositories {
3 | maven { url 'https://repo.spring.io/milestone' }
4 | maven { url 'https://repo.spring.io/snapshot' }
5 | gradlePluginPortal()
6 | }
7 | }
8 | rootProject.name = 'null-away-issue'
9 |
--------------------------------------------------------------------------------
/null-away-issue/src/main/java/org/springframework/example/nullawayissue/NullAwayIssueApplication.java:
--------------------------------------------------------------------------------
1 | package org.springframework.example.nullawayissue;
2 |
3 | import org.jspecify.annotations.Nullable;
4 |
5 | import org.springframework.boot.autoconfigure.SpringBootApplication;
6 | import org.springframework.util.ObjectUtils;
7 |
8 | @SpringBootApplication
9 | public class NullAwayIssueApplication {
10 |
11 | @Nullable Object @Nullable [] someArgs;
12 |
13 | public static void main(@Nullable String @Nullable [] args) {
14 | if (!ObjectUtils.isEmpty(args)) {
15 | System.out.println("All good");
16 | }
17 |
18 | NullAwayIssueApplication application = new NullAwayIssueApplication();
19 | application.someArgs = args;
20 | if (!ObjectUtils.isEmpty(application.someArgs)) {
21 | System.out.println("All good again");
22 | }
23 | }
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/null-away-issue/src/main/java/org/springframework/example/nullawayissue/package-info.java:
--------------------------------------------------------------------------------
1 | @org.jspecify.annotations.NullMarked
2 | package org.springframework.example.nullawayissue;
3 |
--------------------------------------------------------------------------------
/observation-over-stream-rabbit-binder/.gitignore:
--------------------------------------------------------------------------------
1 | HELP.md
2 | target/
3 | !.mvn/wrapper/maven-wrapper.jar
4 | !**/src/main/**/target/
5 | !**/src/test/**/target/
6 |
7 | ### STS ###
8 | .apt_generated
9 | .classpath
10 | .factorypath
11 | .project
12 | .settings
13 | .springBeans
14 | .sts4-cache
15 |
16 | ### IntelliJ IDEA ###
17 | .idea
18 | *.iws
19 | *.iml
20 | *.ipr
21 |
22 | ### NetBeans ###
23 | /nbproject/private/
24 | /nbbuild/
25 | /dist/
26 | /nbdist/
27 | /.nb-gradle/
28 | build/
29 | !**/src/main/**/build/
30 | !**/src/test/**/build/
31 |
32 | ### VS Code ###
33 | .vscode/
34 |
--------------------------------------------------------------------------------
/observation-over-stream-rabbit-binder/.mvn/wrapper/maven-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/artembilan/sandbox/df95ea33d5189ac11b6d7f6149df9f803eff514b/observation-over-stream-rabbit-binder/.mvn/wrapper/maven-wrapper.jar
--------------------------------------------------------------------------------
/observation-over-stream-rabbit-binder/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | # Licensed to the Apache Software Foundation (ASF) under one
2 | # or more contributor license agreements. See the NOTICE file
3 | # distributed with this work for additional information
4 | # regarding copyright ownership. The ASF licenses this file
5 | # to you under the Apache License, Version 2.0 (the
6 | # "License"); you may not use this file except in compliance
7 | # with the License. You may obtain a copy of the License at
8 | #
9 | # https://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing,
12 | # software distributed under the License is distributed on an
13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 | # KIND, either express or implied. See the License for the
15 | # specific language governing permissions and limitations
16 | # under the License.
17 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.7/apache-maven-3.8.7-bin.zip
18 | wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar
19 |
--------------------------------------------------------------------------------
/observation-over-stream-rabbit-binder/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | org.springframework.boot
7 | spring-boot-starter-parent
8 | 3.0.3
9 |
10 |
11 | com.example
12 | observation-over-stream-rabbit-binder
13 | 0.0.1-SNAPSHOT
14 | observation-over-stream-rabbit-binder
15 | observation-over-stream-rabbit-binder
16 |
17 | 17
18 | 2022.0.1
19 |
20 |
21 |
22 | org.springframework.boot
23 | spring-boot-starter-actuator
24 |
25 |
26 | io.micrometer
27 | micrometer-tracing-bridge-brave
28 |
29 |
30 | io.zipkin.reporter2
31 | zipkin-reporter-brave
32 |
33 |
34 | org.springframework.cloud
35 | spring-cloud-stream-binder-rabbit
36 |
37 |
38 |
39 |
40 |
41 | org.springframework.cloud
42 | spring-cloud-dependencies
43 | ${spring-cloud.version}
44 | pom
45 | import
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 | org.springframework.boot
54 | spring-boot-maven-plugin
55 |
56 |
57 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/observation-over-stream-rabbit-binder/src/main/java/com/example/stream/rabbit/binder/observation/ObservationOverStreamRabbitBinderApplication.java:
--------------------------------------------------------------------------------
1 | package com.example.stream.rabbit.binder.observation;
2 |
3 | import java.util.function.Consumer;
4 |
5 | import io.micrometer.observation.Observation;
6 | import io.micrometer.observation.ObservationRegistry;
7 | import org.apache.commons.logging.Log;
8 | import org.apache.commons.logging.LogFactory;
9 |
10 | import org.springframework.boot.ApplicationRunner;
11 | import org.springframework.boot.SpringApplication;
12 | import org.springframework.boot.autoconfigure.SpringBootApplication;
13 | import org.springframework.cloud.stream.function.StreamBridge;
14 | import org.springframework.context.annotation.Bean;
15 | import org.springframework.messaging.Message;
16 |
17 | @SpringBootApplication
18 | public class ObservationOverStreamRabbitBinderApplication {
19 |
20 | private static final Log LOGGER = LogFactory.getLog(ObservationOverStreamRabbitBinderApplication.class);
21 |
22 | public static void main(String[] args) {
23 | SpringApplication.run(ObservationOverStreamRabbitBinderApplication.class, args);
24 | }
25 |
26 | @Bean
27 | ApplicationRunner myApplicationRunner(StreamBridge streamBridge, ObservationRegistry observationRegistry) {
28 | return args ->
29 | Observation.createNotStarted("my parent observation", observationRegistry)
30 | .observe(() -> {
31 | String data = "my data";
32 | LOGGER.debug("Send data to RabbitMQ: " + data);
33 | streamBridge.send("myQueue", data);
34 | });
35 | }
36 |
37 | @Bean
38 | public Consumer> myRabbitConsumer() {
39 | return message -> LOGGER.debug("Received message from RabbitMQ: " + message);
40 | }
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/observation-over-stream-rabbit-binder/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | spring.application.name=my-application
2 | management.tracing.sampling.probability=1
3 | logging.pattern.level=%5p [${spring.application.name:},%X{traceId:-},%X{spanId:-}]
4 | logging.level.com.example.stream.rabbit.binder.observation=debug
5 | spring.cloud.stream.bindings.myRabbitConsumer-in-0.destination=myQueue
6 |
--------------------------------------------------------------------------------
/observation-over-stream-rabbit-binder/src/test/java/com/example/stream/rabbit/binder/observation/ObservationOverStreamRabbitBinderApplicationTests.java:
--------------------------------------------------------------------------------
1 | package com.example.stream.rabbit.binder.observation;
2 |
3 | import org.junit.jupiter.api.Test;
4 |
5 | import org.springframework.boot.test.context.SpringBootTest;
6 |
7 | @SpringBootTest
8 | class ObservationOverStreamRabbitBinderApplicationTests {
9 |
10 | @Test
11 | void contextLoads() {
12 | }
13 |
14 | }
15 |
--------------------------------------------------------------------------------
/postgres-channel-observation/.gitignore:
--------------------------------------------------------------------------------
1 | HELP.md
2 | .gradle
3 | build/
4 | !gradle/wrapper/gradle-wrapper.jar
5 | !**/src/main/**/build/
6 | !**/src/test/**/build/
7 |
8 | ### STS ###
9 | .apt_generated
10 | .classpath
11 | .factorypath
12 | .project
13 | .settings
14 | .springBeans
15 | .sts4-cache
16 | bin/
17 | !**/src/main/**/bin/
18 | !**/src/test/**/bin/
19 |
20 | ### IntelliJ IDEA ###
21 | .idea
22 | *.iws
23 | *.iml
24 | *.ipr
25 | out/
26 | !**/src/main/**/out/
27 | !**/src/test/**/out/
28 |
29 | ### NetBeans ###
30 | /nbproject/private/
31 | /nbbuild/
32 | /dist/
33 | /nbdist/
34 | /.nb-gradle/
35 |
36 | ### VS Code ###
37 | .vscode/
38 |
--------------------------------------------------------------------------------
/postgres-channel-observation/README.adoc:
--------------------------------------------------------------------------------
1 | = Tracing Over PostgreSQL Message Channel
2 |
3 | This sample demonstrates a `PostgresSubscribableChannel` and how an `Observation` is propagated from producer to consumer.
4 |
5 | To propagate an observation over this channel, there is enough to have it enabled on this channel and on its subscriber:
6 |
7 | [source,properties]
8 | ----
9 | spring.integration.management.observation-patterns=postgresChannel,postgresHandler
10 | ----
11 |
12 | It uses Spring Boot https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#features.testing.testcontainers.service-connections[Service Connections] in the test to start Testcontainers for PostgreSQL DB.
13 | The `TestSpanHandler` from the `io.micrometer:micrometer-tracing-integration-test` is used to verify the tracing in the application.
14 | And also the test checks for the common `traceId` in the `CapturedOutput`, which is logged by the `postgresHandler` `@ServiceActivator`.
15 |
16 | See https://docs.spring.io/spring-integration/reference/jdbc/message-store.html#postgresql-push[Spring Integration JDBC] module for more information.
17 |
--------------------------------------------------------------------------------
/postgres-channel-observation/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'java'
3 | id 'org.springframework.boot' version '3.2.3'
4 | id 'io.spring.dependency-management' version '1.1.4'
5 | }
6 |
7 | group = 'org.springframework.integration'
8 | version = '0.0.1-SNAPSHOT'
9 |
10 | java {
11 | sourceCompatibility = '17'
12 | }
13 |
14 | repositories {
15 | mavenCentral()
16 | }
17 |
18 | dependencies {
19 | implementation 'org.springframework.boot:spring-boot-starter-actuator'
20 | implementation 'org.springframework.boot:spring-boot-starter-integration'
21 | implementation 'org.springframework.boot:spring-boot-starter-jdbc'
22 | implementation 'org.springframework.integration:spring-integration-jdbc'
23 | implementation 'io.micrometer:micrometer-tracing-bridge-brave'
24 | implementation 'org.postgresql:postgresql'
25 |
26 | testImplementation 'org.springframework.boot:spring-boot-starter-test'
27 | testImplementation 'org.springframework.boot:spring-boot-testcontainers'
28 | testImplementation 'org.springframework.integration:spring-integration-test'
29 | testImplementation 'org.testcontainers:postgresql'
30 | testImplementation 'io.micrometer:micrometer-observation-test'
31 | testImplementation('io.micrometer:micrometer-tracing-integration-test') {
32 | exclude group: 'io.zipkin.reporter2'
33 | exclude group: 'io.opentelemetry'
34 | exclude group: 'com.wavefront'
35 | exclude group: 'io.micrometer', module: 'micrometer-tracing-bridge-otel'
36 | }
37 | }
38 |
39 | tasks.named('test') {
40 | useJUnitPlatform()
41 | }
42 |
--------------------------------------------------------------------------------
/postgres-channel-observation/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/artembilan/sandbox/df95ea33d5189ac11b6d7f6149df9f803eff514b/postgres-channel-observation/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/postgres-channel-observation/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright 2012-2024 the original author or authors.
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # https://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 | #
16 |
17 | distributionBase=GRADLE_USER_HOME
18 | distributionPath=wrapper/dists
19 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip
20 | networkTimeout=10000
21 | validateDistributionUrl=true
22 | zipStoreBase=GRADLE_USER_HOME
23 | zipStorePath=wrapper/dists
24 |
--------------------------------------------------------------------------------
/postgres-channel-observation/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%"=="" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%"=="" set DIRNAME=.
29 | @rem This is normally unused
30 | set APP_BASE_NAME=%~n0
31 | set APP_HOME=%DIRNAME%
32 |
33 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
34 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
35 |
36 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
37 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
38 |
39 | @rem Find java.exe
40 | if defined JAVA_HOME goto findJavaFromJavaHome
41 |
42 | set JAVA_EXE=java.exe
43 | %JAVA_EXE% -version >NUL 2>&1
44 | if %ERRORLEVEL% equ 0 goto execute
45 |
46 | echo.
47 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
48 | echo.
49 | echo Please set the JAVA_HOME variable in your environment to match the
50 | echo location of your Java installation.
51 |
52 | goto fail
53 |
54 | :findJavaFromJavaHome
55 | set JAVA_HOME=%JAVA_HOME:"=%
56 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
57 |
58 | if exist "%JAVA_EXE%" goto execute
59 |
60 | echo.
61 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
62 | echo.
63 | echo Please set the JAVA_HOME variable in your environment to match the
64 | echo location of your Java installation.
65 |
66 | goto fail
67 |
68 | :execute
69 | @rem Setup the command line
70 |
71 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
72 |
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if %ERRORLEVEL% equ 0 goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | set EXIT_CODE=%ERRORLEVEL%
85 | if %EXIT_CODE% equ 0 set EXIT_CODE=1
86 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
87 | exit /b %EXIT_CODE%
88 |
89 | :mainEnd
90 | if "%OS%"=="Windows_NT" endlocal
91 |
92 | :omega
93 |
--------------------------------------------------------------------------------
/postgres-channel-observation/settings.gradle:
--------------------------------------------------------------------------------
1 | rootProject.name = 'postgres-channel-observation'
2 |
--------------------------------------------------------------------------------
/postgres-channel-observation/src/main/java/org/springframework/integration/postgreschannelobservation/PostgresChannelObservationApplication.java:
--------------------------------------------------------------------------------
1 | package org.springframework.integration.postgreschannelobservation;
2 |
3 | import java.sql.DriverManager;
4 |
5 | import javax.sql.DataSource;
6 |
7 | import org.apache.commons.logging.Log;
8 | import org.apache.commons.logging.LogFactory;
9 | import org.postgresql.jdbc.PgConnection;
10 |
11 | import org.springframework.boot.SpringApplication;
12 | import org.springframework.boot.autoconfigure.SpringBootApplication;
13 | import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
14 | import org.springframework.boot.autoconfigure.jdbc.JdbcConnectionDetails;
15 | import org.springframework.context.annotation.Bean;
16 | import org.springframework.integration.annotation.EndpointId;
17 | import org.springframework.integration.annotation.ServiceActivator;
18 | import org.springframework.integration.dsl.IntegrationFlow;
19 | import org.springframework.integration.jdbc.channel.PostgresChannelMessageTableSubscriber;
20 | import org.springframework.integration.jdbc.channel.PostgresSubscribableChannel;
21 | import org.springframework.integration.jdbc.store.JdbcChannelMessageStore;
22 | import org.springframework.integration.jdbc.store.channel.PostgresChannelMessageStoreQueryProvider;
23 | import org.springframework.messaging.Message;
24 | import org.springframework.transaction.PlatformTransactionManager;
25 |
26 | @SpringBootApplication
27 | public class PostgresChannelObservationApplication {
28 |
29 | private static final Log LOG = LogFactory.getLog(PostgresChannelObservationApplication.class);
30 |
31 | public static void main(String[] args) {
32 | SpringApplication.run(PostgresChannelObservationApplication.class, args);
33 | }
34 |
35 | @Bean
36 | public JdbcChannelMessageStore messageStore(DataSource dataSource) {
37 | var messageStore = new JdbcChannelMessageStore(dataSource);
38 | messageStore.setChannelMessageStoreQueryProvider(new PostgresChannelMessageStoreQueryProvider());
39 | return messageStore;
40 | }
41 |
42 | @Bean
43 | public PostgresChannelMessageTableSubscriber subscriber(JdbcConnectionDetails jdbcConnectionDetails) {
44 | return new PostgresChannelMessageTableSubscriber(
45 | () -> DriverManager.getConnection(
46 | jdbcConnectionDetails.getJdbcUrl(),
47 | jdbcConnectionDetails.getUsername(),
48 | jdbcConnectionDetails.getPassword())
49 | .unwrap(PgConnection.class));
50 | }
51 |
52 | @Bean
53 | public PostgresSubscribableChannel postgresChannel(PostgresChannelMessageTableSubscriber subscriber,
54 | JdbcChannelMessageStore messageStore,
55 | PlatformTransactionManager transactionManager) {
56 |
57 | var postgresSubscribableChannel = new PostgresSubscribableChannel(messageStore, "group-id", subscriber);
58 | postgresSubscribableChannel.setTransactionManager(transactionManager);
59 | return postgresSubscribableChannel;
60 | }
61 |
62 | @ServiceActivator(inputChannel = "postgresChannel")
63 | @EndpointId("postgresHandler")
64 | void handleEvent(Message> message) {
65 | LOG.info("Event received: " + message);
66 | }
67 |
68 | }
69 |
--------------------------------------------------------------------------------
/postgres-channel-observation/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | spring.application.name=postgres-channel-observation
2 | management.tracing.sampling.probability=1
3 | logging.pattern.level=%5p [${spring.application.name:},%X{traceId:-},%X{spanId:-}]
4 | spring.integration.management.observation-patterns=postgresChannel,postgresHandler
5 | spring.integration.jdbc.initialize-schema=always
6 | spring.sql.init.mode=always
--------------------------------------------------------------------------------
/postgres-channel-observation/src/main/resources/schema.sql:
--------------------------------------------------------------------------------
1 | CREATE FUNCTION INT_CHANNEL_MESSAGE_NOTIFY_FCT()
2 | RETURNS TRIGGER AS
3 | '
4 | BEGIN
5 | PERFORM
6 | pg_notify(''int_channel_message_notify'', NEW.REGION || '' '' || NEW.GROUP_KEY);
7 | RETURN NEW;
8 | END;
9 | '
10 | LANGUAGE PLPGSQL;
11 |
12 | CREATE TRIGGER INT_CHANNEL_MESSAGE_NOTIFY_TRG
13 | AFTER INSERT
14 | ON INT_CHANNEL_MESSAGE
15 | FOR EACH ROW
16 | EXECUTE PROCEDURE INT_CHANNEL_MESSAGE_NOTIFY_FCT();
--------------------------------------------------------------------------------
/postgres-channel-observation/src/test/java/org/springframework/integration/postgreschannelobservation/PostgresChannelObservationApplicationTests.java:
--------------------------------------------------------------------------------
1 | package org.springframework.integration.postgreschannelobservation;
2 |
3 | import brave.handler.SpanHandler;
4 | import brave.test.TestSpanHandler;
5 | import io.micrometer.observation.Observation;
6 | import io.micrometer.observation.ObservationRegistry;
7 | import io.micrometer.tracing.brave.bridge.BraveFinishedSpan;
8 | import io.micrometer.tracing.exporter.FinishedSpan;
9 | import io.micrometer.tracing.test.simple.SpansAssert;
10 | import org.junit.jupiter.api.Test;
11 | import org.junit.jupiter.api.extension.ExtendWith;
12 | import org.testcontainers.containers.PostgreSQLContainer;
13 | import org.testcontainers.junit.jupiter.Container;
14 | import org.testcontainers.junit.jupiter.Testcontainers;
15 |
16 | import org.springframework.beans.factory.annotation.Autowired;
17 | import org.springframework.boot.test.autoconfigure.actuate.observability.AutoConfigureObservability;
18 | import org.springframework.boot.test.context.SpringBootTest;
19 | import org.springframework.boot.test.context.TestConfiguration;
20 | import org.springframework.boot.test.system.CapturedOutput;
21 | import org.springframework.boot.test.system.OutputCaptureExtension;
22 | import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
23 | import org.springframework.context.annotation.Bean;
24 | import org.springframework.messaging.MessageChannel;
25 | import org.springframework.messaging.support.GenericMessage;
26 |
27 | import static org.assertj.core.api.Assertions.assertThat;
28 | import static org.awaitility.Awaitility.await;
29 |
30 | @SpringBootTest
31 | @AutoConfigureObservability
32 | @ExtendWith(OutputCaptureExtension.class)
33 | class PostgresChannelObservationApplicationTests {
34 |
35 | static final TestSpanHandler SPANS = new TestSpanHandler();
36 |
37 | @Autowired
38 | ObservationRegistry observationRegistry;
39 |
40 | @Autowired
41 | MessageChannel postgresChannel;
42 |
43 | @Test
44 | void observationIsPropagatedOverPostgresSubscribableChannel(CapturedOutput output) {
45 | Observation
46 | .createNotStarted("test-parent-observation", this.observationRegistry)
47 | .lowCardinalityKeyValue("service.name", PostgresChannelObservationApplicationTests.class.getName())
48 | .observe(() -> postgresChannel.send(new GenericMessage<>("test data")));
49 |
50 | await().untilAsserted(() -> assertThat(SPANS.spans()).hasSize(3));
51 | SpansAssert.assertThat(SPANS.spans().stream().map(BraveFinishedSpan::fromBrave).toList())
52 | .haveSameTraceId();
53 |
54 | assertThat(output.getOut())
55 | .contains(SPANS.spans().stream()
56 | .map(BraveFinishedSpan::fromBrave)
57 | .map(FinishedSpan::getTraceId)
58 | .findFirst()
59 | .get());
60 | }
61 |
62 | @TestConfiguration(proxyBeanMethods = false)
63 | public static class MyTestConfiguration {
64 |
65 | @Bean
66 | @ServiceConnection(name = "postgres")
67 | public PostgreSQLContainer> postgreSQLContainer() {
68 | return new PostgreSQLContainer<>("postgres:11");
69 | }
70 |
71 | @Bean
72 | public SpanHandler testSpanHandler() {
73 | return SPANS;
74 | }
75 |
76 | }
77 |
78 | }
79 |
--------------------------------------------------------------------------------
/so-65667450/.gitignore:
--------------------------------------------------------------------------------
1 | HELP.md
2 | target/
3 | !.mvn/wrapper/maven-wrapper.jar
4 | !**/src/main/**/target/
5 | !**/src/test/**/target/
6 |
7 | ### STS ###
8 | .apt_generated
9 | .classpath
10 | .factorypath
11 | .project
12 | .settings
13 | .springBeans
14 | .sts4-cache
15 |
16 | ### IntelliJ IDEA ###
17 | .idea
18 | *.iws
19 | *.iml
20 | *.ipr
21 |
22 | ### NetBeans ###
23 | /nbproject/private/
24 | /nbbuild/
25 | /dist/
26 | /nbdist/
27 | /.nb-gradle/
28 | build/
29 | !**/src/main/**/build/
30 | !**/src/test/**/build/
31 |
32 | ### VS Code ###
33 | .vscode/
34 |
--------------------------------------------------------------------------------
/so-65667450/.mvn/wrapper/maven-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/artembilan/sandbox/df95ea33d5189ac11b6d7f6149df9f803eff514b/so-65667450/.mvn/wrapper/maven-wrapper.jar
--------------------------------------------------------------------------------
/so-65667450/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip
2 | wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar
3 |
--------------------------------------------------------------------------------
/so-65667450/README.md:
--------------------------------------------------------------------------------
1 | # Spring WebFlux with Kafka and Websockets in Kotlin
2 |
3 | See StackOverflow thread https://stackoverflow.com/questions/65667450/spring-webflux-with-kafka-and-websockets
4 |
--------------------------------------------------------------------------------
/so-65667450/src/main/kotlin/stackoverflow/so65667450/So65667450Application.kt:
--------------------------------------------------------------------------------
1 | package stackoverflow.so65667450
2 |
3 | import org.springframework.boot.autoconfigure.SpringBootApplication
4 | import org.springframework.boot.runApplication
5 | import org.springframework.context.annotation.Bean
6 | import org.springframework.kafka.annotation.KafkaListener
7 | import org.springframework.web.reactive.HandlerMapping
8 | import org.springframework.web.reactive.handler.SimpleUrlHandlerMapping
9 | import org.springframework.web.reactive.socket.WebSocketHandler
10 | import reactor.core.publisher.Sinks
11 |
12 |
13 | @SpringBootApplication
14 | class So65667450Application {
15 |
16 | val sink = Sinks.many().multicast().onBackpressureBuffer()
17 |
18 | @KafkaListener(topics = ["mytopic"], groupId = "test-consumer-group")
19 | fun receiveData(message: String) {
20 | this.sink.tryEmitNext(message)
21 | }
22 |
23 | @Bean
24 | fun handlerMapping(): HandlerMapping {
25 | val map = mapOf("/fromKafka" to
26 | WebSocketHandler { session ->
27 | session.send(this.sink.asFlux().map(session::textMessage))
28 | })
29 | return SimpleUrlHandlerMapping(map, -1)
30 | }
31 |
32 | fun main(args: Array) {
33 | runApplication(*args)
34 | }
35 |
36 | }
37 |
38 |
--------------------------------------------------------------------------------
/so-65667450/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/so-65667450/src/test/kotlin/stackoverflow/so65667450/So65667450ApplicationTests.kt:
--------------------------------------------------------------------------------
1 | package stackoverflow.so65667450
2 |
3 | import org.junit.jupiter.api.Test
4 | import org.springframework.beans.factory.annotation.Autowired
5 | import org.springframework.boot.test.context.SpringBootTest
6 | import org.springframework.boot.web.server.LocalServerPort
7 | import org.springframework.kafka.core.KafkaTemplate
8 | import org.springframework.kafka.test.context.EmbeddedKafka
9 | import org.springframework.web.reactive.socket.WebSocketMessage
10 | import org.springframework.web.reactive.socket.client.ReactorNettyWebSocketClient
11 | import reactor.core.publisher.Sinks
12 | import reactor.test.StepVerifier
13 | import java.net.URI
14 |
15 |
16 | @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
17 | @EmbeddedKafka(topics = ["mytopic"], bootstrapServersProperty = "spring.kafka.bootstrap-servers")
18 | class So65667450ApplicationTests {
19 |
20 | @Autowired
21 | lateinit var kafkaTemplate: KafkaTemplate<*, String>
22 |
23 | @LocalServerPort
24 | var port = 0
25 |
26 | val webSocketClient = ReactorNettyWebSocketClient()
27 |
28 | @Test
29 | fun contextLoads() {
30 | val testDataSink = Sinks.many().unicast().onBackpressureBuffer()
31 | val url = URI("ws://localhost:${port}/fromKafka")
32 | webSocketClient.execute(url) { session ->
33 | session.receive()
34 | .doOnNext(testDataSink::tryEmitNext)
35 | .then()
36 | }.subscribe()
37 |
38 | val stepVerifier =
39 | StepVerifier.create(
40 | testDataSink.asFlux()
41 | .map { it.payloadAsText }
42 | .doOnNext(::println))
43 | .expectNext("TEST DATA")
44 | .thenCancel()
45 | .verifyLater()
46 |
47 | this.kafkaTemplate.send("mytopic", "TEST DATA")
48 |
49 | stepVerifier.verify()
50 | }
51 |
52 | }
53 |
--------------------------------------------------------------------------------
/so-79334692/.gitattributes:
--------------------------------------------------------------------------------
1 | /gradlew text eol=lf
2 | *.bat text eol=crlf
3 | *.jar binary
4 |
--------------------------------------------------------------------------------
/so-79334692/.gitignore:
--------------------------------------------------------------------------------
1 | .gradle
2 | build/
3 | !gradle/wrapper/gradle-wrapper.jar
4 | !**/src/main/**/build/
5 | !**/src/test/**/build/
6 |
7 | ### STS ###
8 | .apt_generated
9 | .classpath
10 | .factorypath
11 | .project
12 | .settings
13 | .springBeans
14 | .sts4-cache
15 | bin/
16 | !**/src/main/**/bin/
17 | !**/src/test/**/bin/
18 |
19 | ### IntelliJ IDEA ###
20 | .idea
21 | *.iws
22 | *.iml
23 | *.ipr
24 | out/
25 | !**/src/main/**/out/
26 | !**/src/test/**/out/
27 |
28 | ### NetBeans ###
29 | /nbproject/private/
30 | /nbbuild/
31 | /dist/
32 | /nbdist/
33 | /.nb-gradle/
34 |
35 | ### VS Code ###
36 | .vscode/
37 |
--------------------------------------------------------------------------------
/so-79334692/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'java'
3 | id 'org.springframework.boot' version '3.4.1'
4 | id 'io.spring.dependency-management' version '1.1.7'
5 | }
6 |
7 | group = 'org.springframework.integration.example'
8 | version = '0.0.1-SNAPSHOT'
9 |
10 | java {
11 | toolchain {
12 | languageVersion = JavaLanguageVersion.of(17)
13 | }
14 | }
15 |
16 | repositories {
17 | mavenCentral()
18 | }
19 |
20 | dependencies {
21 | implementation 'org.springframework.boot:spring-boot-starter-integration'
22 | implementation 'org.springframework.boot:spring-boot-starter-jdbc'
23 | implementation 'org.springframework.integration:spring-integration-jdbc'
24 | implementation 'org.springframework.integration:spring-integration-sftp'
25 |
26 | runtimeOnly 'com.h2database:h2'
27 |
28 | testImplementation 'org.springframework.boot:spring-boot-starter-test'
29 | testImplementation 'org.springframework.integration:spring-integration-test'
30 |
31 | testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
32 | }
33 |
34 | tasks.named('test') {
35 | useJUnitPlatform()
36 | }
37 |
--------------------------------------------------------------------------------
/so-79334692/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/artembilan/sandbox/df95ea33d5189ac11b6d7f6149df9f803eff514b/so-79334692/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/so-79334692/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip
4 | networkTimeout=10000
5 | validateDistributionUrl=true
6 | zipStoreBase=GRADLE_USER_HOME
7 | zipStorePath=wrapper/dists
8 |
--------------------------------------------------------------------------------
/so-79334692/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 | @rem SPDX-License-Identifier: Apache-2.0
17 | @rem
18 |
19 | @if "%DEBUG%"=="" @echo off
20 | @rem ##########################################################################
21 | @rem
22 | @rem Gradle startup script for Windows
23 | @rem
24 | @rem ##########################################################################
25 |
26 | @rem Set local scope for the variables with windows NT shell
27 | if "%OS%"=="Windows_NT" setlocal
28 |
29 | set DIRNAME=%~dp0
30 | if "%DIRNAME%"=="" set DIRNAME=.
31 | @rem This is normally unused
32 | set APP_BASE_NAME=%~n0
33 | set APP_HOME=%DIRNAME%
34 |
35 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
36 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
37 |
38 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
39 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
40 |
41 | @rem Find java.exe
42 | if defined JAVA_HOME goto findJavaFromJavaHome
43 |
44 | set JAVA_EXE=java.exe
45 | %JAVA_EXE% -version >NUL 2>&1
46 | if %ERRORLEVEL% equ 0 goto execute
47 |
48 | echo. 1>&2
49 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
50 | echo. 1>&2
51 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2
52 | echo location of your Java installation. 1>&2
53 |
54 | goto fail
55 |
56 | :findJavaFromJavaHome
57 | set JAVA_HOME=%JAVA_HOME:"=%
58 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
59 |
60 | if exist "%JAVA_EXE%" goto execute
61 |
62 | echo. 1>&2
63 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
64 | echo. 1>&2
65 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2
66 | echo location of your Java installation. 1>&2
67 |
68 | goto fail
69 |
70 | :execute
71 | @rem Setup the command line
72 |
73 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
74 |
75 |
76 | @rem Execute Gradle
77 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
78 |
79 | :end
80 | @rem End local scope for the variables with windows NT shell
81 | if %ERRORLEVEL% equ 0 goto mainEnd
82 |
83 | :fail
84 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
85 | rem the _cmd.exe /c_ return code!
86 | set EXIT_CODE=%ERRORLEVEL%
87 | if %EXIT_CODE% equ 0 set EXIT_CODE=1
88 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
89 | exit /b %EXIT_CODE%
90 |
91 | :mainEnd
92 | if "%OS%"=="Windows_NT" endlocal
93 |
94 | :omega
95 |
--------------------------------------------------------------------------------
/so-79334692/settings.gradle:
--------------------------------------------------------------------------------
1 | rootProject.name = 'so-79334692'
2 |
--------------------------------------------------------------------------------
/so-79334692/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | spring.application.name=so-79334692
2 |
3 | spring.task.scheduling.pool.size=10
--------------------------------------------------------------------------------
/so-79382434/.gitattributes:
--------------------------------------------------------------------------------
1 | /gradlew text eol=lf
2 | *.bat text eol=crlf
3 | *.jar binary
4 |
--------------------------------------------------------------------------------
/so-79382434/.gitignore:
--------------------------------------------------------------------------------
1 | HELP.md
2 | .gradle
3 | build/
4 | !gradle/wrapper/gradle-wrapper.jar
5 | !**/src/main/**/build/
6 | !**/src/test/**/build/
7 |
8 | ### STS ###
9 | .apt_generated
10 | .classpath
11 | .factorypath
12 | .project
13 | .settings
14 | .springBeans
15 | .sts4-cache
16 | bin/
17 | !**/src/main/**/bin/
18 | !**/src/test/**/bin/
19 |
20 | ### IntelliJ IDEA ###
21 | .idea
22 | *.iws
23 | *.iml
24 | *.ipr
25 | out/
26 | !**/src/main/**/out/
27 | !**/src/test/**/out/
28 |
29 | ### NetBeans ###
30 | /nbproject/private/
31 | /nbbuild/
32 | /dist/
33 | /nbdist/
34 | /.nb-gradle/
35 |
36 | ### VS Code ###
37 | .vscode/
38 |
--------------------------------------------------------------------------------
/so-79382434/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'java'
3 | id 'org.springframework.boot' version '3.4.2'
4 | id 'io.spring.dependency-management' version '1.1.7'
5 | }
6 |
7 | group = 'org.springframework.cloud.stream.example'
8 | version = '0.0.1-SNAPSHOT'
9 |
10 | java {
11 | toolchain {
12 | languageVersion = JavaLanguageVersion.of(17)
13 | }
14 | }
15 |
16 | repositories {
17 | mavenCentral()
18 | }
19 |
20 | ext {
21 | set('springCloudVersion', "2024.0.0")
22 | }
23 |
24 | dependencies {
25 | implementation 'org.springframework.boot:spring-boot-starter-amqp'
26 | implementation 'org.springframework.cloud:spring-cloud-stream'
27 | implementation 'org.springframework.cloud:spring-cloud-stream-binder-rabbit'
28 |
29 | testImplementation 'org.springframework.boot:spring-boot-starter-test'
30 | testImplementation 'org.springframework.amqp:spring-rabbit-test'
31 | testImplementation 'org.springframework.cloud:spring-cloud-stream-test-binder'
32 |
33 | testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
34 | }
35 |
36 | dependencyManagement {
37 | imports {
38 | mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
39 | }
40 | }
41 |
42 | tasks.named('test') {
43 | useJUnitPlatform()
44 | }
45 |
--------------------------------------------------------------------------------
/so-79382434/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/artembilan/sandbox/df95ea33d5189ac11b6d7f6149df9f803eff514b/so-79382434/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/so-79382434/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip
4 | networkTimeout=10000
5 | validateDistributionUrl=true
6 | zipStoreBase=GRADLE_USER_HOME
7 | zipStorePath=wrapper/dists
8 |
--------------------------------------------------------------------------------
/so-79382434/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 | @rem SPDX-License-Identifier: Apache-2.0
17 | @rem
18 |
19 | @if "%DEBUG%"=="" @echo off
20 | @rem ##########################################################################
21 | @rem
22 | @rem Gradle startup script for Windows
23 | @rem
24 | @rem ##########################################################################
25 |
26 | @rem Set local scope for the variables with windows NT shell
27 | if "%OS%"=="Windows_NT" setlocal
28 |
29 | set DIRNAME=%~dp0
30 | if "%DIRNAME%"=="" set DIRNAME=.
31 | @rem This is normally unused
32 | set APP_BASE_NAME=%~n0
33 | set APP_HOME=%DIRNAME%
34 |
35 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
36 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
37 |
38 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
39 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
40 |
41 | @rem Find java.exe
42 | if defined JAVA_HOME goto findJavaFromJavaHome
43 |
44 | set JAVA_EXE=java.exe
45 | %JAVA_EXE% -version >NUL 2>&1
46 | if %ERRORLEVEL% equ 0 goto execute
47 |
48 | echo. 1>&2
49 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
50 | echo. 1>&2
51 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2
52 | echo location of your Java installation. 1>&2
53 |
54 | goto fail
55 |
56 | :findJavaFromJavaHome
57 | set JAVA_HOME=%JAVA_HOME:"=%
58 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
59 |
60 | if exist "%JAVA_EXE%" goto execute
61 |
62 | echo. 1>&2
63 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
64 | echo. 1>&2
65 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2
66 | echo location of your Java installation. 1>&2
67 |
68 | goto fail
69 |
70 | :execute
71 | @rem Setup the command line
72 |
73 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
74 |
75 |
76 | @rem Execute Gradle
77 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
78 |
79 | :end
80 | @rem End local scope for the variables with windows NT shell
81 | if %ERRORLEVEL% equ 0 goto mainEnd
82 |
83 | :fail
84 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
85 | rem the _cmd.exe /c_ return code!
86 | set EXIT_CODE=%ERRORLEVEL%
87 | if %EXIT_CODE% equ 0 set EXIT_CODE=1
88 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
89 | exit /b %EXIT_CODE%
90 |
91 | :mainEnd
92 | if "%OS%"=="Windows_NT" endlocal
93 |
94 | :omega
95 |
--------------------------------------------------------------------------------
/so-79382434/settings.gradle:
--------------------------------------------------------------------------------
1 | rootProject.name = 'so-79382434'
2 |
--------------------------------------------------------------------------------
/so-79382434/src/main/java/org/springframework/cloud/stream/example/so79382434/So79382434Application.java:
--------------------------------------------------------------------------------
1 | package org.springframework.cloud.stream.example.so79382434;
2 |
3 | import java.util.function.Consumer;
4 |
5 | import org.springframework.boot.ApplicationRunner;
6 | import org.springframework.boot.SpringApplication;
7 | import org.springframework.boot.autoconfigure.SpringBootApplication;
8 | import org.springframework.cloud.stream.function.StreamBridge;
9 | import org.springframework.context.annotation.Bean;
10 |
11 | @SpringBootApplication
12 | public class So79382434Application {
13 |
14 | public static void main(String[] args) {
15 | SpringApplication.run(So79382434Application.class, args);
16 | }
17 |
18 | @Bean
19 | ApplicationRunner init(StreamBridge streamBridge) {
20 | return args -> streamBridge.send("new-price-out", "100.00");
21 | }
22 |
23 | @Bean
24 | Consumer newPrice() {
25 | return data -> System.out.println("New price is: " + data);
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/so-79382434/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | application:
3 | name: so-79382434
4 | cloud:
5 | stream:
6 | bindings:
7 | new-price-out:
8 | destination: new-price
9 | newPrice-in-0:
10 | destination: new-price
--------------------------------------------------------------------------------
/so-79382434/src/test/java/org/springframework/cloud/stream/example/so79382434/So79382434ApplicationTests.java:
--------------------------------------------------------------------------------
1 | package org.springframework.cloud.stream.example.so79382434;
2 |
3 | import org.junit.jupiter.api.Test;
4 | import org.springframework.boot.test.context.SpringBootTest;
5 |
6 | @SpringBootTest
7 | class So79382434ApplicationTests {
8 |
9 | @Test
10 | void contextLoads() {
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/so57889424/.gitignore:
--------------------------------------------------------------------------------
1 | HELP.md
2 | target/
3 | !.mvn/wrapper/maven-wrapper.jar
4 | !**/src/main/**
5 | !**/src/test/**
6 |
7 | ### STS ###
8 | .apt_generated
9 | .classpath
10 | .factorypath
11 | .project
12 | .settings
13 | .springBeans
14 | .sts4-cache
15 |
16 | ### IntelliJ IDEA ###
17 | .idea
18 | *.iws
19 | *.iml
20 | *.ipr
21 |
22 | ### NetBeans ###
23 | /nbproject/private/
24 | /nbbuild/
25 | /dist/
26 | /nbdist/
27 | /.nb-gradle/
28 | build/
29 |
30 | ### VS Code ###
31 | .vscode/
32 |
--------------------------------------------------------------------------------
/so57889424/.mvn/wrapper/maven-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/artembilan/sandbox/df95ea33d5189ac11b6d7f6149df9f803eff514b/so57889424/.mvn/wrapper/maven-wrapper.jar
--------------------------------------------------------------------------------
/so57889424/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.0/apache-maven-3.6.0-bin.zip
2 |
--------------------------------------------------------------------------------
/so57889424/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | org.springframework.boot
7 | spring-boot-starter-parent
8 | 2.1.8.RELEASE
9 |
10 |
11 | org.springframework.kafka.so57889424
12 | so57889424
13 | 0.0.1-SNAPSHOT
14 | so57889424
15 | Demo project for Spring Kafka to reproduce so57889424
16 |
17 |
18 | 1.8
19 |
20 |
21 |
22 |
23 | org.springframework.boot
24 | spring-boot-starter
25 |
26 |
27 | org.springframework.kafka
28 | spring-kafka
29 |
30 |
31 |
32 | org.springframework.boot
33 | spring-boot-starter-test
34 | test
35 |
36 |
37 | org.springframework.kafka
38 | spring-kafka-test
39 | test
40 |
41 |
42 |
43 |
44 |
45 |
46 | org.springframework.boot
47 | spring-boot-maven-plugin
48 |
49 |
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/so57889424/src/main/java/org/springframework/kafka/so57889424/So57889424Application.java:
--------------------------------------------------------------------------------
1 | package org.springframework.kafka.so57889424;
2 |
3 | import java.util.concurrent.CountDownLatch;
4 | import java.util.concurrent.atomic.AtomicInteger;
5 |
6 | import javax.annotation.PostConstruct;
7 |
8 | import org.apache.kafka.clients.admin.NewTopic;
9 | import org.apache.kafka.clients.consumer.ConsumerRecord;
10 |
11 | import org.springframework.beans.factory.annotation.Autowired;
12 | import org.springframework.boot.SpringApplication;
13 | import org.springframework.boot.autoconfigure.SpringBootApplication;
14 | import org.springframework.context.annotation.Bean;
15 | import org.springframework.context.event.EventListener;
16 | import org.springframework.kafka.annotation.KafkaListener;
17 | import org.springframework.kafka.config.ConcurrentKafkaListenerContainerFactory;
18 | import org.springframework.kafka.event.ListenerContainerIdleEvent;
19 | import org.springframework.kafka.listener.ErrorHandler;
20 | import org.springframework.kafka.listener.SeekToCurrentErrorHandler;
21 | import org.springframework.retry.backoff.BackOffPolicy;
22 | import org.springframework.retry.backoff.ExponentialRandomBackOffPolicy;
23 | import org.springframework.retry.policy.SimpleRetryPolicy;
24 | import org.springframework.retry.support.RetryTemplate;
25 |
26 | @SpringBootApplication
27 | public class So57889424Application {
28 |
29 | public static void main(String[] args) {
30 | SpringApplication.run(So57889424Application.class, args);
31 | }
32 |
33 | public static final String SO57889424_TOPIC = "So57889424";
34 |
35 | @Autowired
36 | private ConcurrentKafkaListenerContainerFactory, ?> concurrentKafkaListenerContainerFactory;
37 |
38 | @PostConstruct
39 | public void setup() {
40 | this.concurrentKafkaListenerContainerFactory.setStatefulRetry(true);
41 | RetryTemplate retryTemplate = new RetryTemplate();
42 | retryTemplate.setBackOffPolicy(new ExponentialRandomBackOffPolicy());
43 | retryTemplate.setThrowLastExceptionOnExhausted(true);
44 | retryTemplate.setRetryPolicy(new SimpleRetryPolicy(3));
45 | this.concurrentKafkaListenerContainerFactory.setRetryTemplate(retryTemplate);
46 | }
47 |
48 | @Bean
49 | public ErrorHandler seekToCurrentErrorHandler() {
50 | SeekToCurrentErrorHandler seekToCurrentErrorHandler = new SeekToCurrentErrorHandler(3);
51 | seekToCurrentErrorHandler.setCommitRecovered(true);
52 | return seekToCurrentErrorHandler;
53 | }
54 |
55 | @Bean
56 | public AtomicInteger processCount() {
57 | return new AtomicInteger();
58 | }
59 |
60 | @KafkaListener(topics = SO57889424_TOPIC)
61 | public void process(ConsumerRecord, ?> record) {
62 | processCount().incrementAndGet();
63 | throw new RuntimeException("force to retry for: " + record);
64 | }
65 |
66 | @Bean
67 | public CountDownLatch listenerIdleLatch() {
68 | return new CountDownLatch(1);
69 | }
70 |
71 | @EventListener
72 | public void containerIdleEvenListener(ListenerContainerIdleEvent event) {
73 | listenerIdleLatch().countDown();
74 | }
75 |
76 | }
77 |
--------------------------------------------------------------------------------
/so57889424/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | spring.kafka.listener.concurrency=4
2 | spring.kafka.consumer.group-id=so57889424
3 | spring.kafka.consumer.enable-auto-commit=false
4 | spring.kafka.consumer.auto-offset-reset=earliest
5 | spring.kafka.listener.idle-event-interval=5s
6 | spring.kafka.listener.ack-mode=manual_immediate
7 |
--------------------------------------------------------------------------------
/so57889424/src/test/java/org/springframework/kafka/so57889424/So57889424ApplicationTests.java:
--------------------------------------------------------------------------------
1 | package org.springframework.kafka.so57889424;
2 |
3 | import static org.assertj.core.api.Assertions.assertThat;
4 |
5 | import java.util.concurrent.CountDownLatch;
6 | import java.util.concurrent.TimeUnit;
7 | import java.util.concurrent.atomic.AtomicInteger;
8 |
9 | import org.junit.BeforeClass;
10 | import org.junit.Test;
11 | import org.junit.runner.RunWith;
12 |
13 | import org.springframework.beans.factory.annotation.Autowired;
14 | import org.springframework.boot.test.context.SpringBootTest;
15 | import org.springframework.kafka.core.KafkaTemplate;
16 | import org.springframework.kafka.test.EmbeddedKafkaBroker;
17 | import org.springframework.kafka.test.context.EmbeddedKafka;
18 | import org.springframework.test.annotation.DirtiesContext;
19 | import org.springframework.test.context.junit4.SpringRunner;
20 |
21 | @RunWith(SpringRunner.class)
22 | @SpringBootTest
23 | @EmbeddedKafka(topics = So57889424Application.SO57889424_TOPIC, partitions = 32, controlledShutdown = true)
24 | @DirtiesContext
25 | public class So57889424ApplicationTests {
26 |
27 | static {
28 | System.setProperty(EmbeddedKafkaBroker.BROKER_LIST_PROPERTY, "spring.kafka.bootstrap-servers");
29 | }
30 |
31 | @Autowired
32 | private KafkaTemplate, String> kafkaTemplate;
33 |
34 | @Autowired
35 | private CountDownLatch listenerIdleLatch;
36 |
37 | @Autowired
38 | private AtomicInteger processCount;
39 |
40 | @Test
41 | public void testSo57889424() throws InterruptedException {
42 | for (int i = 0; i < 60; i++) {
43 | this.kafkaTemplate.send(So57889424Application.SO57889424_TOPIC, "test" + i);
44 | }
45 |
46 | this.kafkaTemplate.flush();
47 |
48 | assertThat(this.listenerIdleLatch.await(60, TimeUnit.SECONDS)).isTrue();
49 |
50 | assertThat(this.processCount.get()).isEqualTo(60 * 3);
51 | }
52 |
53 | }
54 |
--------------------------------------------------------------------------------
/spring-amqp-observation/.gitignore:
--------------------------------------------------------------------------------
1 | HELP.md
2 | .gradle
3 | build/
4 | !gradle/wrapper/gradle-wrapper.jar
5 | !**/src/main/**/build/
6 | !**/src/test/**/build/
7 |
8 | ### STS ###
9 | .apt_generated
10 | .classpath
11 | .factorypath
12 | .project
13 | .settings
14 | .springBeans
15 | .sts4-cache
16 | bin/
17 | !**/src/main/**/bin/
18 | !**/src/test/**/bin/
19 |
20 | ### IntelliJ IDEA ###
21 | .idea
22 | *.iws
23 | *.iml
24 | *.ipr
25 | out/
26 | !**/src/main/**/out/
27 | !**/src/test/**/out/
28 |
29 | ### NetBeans ###
30 | /nbproject/private/
31 | /nbbuild/
32 | /dist/
33 | /nbdist/
34 | /.nb-gradle/
35 |
36 | ### VS Code ###
37 | .vscode/
38 |
--------------------------------------------------------------------------------
/spring-amqp-observation/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'java'
3 | id 'org.springframework.boot' version '3.1.1'
4 | id 'io.spring.dependency-management' version '1.1.0'
5 | }
6 |
7 | group = 'org.springframework.amqp.sample.tracing'
8 | version = '0.0.1-SNAPSHOT'
9 |
10 | java {
11 | sourceCompatibility = '17'
12 | }
13 |
14 | repositories {
15 | mavenCentral()
16 | }
17 |
18 | dependencies {
19 | implementation 'org.springframework.boot:spring-boot-starter-actuator'
20 | implementation 'org.springframework.boot:spring-boot-starter-amqp'
21 | implementation 'org.springframework.boot:spring-boot-starter-web'
22 | implementation 'io.micrometer:micrometer-tracing-bridge-brave'
23 | implementation 'io.zipkin.reporter2:zipkin-reporter-brave'
24 |
25 | testImplementation 'org.springframework.boot:spring-boot-starter-test'
26 | testImplementation 'org.springframework.amqp:spring-rabbit-test'
27 | }
28 |
29 | tasks.named('test') {
30 | useJUnitPlatform()
31 | }
--------------------------------------------------------------------------------
/spring-amqp-observation/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/artembilan/sandbox/df95ea33d5189ac11b6d7f6149df9f803eff514b/spring-amqp-observation/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/spring-amqp-observation/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip
4 | networkTimeout=10000
5 | zipStoreBase=GRADLE_USER_HOME
6 | zipStorePath=wrapper/dists
7 |
--------------------------------------------------------------------------------
/spring-amqp-observation/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%"=="" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%"=="" set DIRNAME=.
29 | @rem This is normally unused
30 | set APP_BASE_NAME=%~n0
31 | set APP_HOME=%DIRNAME%
32 |
33 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
34 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
35 |
36 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
37 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
38 |
39 | @rem Find java.exe
40 | if defined JAVA_HOME goto findJavaFromJavaHome
41 |
42 | set JAVA_EXE=java.exe
43 | %JAVA_EXE% -version >NUL 2>&1
44 | if %ERRORLEVEL% equ 0 goto execute
45 |
46 | echo.
47 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
48 | echo.
49 | echo Please set the JAVA_HOME variable in your environment to match the
50 | echo location of your Java installation.
51 |
52 | goto fail
53 |
54 | :findJavaFromJavaHome
55 | set JAVA_HOME=%JAVA_HOME:"=%
56 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
57 |
58 | if exist "%JAVA_EXE%" goto execute
59 |
60 | echo.
61 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
62 | echo.
63 | echo Please set the JAVA_HOME variable in your environment to match the
64 | echo location of your Java installation.
65 |
66 | goto fail
67 |
68 | :execute
69 | @rem Setup the command line
70 |
71 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
72 |
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if %ERRORLEVEL% equ 0 goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | set EXIT_CODE=%ERRORLEVEL%
85 | if %EXIT_CODE% equ 0 set EXIT_CODE=1
86 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
87 | exit /b %EXIT_CODE%
88 |
89 | :mainEnd
90 | if "%OS%"=="Windows_NT" endlocal
91 |
92 | :omega
93 |
--------------------------------------------------------------------------------
/spring-amqp-observation/settings.gradle:
--------------------------------------------------------------------------------
1 | rootProject.name = 'spring-amqp-observation'
2 |
--------------------------------------------------------------------------------
/spring-amqp-observation/src/main/java/org/springframework/amqp/sample/tracing/SpringAmqpObservationApplication.java:
--------------------------------------------------------------------------------
1 | package org.springframework.amqp.sample.tracing;
2 |
3 | import io.micrometer.observation.Observation;
4 | import io.micrometer.observation.ObservationRegistry;
5 | import org.apache.commons.logging.Log;
6 | import org.apache.commons.logging.LogFactory;
7 |
8 | import org.springframework.amqp.rabbit.annotation.RabbitListener;
9 | import org.springframework.amqp.rabbit.config.ContainerCustomizer;
10 | import org.springframework.amqp.rabbit.core.RabbitTemplate;
11 | import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
12 | import org.springframework.boot.ApplicationRunner;
13 | import org.springframework.boot.SpringApplication;
14 | import org.springframework.boot.autoconfigure.SpringBootApplication;
15 | import org.springframework.boot.autoconfigure.amqp.RabbitTemplateCustomizer;
16 | import org.springframework.context.annotation.Bean;
17 |
18 | @SpringBootApplication
19 | public class SpringAmqpObservationApplication {
20 |
21 | private static final Log LOGGER = LogFactory.getLog(SpringAmqpObservationApplication.class);
22 |
23 | public static void main(String[] args) {
24 | SpringApplication.run(SpringAmqpObservationApplication.class, args);
25 | }
26 |
27 | @Bean
28 | ContainerCustomizer simpleMessageListenerContainerContainerCustomizer() {
29 | return simpleMessageListenerContainer -> simpleMessageListenerContainer.setObservationEnabled(true);
30 | }
31 |
32 | @Bean
33 | RabbitTemplateCustomizer rabbitTemplateCustomizer() {
34 | return rabbitTemplate -> rabbitTemplate.setObservationEnabled(true);
35 | }
36 |
37 | @Bean
38 | ApplicationRunner applicationRunner(RabbitTemplate rabbitTemplate, ObservationRegistry observationRegistry) {
39 | return args ->
40 | Observation
41 | .createNotStarted("amqp-test-observation", observationRegistry)
42 | .lowCardinalityKeyValue("service.name", SpringAmqpObservationApplication.class.getName())
43 | .observe(() -> {
44 | String data = "test data";
45 | LOGGER.warn("Produced data: " + data);
46 | rabbitTemplate.convertAndSend("testQueue", data);
47 | });
48 | }
49 |
50 | @RabbitListener(queues = "testQueue")
51 | void handleAmqp(String data) {
52 | LOGGER.warn("Received data: " + data);
53 | }
54 |
55 | }
56 |
--------------------------------------------------------------------------------
/spring-amqp-observation/src/test/java/org/springframework/amqp/sample/tracing/SpringAmqpObservationApplicationTests.java:
--------------------------------------------------------------------------------
1 | package org.springframework.amqp.sample.tracing;
2 |
3 | import org.junit.jupiter.api.Test;
4 |
5 | import org.springframework.boot.test.context.SpringBootTest;
6 |
7 | @SpringBootTest
8 | class SpringAmqpObservationApplicationTests {
9 |
10 | @Test
11 | void contextLoads() {
12 | }
13 |
14 | }
15 |
--------------------------------------------------------------------------------
/spring-boot-reactor-kafka-tracing/.gitignore:
--------------------------------------------------------------------------------
1 | HELP.md
2 | target/
3 | !.mvn/wrapper/maven-wrapper.jar
4 | !**/src/main/**/target/
5 | !**/src/test/**/target/
6 |
7 | ### STS ###
8 | .apt_generated
9 | .classpath
10 | .factorypath
11 | .project
12 | .settings
13 | .springBeans
14 | .sts4-cache
15 |
16 | ### IntelliJ IDEA ###
17 | .idea
18 | *.iws
19 | *.iml
20 | *.ipr
21 |
22 | ### NetBeans ###
23 | /nbproject/private/
24 | /nbbuild/
25 | /dist/
26 | /nbdist/
27 | /.nb-gradle/
28 | build/
29 | !**/src/main/**/build/
30 | !**/src/test/**/build/
31 |
32 | ### VS Code ###
33 | .vscode/
34 |
--------------------------------------------------------------------------------
/spring-boot-reactor-kafka-tracing/.mvn/wrapper/maven-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/artembilan/sandbox/df95ea33d5189ac11b6d7f6149df9f803eff514b/spring-boot-reactor-kafka-tracing/.mvn/wrapper/maven-wrapper.jar
--------------------------------------------------------------------------------
/spring-boot-reactor-kafka-tracing/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.5/apache-maven-3.9.5-bin.zip
2 | wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar
3 |
--------------------------------------------------------------------------------
/spring-boot-reactor-kafka-tracing/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | org.springframework.boot
7 | spring-boot-starter-parent
8 | 3.1.5
9 |
10 |
11 | com.example
12 | spring-boot-reactor-kafka-tracing
13 | 0.0.1-SNAPSHOT
14 | spring-boot-reactor-kafka-tracing
15 | spring-boot-reactor-kafka-tracing
16 |
17 | 17
18 |
19 |
20 |
21 | io.projectreactor.kafka
22 | reactor-kafka
23 | 1.3.22-SNAPSHOT
24 |
25 |
26 | org.springframework.boot
27 | spring-boot-starter-actuator
28 |
29 |
30 | io.micrometer
31 | micrometer-tracing-bridge-brave
32 |
33 |
34 | io.zipkin.reporter2
35 | zipkin-reporter-brave
36 |
37 |
38 | org.springframework
39 | spring-web
40 |
41 |
42 | org.springframework.kafka
43 | spring-kafka
44 |
45 |
46 |
47 | org.springframework.boot
48 | spring-boot-starter-test
49 | test
50 |
51 |
52 | org.springframework.kafka
53 | spring-kafka-test
54 | test
55 |
56 |
57 | io.projectreactor
58 | reactor-test
59 | test
60 |
61 |
62 |
63 |
64 |
65 |
66 | org.springframework.boot
67 | spring-boot-maven-plugin
68 |
69 |
70 |
71 |
72 |
73 |
74 | spring-snapshots
75 | Spring Snapshots
76 | https://repo.spring.io/snapshot
77 |
78 |
79 |
80 |
81 |
--------------------------------------------------------------------------------
/spring-boot-reactor-kafka-tracing/src/main/java/com/example/springbootreactorkafkatracing/SpringBootReactorKafkaTracingApplication.java:
--------------------------------------------------------------------------------
1 | package com.example.springbootreactorkafkatracing;
2 |
3 | import java.util.Collections;
4 | import java.util.List;
5 | import java.util.Map;
6 |
7 | import io.micrometer.observation.ObservationRegistry;
8 | import org.apache.kafka.clients.consumer.ConsumerConfig;
9 | import org.apache.kafka.clients.producer.ProducerConfig;
10 | import reactor.kafka.receiver.KafkaReceiver;
11 | import reactor.kafka.receiver.ReceiverOptions;
12 | import reactor.kafka.sender.KafkaSender;
13 | import reactor.kafka.sender.SenderOptions;
14 |
15 | import org.springframework.boot.SpringApplication;
16 | import org.springframework.boot.autoconfigure.SpringBootApplication;
17 | import org.springframework.boot.autoconfigure.kafka.KafkaProperties;
18 | import org.springframework.context.annotation.Bean;
19 | import org.springframework.util.StringUtils;
20 |
21 | @SpringBootApplication
22 | public class SpringBootReactorKafkaTracingApplication {
23 |
24 | public static final String MY_TOPIC = "test-topic";
25 |
26 | public static void main(String[] args) {
27 | SpringApplication.run(SpringBootReactorKafkaTracingApplication.class, args);
28 | }
29 |
30 | @Bean
31 | KafkaSender kafkaSender(KafkaProperties kafkaProperties, ObservationRegistry observationRegistry) {
32 | Map producerProperties = kafkaProperties.buildProducerProperties();
33 | producerProperties.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG,
34 | StringUtils.collectionToCommaDelimitedString(kafkaProperties.getBootstrapServers()));
35 | SenderOptions senderOptions = SenderOptions.create(producerProperties);
36 | return KafkaSender.create(senderOptions.withObservation(observationRegistry));
37 | }
38 |
39 | @Bean
40 | KafkaReceiver kafkaReceiver(KafkaProperties kafkaProperties) {
41 | Map consumerProperties = kafkaProperties.buildConsumerProperties();
42 | consumerProperties.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG,
43 | StringUtils.collectionToCommaDelimitedString(kafkaProperties.getBootstrapServers()));
44 | ReceiverOptions receiverOptions = ReceiverOptions.create(consumerProperties);
45 | return KafkaReceiver.create(receiverOptions.subscription(List.of(MY_TOPIC)));
46 | }
47 |
48 | }
49 |
--------------------------------------------------------------------------------
/spring-boot-reactor-kafka-tracing/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | spring.application.name=reactor-kafka-tracing
2 | management.tracing.sampling.probability=1
3 | logging.pattern.level=%5p [${spring.application.name:},%X{traceId:-},%X{spanId:-}]
4 | spring.kafka.consumer.auto-offset-reset=earliest
5 | spring.kafka.consumer.group-id=reactor-kafka-group
6 | logging.level.root=warn
--------------------------------------------------------------------------------
/spring-cloud-stream-rabbit-dlq/.gitignore:
--------------------------------------------------------------------------------
1 | HELP.md
2 | .gradle
3 | build/
4 | !gradle/wrapper/gradle-wrapper.jar
5 | !**/src/main/**/build/
6 | !**/src/test/**/build/
7 |
8 | ### STS ###
9 | .apt_generated
10 | .classpath
11 | .factorypath
12 | .project
13 | .settings
14 | .springBeans
15 | .sts4-cache
16 | bin/
17 | !**/src/main/**/bin/
18 | !**/src/test/**/bin/
19 |
20 | ### IntelliJ IDEA ###
21 | .idea
22 | *.iws
23 | *.iml
24 | *.ipr
25 | out/
26 | !**/src/main/**/out/
27 | !**/src/test/**/out/
28 |
29 | ### NetBeans ###
30 | /nbproject/private/
31 | /nbbuild/
32 | /dist/
33 | /nbdist/
34 | /.nb-gradle/
35 |
36 | ### VS Code ###
37 | .vscode/
38 |
--------------------------------------------------------------------------------
/spring-cloud-stream-rabbit-dlq/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'java'
3 | id 'org.springframework.boot' version '3.2.5'
4 | id 'io.spring.dependency-management' version '1.1.4'
5 | }
6 |
7 | group = 'org.springframework.cloud.stream'
8 | version = '0.0.1-SNAPSHOT'
9 |
10 | java {
11 | sourceCompatibility = '17'
12 | }
13 |
14 | repositories {
15 | mavenLocal()
16 | mavenCentral()
17 | maven { url 'https://repo.spring.io/snapshot' }
18 | }
19 |
20 | ext {
21 | set('springCloudVersion', "2024.0.0-SNAPSHOT")
22 | }
23 |
24 | dependencies {
25 | implementation 'org.springframework.boot:spring-boot-starter-amqp'
26 | implementation 'org.springframework.cloud:spring-cloud-stream'
27 | implementation 'org.springframework.amqp:spring-amqp:3.2.0-SNAPSHOT'
28 | implementation 'org.springframework.amqp:spring-rabbit:3.2.0-SNAPSHOT'
29 | implementation 'org.springframework.integration:spring-integration-amqp:6.4.0-SNAPSHOT'
30 | implementation 'org.springframework.cloud:spring-cloud-stream-binder-rabbit'
31 | testImplementation 'org.springframework.boot:spring-boot-starter-test'
32 | testImplementation 'org.springframework.boot:spring-boot-testcontainers'
33 | testImplementation 'org.springframework.amqp:spring-rabbit-test'
34 | testImplementation 'org.testcontainers:junit-jupiter'
35 | testImplementation 'org.testcontainers:rabbitmq'
36 | }
37 |
38 | dependencyManagement {
39 | imports {
40 | mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
41 | }
42 | }
43 |
44 | tasks.named('test') {
45 | useJUnitPlatform()
46 | }
47 |
--------------------------------------------------------------------------------
/spring-cloud-stream-rabbit-dlq/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/artembilan/sandbox/df95ea33d5189ac11b6d7f6149df9f803eff514b/spring-cloud-stream-rabbit-dlq/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/spring-cloud-stream-rabbit-dlq/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
4 | networkTimeout=10000
5 | validateDistributionUrl=true
6 | zipStoreBase=GRADLE_USER_HOME
7 | zipStorePath=wrapper/dists
8 |
--------------------------------------------------------------------------------
/spring-cloud-stream-rabbit-dlq/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%"=="" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%"=="" set DIRNAME=.
29 | @rem This is normally unused
30 | set APP_BASE_NAME=%~n0
31 | set APP_HOME=%DIRNAME%
32 |
33 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
34 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
35 |
36 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
37 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
38 |
39 | @rem Find java.exe
40 | if defined JAVA_HOME goto findJavaFromJavaHome
41 |
42 | set JAVA_EXE=java.exe
43 | %JAVA_EXE% -version >NUL 2>&1
44 | if %ERRORLEVEL% equ 0 goto execute
45 |
46 | echo. 1>&2
47 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
48 | echo. 1>&2
49 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2
50 | echo location of your Java installation. 1>&2
51 |
52 | goto fail
53 |
54 | :findJavaFromJavaHome
55 | set JAVA_HOME=%JAVA_HOME:"=%
56 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
57 |
58 | if exist "%JAVA_EXE%" goto execute
59 |
60 | echo. 1>&2
61 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
62 | echo. 1>&2
63 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2
64 | echo location of your Java installation. 1>&2
65 |
66 | goto fail
67 |
68 | :execute
69 | @rem Setup the command line
70 |
71 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
72 |
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if %ERRORLEVEL% equ 0 goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | set EXIT_CODE=%ERRORLEVEL%
85 | if %EXIT_CODE% equ 0 set EXIT_CODE=1
86 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
87 | exit /b %EXIT_CODE%
88 |
89 | :mainEnd
90 | if "%OS%"=="Windows_NT" endlocal
91 |
92 | :omega
93 |
--------------------------------------------------------------------------------
/spring-cloud-stream-rabbit-dlq/settings.gradle:
--------------------------------------------------------------------------------
1 | rootProject.name = 'spring-cloud-stream-rabbit-dlq'
2 |
--------------------------------------------------------------------------------
/spring-cloud-stream-rabbit-dlq/src/test/java/org/springframework/cloud/stream/rabbitdlq/SpringCloudStreamRabbitDlqApplicationTests.java:
--------------------------------------------------------------------------------
1 | package org.springframework.cloud.stream.rabbitdlq;
2 |
3 | import java.util.List;
4 | import java.util.Map;
5 | import java.util.concurrent.CountDownLatch;
6 | import java.util.concurrent.TimeUnit;
7 | import java.util.function.Consumer;
8 |
9 | import org.junit.jupiter.api.Test;
10 | import org.testcontainers.containers.RabbitMQContainer;
11 | import org.testcontainers.utility.DockerImageName;
12 |
13 | import org.springframework.amqp.AmqpRejectAndDontRequeueException;
14 | import org.springframework.amqp.ImmediateAcknowledgeAmqpException;
15 | import org.springframework.amqp.rabbit.core.RabbitTemplate;
16 | import org.springframework.amqp.support.AmqpHeaders;
17 | import org.springframework.beans.factory.annotation.Autowired;
18 | import org.springframework.boot.autoconfigure.SpringBootApplication;
19 | import org.springframework.boot.test.context.SpringBootTest;
20 | import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
21 | import org.springframework.context.annotation.Bean;
22 | import org.springframework.messaging.Message;
23 |
24 | import static org.assertj.core.api.Assertions.assertThat;
25 |
26 | @SpringBootTest
27 | class SpringCloudStreamRabbitDlqApplicationTests {
28 |
29 | @Test
30 | void contextLoads(@Autowired RabbitTemplate rabbitTemplate, @Autowired CountDownLatch dlqRetryExhausted)
31 | throws InterruptedException {
32 |
33 | rabbitTemplate.convertAndSend("myDestination.consumerGroup", "test data");
34 |
35 | assertThat(dlqRetryExhausted.await(10, TimeUnit.SECONDS)).isTrue();
36 | }
37 |
38 | @SpringBootApplication
39 | public static class TestSpringCloudStreamRabbitDlqApplication {
40 |
41 | @Bean
42 | @ServiceConnection
43 | RabbitMQContainer rabbitContainer() {
44 | return new RabbitMQContainer(DockerImageName.parse("rabbitmq:4"));
45 | }
46 |
47 | @Bean
48 | CountDownLatch dlqRetryExhausted() {
49 | return new CountDownLatch(1);
50 | }
51 |
52 | @Bean
53 | public Consumer> listener(CountDownLatch dlqRetryExhausted) {
54 | return message -> {
55 | Long retryCount = message.getHeaders().get(AmqpHeaders.RETRY_COUNT, Long.class);
56 | if (retryCount != null && retryCount.equals(3L)) {
57 | dlqRetryExhausted.countDown();
58 | // giving up - don't send to DLX
59 | throw new ImmediateAcknowledgeAmqpException("Failed after 4 attempts");
60 | }
61 | throw new AmqpRejectAndDontRequeueException("failed");
62 | };
63 | }
64 |
65 | }
66 |
67 | }
68 |
--------------------------------------------------------------------------------
/spring-cloud-stream-rabbit-dlq/src/test/resources/application.properties:
--------------------------------------------------------------------------------
1 | spring.application.name=spring-cloud-stream-rabbit-dlq
2 |
3 | spring.cloud.stream.function.bindings.listener-in-0=input
4 | spring.cloud.stream.bindings.input.destination=myDestination
5 | spring.cloud.stream.bindings.input.group=consumerGroup
6 | #disable binder retries
7 | spring.cloud.stream.bindings.input.consumer.max-attempts=1
8 | #dlx/dlq setup
9 | spring.cloud.stream.rabbit.bindings.input.consumer.auto-bind-dlq=true
10 | spring.cloud.stream.rabbit.bindings.input.consumer.dlq-ttl=1000
11 | spring.cloud.stream.rabbit.bindings.input.consumer.dlq-dead-letter-exchange=
12 | #spring.cloud.stream.rabbit.bindings.input.consumer.republish-to-dlq=false
--------------------------------------------------------------------------------
/spring-integration-enricher/.gitignore:
--------------------------------------------------------------------------------
1 | HELP.md
2 | target/
3 | !.mvn/wrapper/maven-wrapper.jar
4 | !**/src/main/**
5 | !**/src/test/**
6 |
7 | ### STS ###
8 | .apt_generated
9 | .classpath
10 | .factorypath
11 | .project
12 | .settings
13 | .springBeans
14 | .sts4-cache
15 |
16 | ### IntelliJ IDEA ###
17 | .idea
18 | *.iws
19 | *.iml
20 | *.ipr
21 |
22 | ### NetBeans ###
23 | /nbproject/private/
24 | /nbbuild/
25 | /dist/
26 | /nbdist/
27 | /.nb-gradle/
28 | build/
29 |
30 | ### VS Code ###
31 | .vscode/
32 |
--------------------------------------------------------------------------------
/spring-integration-enricher/.mvn/wrapper/maven-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/artembilan/sandbox/df95ea33d5189ac11b6d7f6149df9f803eff514b/spring-integration-enricher/.mvn/wrapper/maven-wrapper.jar
--------------------------------------------------------------------------------
/spring-integration-enricher/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.0/apache-maven-3.6.0-bin.zip
2 |
--------------------------------------------------------------------------------
/spring-integration-enricher/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | org.springframework.boot
7 | spring-boot-starter-parent
8 | 2.2.0.RC1
9 |
10 |
11 | org.springframework.integration.stackoverflow
12 | spring-integration-enricher
13 | 0.0.1-SNAPSHOT
14 | spring-integration-enricher
15 | Demo project for SO58205432
16 |
17 |
18 | 1.8
19 |
20 |
21 |
22 |
23 | org.springframework.boot
24 | spring-boot-starter-integration
25 |
26 |
27 | org.springframework.boot
28 | spring-boot-starter-json
29 |
30 |
31 | org.springframework.integration
32 | spring-integration-http
33 |
34 |
35 |
36 | org.springframework.boot
37 | spring-boot-starter-test
38 | test
39 |
40 |
41 | org.junit.vintage
42 | junit-vintage-engine
43 |
44 |
45 |
46 |
47 | org.springframework.integration
48 | spring-integration-test
49 | test
50 |
51 |
52 |
53 |
54 |
55 |
56 | org.springframework.boot
57 | spring-boot-maven-plugin
58 |
59 |
60 |
61 |
62 |
63 |
64 | spring-milestones
65 | Spring Milestones
66 | https://repo.spring.io/milestone
67 |
68 |
69 |
70 |
71 | spring-milestones
72 | Spring Milestones
73 | https://repo.spring.io/milestone
74 |
75 |
76 |
77 |
78 |
--------------------------------------------------------------------------------
/spring-integration-enricher/src/main/java/org/springframework/integration/stackoverflow/enricher/SpringIntegrationEnricherApplication.java:
--------------------------------------------------------------------------------
1 | package org.springframework.integration.stackoverflow.enricher;
2 |
3 | import java.util.List;
4 | import java.util.Map;
5 | import java.util.function.Function;
6 | import java.util.stream.Collectors;
7 |
8 | import org.springframework.boot.SpringApplication;
9 | import org.springframework.boot.autoconfigure.SpringBootApplication;
10 | import org.springframework.context.annotation.Bean;
11 | import org.springframework.http.HttpMethod;
12 | import org.springframework.integration.dsl.IntegrationFlow;
13 | import org.springframework.integration.dsl.IntegrationFlows;
14 | import org.springframework.integration.dsl.Transformers;
15 | import org.springframework.integration.http.dsl.Http;
16 | import org.springframework.web.client.RestTemplate;
17 |
18 | @SpringBootApplication
19 | public class SpringIntegrationEnricherApplication {
20 |
21 | public static void main(String[] args) {
22 | SpringApplication.run(SpringIntegrationEnricherApplication.class, args);
23 | }
24 |
25 | @Bean
26 | public IntegrationFlow jsonEnricherFlow(RestTemplate restTemplate) {
27 | return IntegrationFlows.from(Function.class)
28 | .transform(Transformers.fromJson(Map.class))
29 | .enrich((enricher) -> enricher
30 | .