├── stubs
+ ├── bookDeleted.groovy
+ ├── bookReturned1.groovy
+ └── bookReturned2.groovy
+diff --git a/reference/html/appendix.html b/reference/html/appendix.html index 678f863552..d6c047142e 100644 --- a/reference/html/appendix.html +++ b/reference/html/appendix.html @@ -232,6 +232,21 @@ Also, you can define your own properties.
Whether to enable Stub Runner integration with Spring Integration.
stubrunner.jms.enabled
true
Whether to enable Stub Runner integration with Spring JMS.
stubrunner.kafka.enabled
true
Whether to enable Stub Runner integration with Spring Kafka.
stubrunner.kafka.initializer.enabled
true
Whether to allow Stub Runner to take care of polling for messages instead of the KafkaStubMessages component. The latter should be used only on the producer side.
stubrunner.mappings-output-folder
Dumps the mappings of each HTTP server to the selected folder.
Spring AMQP
Spring JMS
+Spring JMS (requires embedded broker)
+Spring Kafka (requires embedded broker)
Spring Cloud Contract Stub Runner’s messaging module provides an easy way to +integrate with Spring Kafka.
+The integration assumes that you have a running instance of a embedded Kafka broker (via the spring-kafka-test dependency).
You need to have both Spring Kafka, Spring Kafka Test (to run the @EmbeddedBroker) and Spring Cloud Contract Stub Runner on the classpath. Remember to annotate your test class
+with @AutoConfigureStubRunner.
With Kafka integration, in order to poll for a single message we need to register a consumer upon Spring context startup. That may lead to a situation that, when you’re on the consumer side, Stub Runner can register an additional consumer for the same group id and topic. That could lead to a situation that only one of the components would actually poll for the message. Since on the consumer side you have both the Spring Cloud Contract Stub Runner and Spring Cloud Contract Verifier classpath, we need to be able to switch off such behaviour. That’s done automatically via the stubrunner.kafka.initializer.enabled flag, that will disable the Contact Verifier consumer registration. If your application is both the consumer and the producer of a kafka message, you might need to manually toggle that property to false in the base class of your generated tests.
Assume that the stub structure looks as follows:
+├── stubs
+ ├── bookDeleted.groovy
+ ├── bookReturned1.groovy
+ └── bookReturned2.groovy
+Further assume the following test configuration (notice the spring.kafka.bootstrap-servers pointing to the embedded broker’s IP via ${spring.embedded.kafka.brokers}):
stubrunner:
+ repository-root: stubs:classpath:/stubs/
+ ids: my:stubs
+ stubs-mode: remote
+spring:
+ kafka:
+ bootstrap-servers: ${spring.embedded.kafka.brokers}
+ producer:
+ properties:
+ "value.serializer": "org.springframework.kafka.support.serializer.JsonSerializer"
+ "spring.json.trusted.packages": "*"
+ consumer:
+ properties:
+ "value.deserializer": "org.springframework.kafka.support.serializer.JsonDeserializer"
+ "value.serializer": "org.springframework.kafka.support.serializer.JsonSerializer"
+ "spring.json.trusted.packages": "*"
+ group-id: groupId
+Now consider the following contracts (we number them 1 and 2):
+Contract.make {
+ label 'return_book_1'
+ input {
+ triggeredBy('bookReturnedTriggered()')
+ }
+ outputMessage {
+ sentTo('output')
+ body('''{ "bookName" : "foo" }''')
+ headers {
+ header('BOOK-NAME', 'foo')
+ }
+ }
+}
+Contract.make {
+ label 'return_book_2'
+ input {
+ messageFrom('input')
+ messageBody([
+ bookName: 'foo'
+ ])
+ messageHeaders {
+ header('sample', 'header')
+ }
+ }
+ outputMessage {
+ sentTo('output')
+ body([
+ bookName: 'foo'
+ ])
+ headers {
+ header('BOOK-NAME', 'foo')
+ }
+ }
+}
+To trigger a message from the return_book_1 label, we use the StubTigger interface, as follows:
stubFinder.trigger('return_book_1')
+Next, we want to listen to the output of the message sent to output:
Message receivedMessage = receiveFromOutput()
+The received message would then pass the following assertions:
+assert receivedMessage != null
+assert assertThatBodyContainsBookNameFoo(receivedMessage.getPayload())
+assert receivedMessage.getHeaders().get('BOOK-NAME') == 'foo'
+Since the route is set for you, you can send a message to the output destination.
Message message = MessageBuilder.createMessage(new BookReturned('foo'), new MessageHeaders([sample: "header",]))
+kafkaTemplate.setDefaultTopic('input')
+kafkaTemplate.send(message)
+Next, we want to listen to the output of the message sent to output, as follows:
Message receivedMessage = receiveFromOutput()
+The received message would pass the following assertions:
+assert receivedMessage != null
+assert assertThatBodyContainsBookNameFoo(receivedMessage.getPayload())
+assert receivedMessage.getHeaders().get('BOOK-NAME') == 'foo'
+Since the route is set for you, you can send a message to the output destination, as follows:
Message message = MessageBuilder.createMessage(new BookReturned('foo'), new MessageHeaders([sample: "header",]))
+kafkaTemplate.setDefaultTopic('delete')
+kafkaTemplate.send(message)
+Spring AMQP
Spring JMS
+Spring JMS (requires embedded broker)
+Spring Kafka (requires embedded broker)
Spring Cloud Contract Stub Runner’s messaging module provides an easy way to +integrate with Spring Kafka.
+The integration assumes that you have a running instance of a embedded Kafka broker (via the spring-kafka-test dependency).
You need to have both Spring Kafka, Spring Kafka Test (to run the @EmbeddedBroker) and Spring Cloud Contract Stub Runner on the classpath. Remember to annotate your test class
+with @AutoConfigureStubRunner.
With Kafka integration, in order to poll for a single message we need to register a consumer upon Spring context startup. That may lead to a situation that, when you’re on the consumer side, Stub Runner can register an additional consumer for the same group id and topic. That could lead to a situation that only one of the components would actually poll for the message. Since on the consumer side you have both the Spring Cloud Contract Stub Runner and Spring Cloud Contract Verifier classpath, we need to be able to switch off such behaviour. That’s done automatically via the stubrunner.kafka.initializer.enabled flag, that will disable the Contact Verifier consumer registration. If your application is both the consumer and the producer of a kafka message, you might need to manually toggle that property to false in the base class of your generated tests.
Assume that the stub structure looks as follows:
+├── stubs
+ ├── bookDeleted.groovy
+ ├── bookReturned1.groovy
+ └── bookReturned2.groovy
+Further assume the following test configuration (notice the spring.kafka.bootstrap-servers pointing to the embedded broker’s IP via ${spring.embedded.kafka.brokers}):
stubrunner:
+ repository-root: stubs:classpath:/stubs/
+ ids: my:stubs
+ stubs-mode: remote
+spring:
+ kafka:
+ bootstrap-servers: ${spring.embedded.kafka.brokers}
+ producer:
+ properties:
+ "value.serializer": "org.springframework.kafka.support.serializer.JsonSerializer"
+ "spring.json.trusted.packages": "*"
+ consumer:
+ properties:
+ "value.deserializer": "org.springframework.kafka.support.serializer.JsonDeserializer"
+ "value.serializer": "org.springframework.kafka.support.serializer.JsonSerializer"
+ "spring.json.trusted.packages": "*"
+ group-id: groupId
+Now consider the following contracts (we number them 1 and 2):
+Contract.make {
+ label 'return_book_1'
+ input {
+ triggeredBy('bookReturnedTriggered()')
+ }
+ outputMessage {
+ sentTo('output')
+ body('''{ "bookName" : "foo" }''')
+ headers {
+ header('BOOK-NAME', 'foo')
+ }
+ }
+}
+Contract.make {
+ label 'return_book_2'
+ input {
+ messageFrom('input')
+ messageBody([
+ bookName: 'foo'
+ ])
+ messageHeaders {
+ header('sample', 'header')
+ }
+ }
+ outputMessage {
+ sentTo('output')
+ body([
+ bookName: 'foo'
+ ])
+ headers {
+ header('BOOK-NAME', 'foo')
+ }
+ }
+}
+To trigger a message from the return_book_1 label, we use the StubTigger interface, as follows:
stubFinder.trigger('return_book_1')
+Next, we want to listen to the output of the message sent to output:
Message receivedMessage = receiveFromOutput()
+The received message would then pass the following assertions:
+assert receivedMessage != null
+assert assertThatBodyContainsBookNameFoo(receivedMessage.getPayload())
+assert receivedMessage.getHeaders().get('BOOK-NAME') == 'foo'
+Since the route is set for you, you can send a message to the output destination.
Message message = MessageBuilder.createMessage(new BookReturned('foo'), new MessageHeaders([sample: "header",]))
+kafkaTemplate.setDefaultTopic('input')
+kafkaTemplate.send(message)
+Next, we want to listen to the output of the message sent to output, as follows:
Message receivedMessage = receiveFromOutput()
+The received message would pass the following assertions:
+assert receivedMessage != null
+assert assertThatBodyContainsBookNameFoo(receivedMessage.getPayload())
+assert receivedMessage.getHeaders().get('BOOK-NAME') == 'foo'
+Since the route is set for you, you can send a message to the output destination, as follows:
Message message = MessageBuilder.createMessage(new BookReturned('foo'), new MessageHeaders([sample: "header",]))
+kafkaTemplate.setDefaultTopic('delete')
+kafkaTemplate.send(message)
+Whether to enable Stub Runner integration with Spring Integration.
stubrunner.jms.enabled
true
Whether to enable Stub Runner integration with Spring JMS.
stubrunner.kafka.enabled
true
Whether to enable Stub Runner integration with Spring Kafka.
stubrunner.kafka.initializer.enabled
true
Whether to allow Stub Runner to take care of polling for messages instead of the KafkaStubMessages component. The latter should be used only on the producer side.
stubrunner.mappings-output-folder
Dumps the mappings of each HTTP server to the selected folder.