JDK16 changes
This commit is contained in:
@@ -223,9 +223,15 @@
|
||||
<artifactId>gmavenplus-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<!-- Will run JUnit 4 -->
|
||||
<!-- Will run JUnit 5 -->
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<!-- Will run JUnit 4 -->
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-failsafe-plugin</artifactId>
|
||||
<version>${maven-failsafe-plugin.version}</version>
|
||||
<dependencies>
|
||||
<!-- let JUnit vintage engine run JUnit 3 or JUnit 4 tests -->
|
||||
<dependency>
|
||||
@@ -239,32 +245,17 @@
|
||||
<version>${junit-vintage.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<configuration>
|
||||
<junitPlatformArtifactName>
|
||||
org.junit.jupiter:junit-vintage-engine
|
||||
</junitPlatformArtifactName>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<!-- Will run JUnit 5 -->
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-failsafe-plugin</artifactId>
|
||||
<version>${maven-failsafe-plugin.version}</version>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-engine</artifactId>
|
||||
<version>${junit-jupiter.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<configuration>
|
||||
<includes>
|
||||
<include>**/*Test.*</include>
|
||||
<include>**/*Tests.*</include>
|
||||
<include>**/*Spec.*</include>
|
||||
<include>**/junit4/*Test.*</include>
|
||||
<include>**/junit4/*Tests.*</include>
|
||||
<include>**/junit4/*Spec.*</include>
|
||||
</includes>
|
||||
<reportFormat>plain</reportFormat>
|
||||
<failIfNoTests>true</failIfNoTests>
|
||||
<junitPlatformArtifactName>
|
||||
org.junit.jupiter:junit-vintage-engine
|
||||
</junitPlatformArtifactName>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.contract.stubrunner.junit
|
||||
package org.springframework.cloud.contract.stubrunner.junit4
|
||||
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
@@ -24,6 +24,7 @@ import org.junit.ClassRule
|
||||
import spock.lang.Shared
|
||||
import spock.lang.Specification
|
||||
|
||||
import org.springframework.cloud.contract.stubrunner.junit.StubRunnerRule
|
||||
import org.springframework.cloud.contract.stubrunner.spring.StubRunnerProperties
|
||||
import org.springframework.cloud.contract.verifier.converter.YamlContract
|
||||
import org.springframework.cloud.contract.verifier.messaging.MessageVerifier
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.contract.stubrunner.junit;
|
||||
package org.springframework.cloud.contract.stubrunner.junit4;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
@@ -25,6 +25,7 @@ import org.junit.BeforeClass;
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.cloud.contract.stubrunner.junit.StubRunnerRule;
|
||||
import org.springframework.cloud.contract.stubrunner.spring.StubRunnerProperties;
|
||||
import org.springframework.util.StreamUtils;
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.contract.stubrunner.junit
|
||||
package org.springframework.cloud.contract.stubrunner.junit4
|
||||
|
||||
import org.junit.AfterClass
|
||||
import org.junit.BeforeClass
|
||||
@@ -22,6 +22,7 @@ import org.junit.ClassRule
|
||||
import spock.lang.Shared
|
||||
import spock.lang.Specification
|
||||
|
||||
import org.springframework.cloud.contract.stubrunner.junit.StubRunnerRule
|
||||
import org.springframework.cloud.contract.stubrunner.spring.StubRunnerProperties
|
||||
|
||||
/**
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.contract.stubrunner.junit;
|
||||
package org.springframework.cloud.contract.stubrunner.junit4;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
@@ -25,6 +25,7 @@ import org.junit.BeforeClass;
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.cloud.contract.stubrunner.junit.StubRunnerRule;
|
||||
import org.springframework.cloud.contract.stubrunner.spring.StubRunnerProperties;
|
||||
import org.springframework.util.StreamUtils;
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.contract.stubrunner.junit
|
||||
package org.springframework.cloud.contract.stubrunner.junit4
|
||||
|
||||
import org.junit.AfterClass
|
||||
import org.junit.BeforeClass
|
||||
@@ -22,6 +22,7 @@ import org.junit.ClassRule
|
||||
import spock.lang.Shared
|
||||
import spock.lang.Specification
|
||||
|
||||
import org.springframework.cloud.contract.stubrunner.junit.StubRunnerRule
|
||||
import org.springframework.cloud.contract.stubrunner.spring.StubRunnerProperties
|
||||
|
||||
/**
|
||||
@@ -31,8 +31,7 @@ import org.springframework.test.context.ContextConfiguration
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
// tag::boot_usage[]
|
||||
@ContextConfiguration(classes = StubRunnerBoot, loader = SpringBootContextLoader)
|
||||
@SpringBootTest(properties = "spring.cloud.zookeeper.enabled=false")
|
||||
@SpringBootTest(classes = StubRunnerBoot, properties = "spring.cloud.zookeeper.enabled=false")
|
||||
@ActiveProfiles("test")
|
||||
class StubRunnerBootSpec extends Specification {
|
||||
|
||||
|
||||
@@ -20,15 +20,12 @@ import com.github.tomakehurst.wiremock.core.WireMockConfiguration
|
||||
import groovy.transform.CompileStatic
|
||||
import org.apache.commons.logging.Log
|
||||
import org.apache.commons.logging.LogFactory
|
||||
import org.junit.AfterClass
|
||||
import org.junit.BeforeClass
|
||||
import spock.lang.Issue
|
||||
import spock.lang.Specification
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import org.springframework.beans.factory.annotation.Value
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration
|
||||
import org.springframework.boot.test.context.SpringBootContextLoader
|
||||
import org.springframework.boot.test.context.SpringBootTest
|
||||
import org.springframework.cloud.contract.stubrunner.HttpServerStubConfiguration
|
||||
import org.springframework.cloud.contract.stubrunner.StubFinder
|
||||
@@ -38,7 +35,6 @@ import org.springframework.cloud.contract.stubrunner.provider.wiremock.WireMockH
|
||||
import org.springframework.context.annotation.Configuration
|
||||
import org.springframework.core.env.Environment
|
||||
import org.springframework.test.context.ActiveProfiles
|
||||
import org.springframework.test.context.ContextConfiguration
|
||||
import org.springframework.util.SocketUtils
|
||||
|
||||
/**
|
||||
@@ -47,131 +43,132 @@ import org.springframework.util.SocketUtils
|
||||
|
||||
// Not necessary if Spring Cloud is used. TODO: make it work without this.
|
||||
// tag::test[]
|
||||
@ContextConfiguration(classes = Config, loader = SpringBootContextLoader)
|
||||
@SpringBootTest(properties = [" stubrunner.cloud.enabled=false",
|
||||
'foo=${stubrunner.runningstubs.fraudDetectionServer.port}',
|
||||
'fooWithGroup=${stubrunner.runningstubs.org.springframework.cloud.contract.verifier.stubs.fraudDetectionServer.port}'])
|
||||
@SpringBootTest(classes = Config, properties = [" stubrunner.cloud.enabled=false",
|
||||
'foo=${stubrunner.runningstubs.fraudDetectionServer.port}',
|
||||
'fooWithGroup=${stubrunner.runningstubs.org.springframework.cloud.contract.verifier.stubs.fraudDetectionServer.port}'])
|
||||
// tag::annotation[]
|
||||
@AutoConfigureStubRunner(mappingsOutputFolder = "target/outputmappings/",
|
||||
httpServerStubConfigurer = HttpsForFraudDetection)
|
||||
httpServerStubConfigurer = HttpsForFraudDetection)
|
||||
// end::annotation[]
|
||||
@ActiveProfiles("test")
|
||||
class StubRunnerConfigurationSpec extends Specification {
|
||||
|
||||
@Autowired
|
||||
StubFinder stubFinder
|
||||
@Autowired
|
||||
Environment environment
|
||||
@StubRunnerPort("fraudDetectionServer")
|
||||
int fraudDetectionServerPort
|
||||
@StubRunnerPort("org.springframework.cloud.contract.verifier.stubs:fraudDetectionServer")
|
||||
int fraudDetectionServerPortWithGroupId
|
||||
@Value('${foo}')
|
||||
Integer foo
|
||||
@Autowired
|
||||
StubFinder stubFinder
|
||||
@Autowired
|
||||
Environment environment
|
||||
@StubRunnerPort("fraudDetectionServer")
|
||||
int fraudDetectionServerPort
|
||||
@StubRunnerPort("org.springframework.cloud.contract.verifier.stubs:fraudDetectionServer")
|
||||
int fraudDetectionServerPortWithGroupId
|
||||
@Value('${foo}')
|
||||
Integer foo
|
||||
|
||||
@BeforeClass
|
||||
@AfterClass
|
||||
void setupProps() {
|
||||
System.clearProperty("stubrunner.repository.root")
|
||||
System.clearProperty("stubrunner.classifier")
|
||||
WireMockHttpServerStubAccessor.clear()
|
||||
}
|
||||
void setupSpec() {
|
||||
System.clearProperty("stubrunner.repository.root")
|
||||
System.clearProperty("stubrunner.classifier")
|
||||
WireMockHttpServerStubAccessor.clear()
|
||||
}
|
||||
|
||||
def 'should mark all ports as random'() {
|
||||
expect:
|
||||
WireMockHttpServerStubAccessor.everyPortRandom()
|
||||
}
|
||||
void cleanupSpec() {
|
||||
setupSpec()
|
||||
}
|
||||
|
||||
def 'should start WireMock servers'() {
|
||||
expect: 'WireMocks are running'
|
||||
stubFinder.findStubUrl('org.springframework.cloud.contract.verifier.stubs', 'loanIssuance') != null
|
||||
stubFinder.findStubUrl('loanIssuance') != null
|
||||
stubFinder.findStubUrl('loanIssuance') == stubFinder.findStubUrl('org.springframework.cloud.contract.verifier.stubs', 'loanIssuance')
|
||||
stubFinder.findStubUrl('loanIssuance') == stubFinder.findStubUrl('org.springframework.cloud.contract.verifier.stubs:loanIssuance')
|
||||
stubFinder.findStubUrl('org.springframework.cloud.contract.verifier.stubs:loanIssuance:0.0.1-SNAPSHOT') == stubFinder.findStubUrl('org.springframework.cloud.contract.verifier.stubs:loanIssuance:0.0.1-SNAPSHOT:stubs')
|
||||
stubFinder.findStubUrl('org.springframework.cloud.contract.verifier.stubs:fraudDetectionServer') != null
|
||||
and:
|
||||
stubFinder.findAllRunningStubs().isPresent('loanIssuance')
|
||||
stubFinder.findAllRunningStubs().isPresent('org.springframework.cloud.contract.verifier.stubs', 'fraudDetectionServer')
|
||||
stubFinder.findAllRunningStubs().isPresent('org.springframework.cloud.contract.verifier.stubs:fraudDetectionServer')
|
||||
and: 'Stubs were registered'
|
||||
"${stubFinder.findStubUrl('loanIssuance').toString()}/name".toURL().text == 'loanIssuance'
|
||||
"${stubFinder.findStubUrl('fraudDetectionServer').toString()}/name".toURL().text == 'fraudDetectionServer'
|
||||
and: 'Fraud Detection is an HTTPS endpoint'
|
||||
stubFinder.findStubUrl('fraudDetectionServer').toString().startsWith("https")
|
||||
}
|
||||
def 'should mark all ports as random'() {
|
||||
expect:
|
||||
WireMockHttpServerStubAccessor.everyPortRandom()
|
||||
}
|
||||
|
||||
def 'should throw an exception when stub is not found'() {
|
||||
when:
|
||||
stubFinder.findStubUrl('nonExistingService')
|
||||
then:
|
||||
thrown(StubNotFoundException)
|
||||
when:
|
||||
stubFinder.findStubUrl('nonExistingGroupId', 'nonExistingArtifactId')
|
||||
then:
|
||||
thrown(StubNotFoundException)
|
||||
}
|
||||
def 'should start WireMock servers'() {
|
||||
expect: 'WireMocks are running'
|
||||
stubFinder.findStubUrl('org.springframework.cloud.contract.verifier.stubs', 'loanIssuance') != null
|
||||
stubFinder.findStubUrl('loanIssuance') != null
|
||||
stubFinder.findStubUrl('loanIssuance') == stubFinder.findStubUrl('org.springframework.cloud.contract.verifier.stubs', 'loanIssuance')
|
||||
stubFinder.findStubUrl('loanIssuance') == stubFinder.findStubUrl('org.springframework.cloud.contract.verifier.stubs:loanIssuance')
|
||||
stubFinder.findStubUrl('org.springframework.cloud.contract.verifier.stubs:loanIssuance:0.0.1-SNAPSHOT') == stubFinder.findStubUrl('org.springframework.cloud.contract.verifier.stubs:loanIssuance:0.0.1-SNAPSHOT:stubs')
|
||||
stubFinder.findStubUrl('org.springframework.cloud.contract.verifier.stubs:fraudDetectionServer') != null
|
||||
and:
|
||||
stubFinder.findAllRunningStubs().isPresent('loanIssuance')
|
||||
stubFinder.findAllRunningStubs().isPresent('org.springframework.cloud.contract.verifier.stubs', 'fraudDetectionServer')
|
||||
stubFinder.findAllRunningStubs().isPresent('org.springframework.cloud.contract.verifier.stubs:fraudDetectionServer')
|
||||
and: 'Stubs were registered'
|
||||
"${stubFinder.findStubUrl('loanIssuance').toString()}/name".toURL().text == 'loanIssuance'
|
||||
"${stubFinder.findStubUrl('fraudDetectionServer').toString()}/name".toURL().text == 'fraudDetectionServer'
|
||||
and: 'Fraud Detection is an HTTPS endpoint'
|
||||
stubFinder.findStubUrl('fraudDetectionServer').toString().startsWith("https")
|
||||
}
|
||||
|
||||
def 'should register started servers as environment variables'() {
|
||||
expect:
|
||||
environment.getProperty("stubrunner.runningstubs.loanIssuance.port") != null
|
||||
stubFinder.findAllRunningStubs().getPort("loanIssuance") == (environment.getProperty("stubrunner.runningstubs.loanIssuance.port") as Integer)
|
||||
and:
|
||||
environment.getProperty("stubrunner.runningstubs.fraudDetectionServer.port") != null
|
||||
stubFinder.findAllRunningStubs().getPort("fraudDetectionServer") == (environment.getProperty("stubrunner.runningstubs.fraudDetectionServer.port") as Integer)
|
||||
and:
|
||||
environment.getProperty("stubrunner.runningstubs.fraudDetectionServer.port") != null
|
||||
stubFinder.findAllRunningStubs().getPort("fraudDetectionServer") == (environment.getProperty("stubrunner.runningstubs.org.springframework.cloud.contract.verifier.stubs.fraudDetectionServer.port") as Integer)
|
||||
}
|
||||
def 'should throw an exception when stub is not found'() {
|
||||
when:
|
||||
stubFinder.findStubUrl('nonExistingService')
|
||||
then:
|
||||
thrown(StubNotFoundException)
|
||||
when:
|
||||
stubFinder.findStubUrl('nonExistingGroupId', 'nonExistingArtifactId')
|
||||
then:
|
||||
thrown(StubNotFoundException)
|
||||
}
|
||||
|
||||
def 'should be able to interpolate a running stub in the passed test property'() {
|
||||
given:
|
||||
int fraudPort = stubFinder.findAllRunningStubs().getPort("fraudDetectionServer")
|
||||
expect:
|
||||
fraudPort > 0
|
||||
environment.getProperty("foo", Integer) == fraudPort
|
||||
environment.getProperty("fooWithGroup", Integer) == fraudPort
|
||||
foo == fraudPort
|
||||
}
|
||||
def 'should register started servers as environment variables'() {
|
||||
expect:
|
||||
environment.getProperty("stubrunner.runningstubs.loanIssuance.port") != null
|
||||
stubFinder.findAllRunningStubs().getPort("loanIssuance") == (environment.getProperty("stubrunner.runningstubs.loanIssuance.port") as Integer)
|
||||
and:
|
||||
environment.getProperty("stubrunner.runningstubs.fraudDetectionServer.port") != null
|
||||
stubFinder.findAllRunningStubs().getPort("fraudDetectionServer") == (environment.getProperty("stubrunner.runningstubs.fraudDetectionServer.port") as Integer)
|
||||
and:
|
||||
environment.getProperty("stubrunner.runningstubs.fraudDetectionServer.port") != null
|
||||
stubFinder.findAllRunningStubs().getPort("fraudDetectionServer") == (environment.getProperty("stubrunner.runningstubs.org.springframework.cloud.contract.verifier.stubs.fraudDetectionServer.port") as Integer)
|
||||
}
|
||||
|
||||
@Issue("#573")
|
||||
def 'should be able to retrieve the port of a running stub via an annotation'() {
|
||||
given:
|
||||
int fraudPort = stubFinder.findAllRunningStubs().getPort("fraudDetectionServer")
|
||||
expect:
|
||||
fraudPort > 0
|
||||
fraudDetectionServerPort == fraudPort
|
||||
fraudDetectionServerPortWithGroupId == fraudPort
|
||||
}
|
||||
def 'should be able to interpolate a running stub in the passed test property'() {
|
||||
given:
|
||||
int fraudPort = stubFinder.findAllRunningStubs().getPort("fraudDetectionServer")
|
||||
expect:
|
||||
fraudPort > 0
|
||||
environment.getProperty("foo", Integer) == fraudPort
|
||||
environment.getProperty("fooWithGroup", Integer) == fraudPort
|
||||
foo == fraudPort
|
||||
}
|
||||
|
||||
def 'should dump all mappings to a file'() {
|
||||
when:
|
||||
def url = stubFinder.findStubUrl("fraudDetectionServer")
|
||||
then:
|
||||
new File("target/outputmappings/", "fraudDetectionServer_${url.port}").exists()
|
||||
}
|
||||
@Issue("#573")
|
||||
def 'should be able to retrieve the port of a running stub via an annotation'() {
|
||||
given:
|
||||
int fraudPort = stubFinder.findAllRunningStubs().getPort("fraudDetectionServer")
|
||||
expect:
|
||||
fraudPort > 0
|
||||
fraudDetectionServerPort == fraudPort
|
||||
fraudDetectionServerPortWithGroupId == fraudPort
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
static class Config {}
|
||||
def 'should dump all mappings to a file'() {
|
||||
when:
|
||||
def url = stubFinder.findStubUrl("fraudDetectionServer")
|
||||
then:
|
||||
new File("target/outputmappings/", "fraudDetectionServer_${url.port}").exists()
|
||||
}
|
||||
|
||||
// tag::wireMockHttpServerStubConfigurer[]
|
||||
@CompileStatic
|
||||
static class HttpsForFraudDetection extends WireMockHttpServerStubConfigurer {
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
static class Config {}
|
||||
|
||||
private static final Log log = LogFactory.getLog(HttpsForFraudDetection)
|
||||
// tag::wireMockHttpServerStubConfigurer[]
|
||||
@CompileStatic
|
||||
static class HttpsForFraudDetection extends WireMockHttpServerStubConfigurer {
|
||||
|
||||
@Override
|
||||
WireMockConfiguration configure(WireMockConfiguration httpStubConfiguration, HttpServerStubConfiguration httpServerStubConfiguration) {
|
||||
if (httpServerStubConfiguration.stubConfiguration.artifactId == "fraudDetectionServer") {
|
||||
int httpsPort = SocketUtils.findAvailableTcpPort()
|
||||
log.info("Will set HTTPs port [" + httpsPort + "] for fraud detection server")
|
||||
return httpStubConfiguration
|
||||
.httpsPort(httpsPort)
|
||||
}
|
||||
return httpStubConfiguration
|
||||
}
|
||||
}
|
||||
// end::wireMockHttpServerStubConfigurer[]
|
||||
private static final Log log = LogFactory.getLog(HttpsForFraudDetection)
|
||||
|
||||
@Override
|
||||
WireMockConfiguration configure(WireMockConfiguration httpStubConfiguration, HttpServerStubConfiguration httpServerStubConfiguration) {
|
||||
if (httpServerStubConfiguration.stubConfiguration.artifactId == "fraudDetectionServer") {
|
||||
int httpsPort = SocketUtils.findAvailableTcpPort()
|
||||
log.info("Will set HTTPs port [" + httpsPort + "] for fraud detection server")
|
||||
return httpStubConfiguration
|
||||
.httpsPort(httpsPort)
|
||||
}
|
||||
return httpStubConfiguration
|
||||
}
|
||||
}
|
||||
// end::wireMockHttpServerStubConfigurer[]
|
||||
}
|
||||
// end::test[]
|
||||
|
||||
@@ -16,22 +16,18 @@
|
||||
|
||||
package org.springframework.cloud.contract.stubrunner.spring
|
||||
|
||||
|
||||
import spock.lang.Specification
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration
|
||||
import org.springframework.boot.test.context.SpringBootContextLoader
|
||||
import org.springframework.boot.test.context.SpringBootTest
|
||||
import org.springframework.context.annotation.Configuration
|
||||
import org.springframework.test.context.ActiveProfiles
|
||||
import org.springframework.test.context.ContextConfiguration
|
||||
/**
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
|
||||
@ContextConfiguration(classes = Config, loader = SpringBootContextLoader)
|
||||
@SpringBootTest(properties = ['some.property1=org.springframework.cloud.contract.verifier.stubs:loanIssuance'])
|
||||
@SpringBootTest(classes = Config, properties = ['some.property1=org.springframework.cloud.contract.verifier.stubs:loanIssuance'])
|
||||
@AutoConfigureStubRunner
|
||||
@ActiveProfiles("test-with-placeholders")
|
||||
class StubRunnerOptionsBuilderSpec extends Specification {
|
||||
|
||||
@@ -16,13 +16,11 @@
|
||||
|
||||
package org.springframework.cloud.contract.stubrunner.spring.cloud
|
||||
|
||||
import org.junit.AfterClass
|
||||
import org.junit.BeforeClass
|
||||
import spock.lang.Specification
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration
|
||||
import org.springframework.boot.test.context.SpringBootContextLoader
|
||||
import org.springframework.boot.test.context.SpringBootTest
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalanced
|
||||
import org.springframework.cloud.consul.ConsulAutoConfiguration
|
||||
import org.springframework.cloud.contract.stubrunner.StubFinder
|
||||
@@ -35,62 +33,64 @@ import org.springframework.cloud.zookeeper.ZookeeperAutoConfiguration
|
||||
import org.springframework.context.annotation.Bean
|
||||
import org.springframework.context.annotation.Configuration
|
||||
import org.springframework.test.context.ActiveProfiles
|
||||
import org.springframework.test.context.ContextConfiguration
|
||||
import org.springframework.web.client.RestTemplate
|
||||
|
||||
/**
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
@ContextConfiguration(classes = Config, loader = SpringBootContextLoader)
|
||||
@SpringBootTest(classes = Config)
|
||||
@ActiveProfiles("cloudtest")
|
||||
// tag::autoconfigure[]
|
||||
@AutoConfigureStubRunner(
|
||||
ids = ["org.springframework.cloud.contract.verifier.stubs:loanIssuance",
|
||||
"org.springframework.cloud.contract.verifier.stubs:fraudDetectionServer",
|
||||
"org.springframework.cloud.contract.verifier.stubs:bootService"],
|
||||
stubsMode = StubRunnerProperties.StubsMode.REMOTE,
|
||||
repositoryRoot = "classpath:m2repo/repository/")
|
||||
ids = ["org.springframework.cloud.contract.verifier.stubs:loanIssuance",
|
||||
"org.springframework.cloud.contract.verifier.stubs:fraudDetectionServer",
|
||||
"org.springframework.cloud.contract.verifier.stubs:bootService"],
|
||||
stubsMode = StubRunnerProperties.StubsMode.REMOTE,
|
||||
repositoryRoot = "classpath:m2repo/repository/")
|
||||
// end::autoconfigure[]
|
||||
class StubRunnerSpringCloudAutoConfigurationSpec extends Specification {
|
||||
|
||||
@Autowired
|
||||
StubFinder stubFinder
|
||||
@Autowired
|
||||
@LoadBalanced
|
||||
RestTemplate restTemplate
|
||||
@Autowired
|
||||
LoadBalancerClientFactory loadBalancerClientFactory;
|
||||
@Autowired
|
||||
StubFinder stubFinder
|
||||
@Autowired
|
||||
@LoadBalanced
|
||||
RestTemplate restTemplate
|
||||
@Autowired
|
||||
LoadBalancerClientFactory loadBalancerClientFactory;
|
||||
|
||||
@BeforeClass
|
||||
@AfterClass
|
||||
static void setupProps() {
|
||||
System.clearProperty("stubrunner.repository.root")
|
||||
System.clearProperty("stubrunner.classifier")
|
||||
}
|
||||
void setupSpec() {
|
||||
System.clearProperty("stubrunner.repository.root")
|
||||
System.clearProperty("stubrunner.classifier")
|
||||
}
|
||||
|
||||
def setup() {
|
||||
assert loadBalancerClientFactory instanceof StubRunnerLoadBalancerClientFactory
|
||||
}
|
||||
void cleanupSpec() {
|
||||
setupSpec()
|
||||
}
|
||||
|
||||
// tag::test[]
|
||||
def 'should make service discovery work'() {
|
||||
expect: 'WireMocks are running'
|
||||
"${stubFinder.findStubUrl('loanIssuance').toString()}/name".toURL().text == 'loanIssuance'
|
||||
"${stubFinder.findStubUrl('fraudDetectionServer').toString()}/name".toURL().text == 'fraudDetectionServer'
|
||||
and: 'Stubs can be reached via load service discovery'
|
||||
restTemplate.getForObject('http://loanIssuance/name', String) == 'loanIssuance'
|
||||
restTemplate.getForObject('http://someNameThatShouldMapFraudDetectionServer/name', String) == 'fraudDetectionServer'
|
||||
}
|
||||
// end::test[]
|
||||
def setup() {
|
||||
assert loadBalancerClientFactory instanceof StubRunnerLoadBalancerClientFactory
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableAutoConfiguration(exclude = [EurekaClientAutoConfiguration,
|
||||
ConsulAutoConfiguration, ZookeeperAutoConfiguration])
|
||||
static class Config {
|
||||
// tag::test[]
|
||||
def 'should make service discovery work'() {
|
||||
expect: 'WireMocks are running'
|
||||
"${stubFinder.findStubUrl('loanIssuance').toString()}/name".toURL().text == 'loanIssuance'
|
||||
"${stubFinder.findStubUrl('fraudDetectionServer').toString()}/name".toURL().text == 'fraudDetectionServer'
|
||||
and: 'Stubs can be reached via load service discovery'
|
||||
restTemplate.getForObject('http://loanIssuance/name', String) == 'loanIssuance'
|
||||
restTemplate.getForObject('http://someNameThatShouldMapFraudDetectionServer/name', String) == 'fraudDetectionServer'
|
||||
}
|
||||
// end::test[]
|
||||
|
||||
@Bean
|
||||
@LoadBalanced
|
||||
RestTemplate restTemplate() {
|
||||
return new RestTemplate()
|
||||
}
|
||||
}
|
||||
@Configuration
|
||||
@EnableAutoConfiguration(exclude = [EurekaClientAutoConfiguration,
|
||||
ConsulAutoConfiguration, ZookeeperAutoConfiguration])
|
||||
static class Config {
|
||||
|
||||
@Bean
|
||||
@LoadBalanced
|
||||
RestTemplate restTemplate() {
|
||||
return new RestTemplate()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ import spock.lang.Specification
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration
|
||||
import org.springframework.boot.test.context.SpringBootContextLoader
|
||||
import org.springframework.boot.test.context.SpringBootTest
|
||||
import org.springframework.cloud.client.ServiceInstance
|
||||
import org.springframework.cloud.client.discovery.ReactiveDiscoveryClient
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalanced
|
||||
@@ -37,61 +37,61 @@ import org.springframework.cloud.zookeeper.ZookeeperAutoConfiguration
|
||||
import org.springframework.context.annotation.Bean
|
||||
import org.springframework.context.annotation.Configuration
|
||||
import org.springframework.test.context.ActiveProfiles
|
||||
import org.springframework.test.context.ContextConfiguration
|
||||
import org.springframework.web.client.RestTemplate
|
||||
|
||||
/**
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
@ContextConfiguration(classes = Config, loader = SpringBootContextLoader)
|
||||
@SpringBootTest(classes = Config)
|
||||
@ActiveProfiles("cloudtest")
|
||||
@AutoConfigureStubRunner(
|
||||
ids = ["org.springframework.cloud.contract.verifier.stubs:loanIssuance",
|
||||
"org.springframework.cloud.contract.verifier.stubs:fraudDetectionServer",
|
||||
"org.springframework.cloud.contract.verifier.stubs:bootService"],
|
||||
stubsMode = StubRunnerProperties.StubsMode.REMOTE,
|
||||
repositoryRoot = "classpath:m2repo/repository/")
|
||||
ids = ["org.springframework.cloud.contract.verifier.stubs:loanIssuance",
|
||||
"org.springframework.cloud.contract.verifier.stubs:fraudDetectionServer",
|
||||
"org.springframework.cloud.contract.verifier.stubs:bootService"],
|
||||
stubsMode = StubRunnerProperties.StubsMode.REMOTE,
|
||||
repositoryRoot = "classpath:m2repo/repository/")
|
||||
class StubRunnerSpringCloudReactiveAutoConfigurationSpec extends Specification {
|
||||
@Autowired
|
||||
StubFinder stubFinder
|
||||
@Autowired
|
||||
ReactiveDiscoveryClient reactiveDiscoveryClient;
|
||||
@Autowired
|
||||
LoadBalancerClientFactory loadBalancerClientFactory;
|
||||
RestTemplate restTemplate = new RestTemplate()
|
||||
@Autowired
|
||||
StubFinder stubFinder
|
||||
@Autowired
|
||||
ReactiveDiscoveryClient reactiveDiscoveryClient;
|
||||
@Autowired
|
||||
LoadBalancerClientFactory loadBalancerClientFactory;
|
||||
RestTemplate restTemplate = new RestTemplate()
|
||||
|
||||
@BeforeClass
|
||||
@AfterClass
|
||||
static void setupProps() {
|
||||
System.clearProperty("stubrunner.repository.root")
|
||||
System.clearProperty("stubrunner.classifier")
|
||||
}
|
||||
@BeforeClass
|
||||
@AfterClass
|
||||
static void setupProps() {
|
||||
System.clearProperty("stubrunner.repository.root")
|
||||
System.clearProperty("stubrunner.classifier")
|
||||
}
|
||||
|
||||
def setup() {
|
||||
assert loadBalancerClientFactory instanceof StubRunnerLoadBalancerClientFactory
|
||||
}
|
||||
def setup() {
|
||||
assert loadBalancerClientFactory instanceof StubRunnerLoadBalancerClientFactory
|
||||
}
|
||||
|
||||
// tag::test[]
|
||||
def 'should make service discovery work'() {
|
||||
expect: 'WireMocks are running'
|
||||
"${stubFinder.findStubUrl('loanIssuance').toString()}/name".toURL().text == 'loanIssuance'
|
||||
"${stubFinder.findStubUrl('fraudDetectionServer').toString()}/name".toURL().text == 'fraudDetectionServer'
|
||||
and: 'Stubs can be reached via load service discovery'
|
||||
ServiceInstance loanIssuance = reactiveDiscoveryClient.getInstances('loanIssuance').blockFirst()
|
||||
restTemplate.getForObject(loanIssuance.uri.toString() + '/name', String) == 'loanIssuance'
|
||||
ServiceInstance fraudDetection = reactiveDiscoveryClient.getInstances('someNameThatShouldMapFraudDetectionServer').blockFirst()
|
||||
restTemplate.getForObject(fraudDetection.uri.toString() + '/name', String)== 'fraudDetectionServer'
|
||||
}
|
||||
// end::test[]
|
||||
// tag::test[]
|
||||
def 'should make service discovery work'() {
|
||||
expect: 'WireMocks are running'
|
||||
"${stubFinder.findStubUrl('loanIssuance').toString()}/name".toURL().text == 'loanIssuance'
|
||||
"${stubFinder.findStubUrl('fraudDetectionServer').toString()}/name".toURL().text == 'fraudDetectionServer'
|
||||
and: 'Stubs can be reached via load service discovery'
|
||||
ServiceInstance loanIssuance = reactiveDiscoveryClient.getInstances('loanIssuance').blockFirst()
|
||||
restTemplate.getForObject(loanIssuance.uri.toString() + '/name', String) == 'loanIssuance'
|
||||
ServiceInstance fraudDetection = reactiveDiscoveryClient.getInstances('someNameThatShouldMapFraudDetectionServer').blockFirst()
|
||||
restTemplate.getForObject(fraudDetection.uri.toString() + '/name', String) == 'fraudDetectionServer'
|
||||
}
|
||||
// end::test[]
|
||||
|
||||
@Configuration
|
||||
@EnableAutoConfiguration(exclude = [EurekaClientAutoConfiguration,
|
||||
ConsulAutoConfiguration, ZookeeperAutoConfiguration])
|
||||
static class Config {
|
||||
@Configuration
|
||||
@EnableAutoConfiguration(exclude = [EurekaClientAutoConfiguration,
|
||||
ConsulAutoConfiguration, ZookeeperAutoConfiguration])
|
||||
static class Config {
|
||||
|
||||
@Bean
|
||||
@LoadBalanced
|
||||
RestTemplate restTemplate() {
|
||||
return new RestTemplate()
|
||||
}
|
||||
}
|
||||
@Bean
|
||||
@LoadBalanced
|
||||
RestTemplate restTemplate() {
|
||||
return new RestTemplate()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,12 +42,11 @@ import org.springframework.test.context.ContextConfiguration
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
// tag::test[]
|
||||
@ContextConfiguration(classes = Config, loader = SpringBootContextLoader)
|
||||
@SpringBootTest(properties = ["spring.application.name=bar-consumer"])
|
||||
@SpringBootTest(classes = Config, properties = ["spring.application.name=bar-consumer"])
|
||||
@AutoConfigureStubRunner(ids = "org.springframework.cloud.contract.verifier.stubs:producerWithMultipleConsumers",
|
||||
repositoryRoot = "classpath:m2repo/repository/",
|
||||
stubsMode = StubRunnerProperties.StubsMode.REMOTE,
|
||||
stubsPerConsumer = true)
|
||||
repositoryRoot = "classpath:m2repo/repository/",
|
||||
stubsMode = StubRunnerProperties.StubsMode.REMOTE,
|
||||
stubsPerConsumer = true)
|
||||
@ActiveProfiles("streamconsumer")
|
||||
class StubRunnerStubsPerConsumerSpec extends Specification {
|
||||
// end::test[]
|
||||
|
||||
@@ -23,7 +23,6 @@ import spock.lang.Specification
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration
|
||||
import org.springframework.boot.autoconfigure.ImportAutoConfiguration
|
||||
import org.springframework.boot.test.context.SpringBootContextLoader
|
||||
import org.springframework.boot.test.context.SpringBootTest
|
||||
import org.springframework.boot.test.web.client.TestRestTemplate
|
||||
import org.springframework.cloud.contract.stubrunner.StubFinder
|
||||
@@ -37,18 +36,16 @@ import org.springframework.core.env.Environment
|
||||
import org.springframework.http.ResponseEntity
|
||||
import org.springframework.messaging.Message
|
||||
import org.springframework.test.context.ActiveProfiles
|
||||
import org.springframework.test.context.ContextConfiguration
|
||||
/**
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
// tag::test[]
|
||||
@ContextConfiguration(classes = Config, loader = SpringBootContextLoader)
|
||||
@SpringBootTest
|
||||
@SpringBootTest(classes = Config)
|
||||
@AutoConfigureStubRunner(ids = "org.springframework.cloud.contract.verifier.stubs:producerWithMultipleConsumers",
|
||||
repositoryRoot = "classpath:m2repo/repository/",
|
||||
consumerName = "foo-consumer",
|
||||
stubsMode = StubRunnerProperties.StubsMode.REMOTE,
|
||||
stubsPerConsumer = true)
|
||||
repositoryRoot = "classpath:m2repo/repository/",
|
||||
consumerName = "foo-consumer",
|
||||
stubsMode = StubRunnerProperties.StubsMode.REMOTE,
|
||||
stubsPerConsumer = true)
|
||||
@ActiveProfiles("streamconsumer")
|
||||
class StubRunnerStubsPerConsumerWithConsumerNameSpec extends Specification {
|
||||
// end::test[]
|
||||
|
||||
@@ -18,8 +18,7 @@ package org.springframework.cloud.contract.stubrunner.spring.cloud.consul
|
||||
|
||||
import com.ecwid.consul.v1.ConsulClient
|
||||
import com.ecwid.consul.v1.agent.model.NewService
|
||||
import org.junit.AfterClass
|
||||
import org.junit.BeforeClass
|
||||
import groovy.transform.CompileStatic
|
||||
import org.mockito.ArgumentMatcher
|
||||
import spock.lang.Specification
|
||||
|
||||
@@ -41,8 +40,7 @@ import static org.mockito.Mockito.mock
|
||||
/**
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
@ContextConfiguration(classes = Config, loader = SpringBootContextLoader)
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
||||
@SpringBootTest(classes = Config, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
||||
properties = ["eureka.client.enabled=false",
|
||||
"spring.cloud.zookeeper.enabled=false",
|
||||
"stubrunner.cloud.stubbed.discovery.enabled=false",
|
||||
@@ -51,24 +49,25 @@ import static org.mockito.Mockito.mock
|
||||
"stubrunner.cloud.consul.enabled=true",
|
||||
"stubrunner.cloud.zookeeper.enabled=false",
|
||||
"debug=true"])
|
||||
@AutoConfigureStubRunner(ids =
|
||||
["org.springframework.cloud.contract.verifier.stubs:loanIssuance",
|
||||
"org.springframework.cloud.contract.verifier.stubs:fraudDetectionServer",
|
||||
"org.springframework.cloud.contract.verifier.stubs:bootService"],
|
||||
stubsMode = StubRunnerProperties.StubsMode.REMOTE,
|
||||
repositoryRoot = "classpath:m2repo/repository/")
|
||||
@AutoConfigureStubRunner(ids = ["org.springframework.cloud.contract.verifier.stubs:loanIssuance",
|
||||
"org.springframework.cloud.contract.verifier.stubs:fraudDetectionServer",
|
||||
"org.springframework.cloud.contract.verifier.stubs:bootService"] ,
|
||||
stubsMode = StubRunnerProperties.StubsMode.REMOTE ,
|
||||
repositoryRoot = "classpath:m2repo/repository/" )
|
||||
class StubRunnerSpringCloudConsulAutoConfigurationSpec extends Specification {
|
||||
|
||||
@Autowired
|
||||
ConsulClient client
|
||||
|
||||
@BeforeClass
|
||||
@AfterClass
|
||||
static void setupProps() {
|
||||
void setupSpec() {
|
||||
System.clearProperty("stubrunner.stubs.repository.root")
|
||||
System.clearProperty("stubrunner.stubs.classifier")
|
||||
}
|
||||
|
||||
void cleanupSpec() {
|
||||
setupSpec()
|
||||
}
|
||||
|
||||
def 'should make service discovery work for #serviceName'() {
|
||||
given:
|
||||
final String expectedId = serviceName.split(':')[0]
|
||||
@@ -97,6 +96,7 @@ class StubRunnerSpringCloudConsulAutoConfigurationSpec extends Specification {
|
||||
}
|
||||
}
|
||||
|
||||
@CompileStatic
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
@EnableDiscoveryClient
|
||||
|
||||
@@ -24,6 +24,7 @@ import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||
|
||||
import org.springframework.cloud.contract.stubrunner.junit4.StubRunnerRuleCustomPortJUnitTest;
|
||||
import org.springframework.cloud.contract.stubrunner.spring.StubRunnerProperties;
|
||||
import org.springframework.cloud.contract.verifier.converter.YamlContract;
|
||||
import org.springframework.cloud.contract.verifier.messaging.MessageVerifier;
|
||||
|
||||
@@ -21,6 +21,7 @@ import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||
|
||||
import org.springframework.cloud.contract.stubrunner.junit4.StubRunnerRuleCustomPortJUnitTest;
|
||||
import org.springframework.cloud.contract.stubrunner.spring.StubRunnerProperties;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
@@ -24,6 +24,7 @@ import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||
|
||||
import org.springframework.cloud.contract.stubrunner.junit4.StubRunnerRuleJUnitTest;
|
||||
import org.springframework.cloud.contract.stubrunner.spring.StubRunnerProperties;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@@ -24,6 +24,7 @@ import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||
|
||||
import org.springframework.cloud.contract.stubrunner.junit4.StubRunnerRuleJUnitTest;
|
||||
import org.springframework.cloud.contract.stubrunner.spring.StubRunnerProperties;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@@ -26,23 +26,20 @@ import spock.lang.Issue
|
||||
import spock.lang.Specification
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import org.springframework.boot.test.context.SpringBootContextLoader
|
||||
import org.springframework.boot.test.context.SpringBootTest
|
||||
import org.springframework.cloud.contract.spec.Contract
|
||||
import org.springframework.cloud.contract.verifier.messaging.boot.AutoConfigureMessageVerifier
|
||||
import org.springframework.cloud.contract.verifier.messaging.internal.ContractVerifierMessage
|
||||
import org.springframework.cloud.contract.verifier.messaging.internal.ContractVerifierMessaging
|
||||
import org.springframework.cloud.contract.verifier.messaging.internal.ContractVerifierObjectMapper
|
||||
import org.springframework.test.context.ContextConfiguration
|
||||
|
||||
import static com.toomuchcoding.jsonassert.JsonAssertion.assertThatJson
|
||||
import static org.assertj.core.api.Assertions.assertThat
|
||||
import static org.springframework.cloud.contract.verifier.messaging.util.ContractVerifierMessagingUtil.headers
|
||||
|
||||
// Context configuration would end up in base class
|
||||
@ContextConfiguration(classes = [AmqpMessagingApplication], loader = SpringBootContextLoader)
|
||||
@AutoConfigureMessageVerifier
|
||||
@SpringBootTest(properties = "stubrunner.amqp.enabled=true")
|
||||
@SpringBootTest(classes = AmqpMessagingApplication, properties = "stubrunner.amqp.enabled=true")
|
||||
class AmqpMessagingApplicationSpec extends Specification {
|
||||
|
||||
// ALL CASES
|
||||
|
||||
@@ -23,12 +23,12 @@ import com.jayway.jsonpath.JsonPath
|
||||
import com.toomuchcoding.jsonassert.JsonAssertion
|
||||
import org.apache.camel.Message
|
||||
import org.apache.camel.model.ModelCamelContext
|
||||
import org.junit.BeforeClass
|
||||
import spock.lang.Specification
|
||||
import spock.util.concurrent.PollingConditions
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import org.springframework.boot.test.context.SpringBootContextLoader
|
||||
import org.springframework.boot.test.context.SpringBootTest
|
||||
import org.springframework.cloud.contract.spec.Contract
|
||||
import org.springframework.cloud.contract.verifier.messaging.MessageVerifier
|
||||
import org.springframework.cloud.contract.verifier.messaging.boot.AutoConfigureMessageVerifier
|
||||
@@ -39,8 +39,8 @@ import org.springframework.test.context.ContextConfiguration
|
||||
* SPIKE ON TESTS FROM NOTES IN MessagingSpec
|
||||
*/
|
||||
// Context configuration would end up in base class
|
||||
@ContextConfiguration(classes = [CamelMessagingApplication], loader = SpringBootContextLoader)
|
||||
@AutoConfigureMessageVerifier
|
||||
@SpringBootTest(classes = CamelMessagingApplication)
|
||||
class CamelMessagingApplicationSpec extends Specification {
|
||||
|
||||
// ALL CASES
|
||||
@@ -53,8 +53,7 @@ class CamelMessagingApplicationSpec extends Specification {
|
||||
|
||||
ContractVerifierObjectMapper contractVerifierObjectMapper = new ContractVerifierObjectMapper()
|
||||
|
||||
@BeforeClass
|
||||
static void init() {
|
||||
void setupSpec() {
|
||||
System.setProperty("org.apache.activemq.SERIALIZABLE_PACKAGES", "*")
|
||||
}
|
||||
|
||||
|
||||
@@ -24,17 +24,16 @@ import com.toomuchcoding.jsonassert.JsonAssertion
|
||||
import spock.lang.Specification
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import org.springframework.boot.test.context.SpringBootContextLoader
|
||||
import org.springframework.boot.test.context.SpringBootTest
|
||||
import org.springframework.cloud.contract.spec.Contract
|
||||
import org.springframework.cloud.contract.verifier.messaging.MessageVerifier
|
||||
import org.springframework.cloud.contract.verifier.messaging.boot.AutoConfigureMessageVerifier
|
||||
import org.springframework.cloud.contract.verifier.messaging.internal.ContractVerifierObjectMapper
|
||||
import org.springframework.messaging.Message
|
||||
import org.springframework.test.context.ContextConfiguration
|
||||
|
||||
// Context configuration would end up in base class
|
||||
@ContextConfiguration(classes = [IntegrationMessagingApplication], loader = SpringBootContextLoader)
|
||||
@AutoConfigureMessageVerifier
|
||||
@SpringBootTest(classes = IntegrationMessagingApplication)
|
||||
class IntegrationMessagingApplicationSpec extends Specification {
|
||||
|
||||
// ALL CASES
|
||||
|
||||
@@ -23,12 +23,11 @@ import javax.jms.Message
|
||||
import com.jayway.jsonpath.DocumentContext
|
||||
import com.jayway.jsonpath.JsonPath
|
||||
import com.toomuchcoding.jsonassert.JsonAssertion
|
||||
import org.junit.BeforeClass
|
||||
import spock.lang.Specification
|
||||
import spock.util.concurrent.PollingConditions
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import org.springframework.boot.test.context.SpringBootContextLoader
|
||||
import org.springframework.boot.test.context.SpringBootTest
|
||||
import org.springframework.cloud.contract.spec.Contract
|
||||
import org.springframework.cloud.contract.verifier.messaging.MessageVerifier
|
||||
import org.springframework.cloud.contract.verifier.messaging.boot.AutoConfigureMessageVerifier
|
||||
@@ -38,137 +37,138 @@ import org.springframework.cloud.contract.verifier.messaging.internal.ContractVe
|
||||
import org.springframework.jms.core.JmsTemplate
|
||||
import org.springframework.jms.core.MessagePostProcessor
|
||||
import org.springframework.test.annotation.DirtiesContext
|
||||
import org.springframework.test.context.ContextConfiguration
|
||||
|
||||
/**
|
||||
* SPIKE ON TESTS FROM NOTES IN MessagingSpec
|
||||
*/
|
||||
// Context configuration would end up in base class
|
||||
@ContextConfiguration(classes = [JmsMessagingApplication], loader = SpringBootContextLoader)
|
||||
@AutoConfigureMessageVerifier
|
||||
@SpringBootTest(classes = JmsMessagingApplication)
|
||||
class JmsMessagingApplicationSpec extends Specification {
|
||||
|
||||
// ALL CASES
|
||||
@Autowired
|
||||
JmsTemplate jmsTemplate
|
||||
@Autowired
|
||||
BookDeleter bookDeleter
|
||||
@Inject MessageVerifier<Message> messageVerifier
|
||||
@Inject ContractVerifierMessaging contractVerifierMessaging
|
||||
@Inject ContractVerifierObjectMapper contractVerifierObjectMapper
|
||||
// ALL CASES
|
||||
@Autowired
|
||||
JmsTemplate jmsTemplate
|
||||
@Autowired
|
||||
BookDeleter bookDeleter
|
||||
@Inject
|
||||
MessageVerifier<Message> messageVerifier
|
||||
@Inject
|
||||
ContractVerifierMessaging contractVerifierMessaging
|
||||
@Inject
|
||||
ContractVerifierObjectMapper contractVerifierObjectMapper
|
||||
|
||||
@BeforeClass
|
||||
static void init() {
|
||||
System.setProperty("org.apache.activemq.SERIALIZABLE_PACKAGES", "*")
|
||||
System.setProperty("debug", "true")
|
||||
}
|
||||
void setupSpec() {
|
||||
System.setProperty("org.apache.activemq.SERIALIZABLE_PACKAGES", "*")
|
||||
System.setProperty("debug", "true")
|
||||
}
|
||||
|
||||
def "should work for triggered based messaging"() {
|
||||
given:
|
||||
Contract.make {
|
||||
label 'some_label'
|
||||
input {
|
||||
triggeredBy('bookReturnedTriggered()')
|
||||
}
|
||||
outputMessage {
|
||||
sentTo('output')
|
||||
body('''{ "bookName" : "foo" }''')
|
||||
headers {
|
||||
header('BOOK-NAME', 'foo')
|
||||
}
|
||||
}
|
||||
}
|
||||
// generated test should look like this:
|
||||
when:
|
||||
bookReturnedTriggered()
|
||||
then:
|
||||
ContractVerifierMessage response = contractVerifierMessaging.receive('output')
|
||||
response.getHeader('BOOK-NAME') == 'foo'
|
||||
and:
|
||||
DocumentContext parsedJson = JsonPath.
|
||||
parse(contractVerifierObjectMapper.writeValueAsString(response.getPayload()))
|
||||
JsonAssertion.assertThat(parsedJson).field('bookName').isEqualTo('foo')
|
||||
}
|
||||
def "should work for triggered based messaging"() {
|
||||
given:
|
||||
Contract.make {
|
||||
label 'some_label'
|
||||
input {
|
||||
triggeredBy('bookReturnedTriggered()')
|
||||
}
|
||||
outputMessage {
|
||||
sentTo('output')
|
||||
body('''{ "bookName" : "foo" }''')
|
||||
headers {
|
||||
header('BOOK-NAME', 'foo')
|
||||
}
|
||||
}
|
||||
}
|
||||
// generated test should look like this:
|
||||
when:
|
||||
bookReturnedTriggered()
|
||||
then:
|
||||
ContractVerifierMessage response = contractVerifierMessaging.receive('output')
|
||||
response.getHeader('BOOK-NAME') == 'foo'
|
||||
and:
|
||||
DocumentContext parsedJson = JsonPath.
|
||||
parse(contractVerifierObjectMapper.writeValueAsString(response.getPayload()))
|
||||
JsonAssertion.assertThat(parsedJson).field('bookName').isEqualTo('foo')
|
||||
}
|
||||
|
||||
@DirtiesContext
|
||||
def "should generate tests triggered by a message"() {
|
||||
given:
|
||||
Contract.make {
|
||||
label 'some_label'
|
||||
input {
|
||||
messageFrom('input2')
|
||||
messageBody([
|
||||
bookName: 'foo'
|
||||
])
|
||||
messageHeaders {
|
||||
header('sample', 'header')
|
||||
}
|
||||
}
|
||||
outputMessage {
|
||||
sentTo('output2')
|
||||
body([
|
||||
bookName: 'foo'
|
||||
])
|
||||
headers {
|
||||
header('BOOK-NAME', 'foo')
|
||||
}
|
||||
}
|
||||
}
|
||||
// generated test should look like this:
|
||||
when:
|
||||
messageVerifier.send(
|
||||
contractVerifierObjectMapper.writeValueAsString([bookName: 'foo']),
|
||||
[sample: 'header'], 'input2')
|
||||
then:
|
||||
ContractVerifierMessage response = contractVerifierMessaging.receive('output2')
|
||||
response.getHeader('BOOK-NAME') == 'foo'
|
||||
and:
|
||||
DocumentContext parsedJson = JsonPath.
|
||||
parse(contractVerifierObjectMapper.writeValueAsString(response.getPayload()))
|
||||
JsonAssertion.assertThat(parsedJson).field('bookName').isEqualTo('foo')
|
||||
}
|
||||
@DirtiesContext
|
||||
def "should generate tests triggered by a message"() {
|
||||
given:
|
||||
Contract.make {
|
||||
label 'some_label'
|
||||
input {
|
||||
messageFrom('input2')
|
||||
messageBody([
|
||||
bookName: 'foo'
|
||||
])
|
||||
messageHeaders {
|
||||
header('sample', 'header')
|
||||
}
|
||||
}
|
||||
outputMessage {
|
||||
sentTo('output2')
|
||||
body([
|
||||
bookName: 'foo'
|
||||
])
|
||||
headers {
|
||||
header('BOOK-NAME', 'foo')
|
||||
}
|
||||
}
|
||||
}
|
||||
// generated test should look like this:
|
||||
when:
|
||||
messageVerifier.send(
|
||||
contractVerifierObjectMapper.writeValueAsString([bookName: 'foo']),
|
||||
[sample: 'header'], 'input2')
|
||||
then:
|
||||
ContractVerifierMessage response = contractVerifierMessaging.receive('output2')
|
||||
response.getHeader('BOOK-NAME') == 'foo'
|
||||
and:
|
||||
DocumentContext parsedJson = JsonPath.
|
||||
parse(contractVerifierObjectMapper.writeValueAsString(response.getPayload()))
|
||||
JsonAssertion.assertThat(parsedJson).field('bookName').isEqualTo('foo')
|
||||
}
|
||||
|
||||
def "should generate tests without destination, triggered by a message"() {
|
||||
given:
|
||||
Contract.make {
|
||||
label 'some_label'
|
||||
input {
|
||||
messageFrom('delete')
|
||||
messageBody([
|
||||
bookName: 'foo'
|
||||
])
|
||||
messageHeaders {
|
||||
header('sample', 'header')
|
||||
}
|
||||
assertThat('bookWasDeleted()')
|
||||
}
|
||||
}
|
||||
// generated test should look like this:
|
||||
when:
|
||||
messageVerifier.
|
||||
send(contractVerifierObjectMapper.writeValueAsString([bookName: 'foo']),
|
||||
[sample: 'header'], 'delete')
|
||||
then:
|
||||
noExceptionThrown()
|
||||
bookWasDeleted()
|
||||
}
|
||||
def "should generate tests without destination, triggered by a message"() {
|
||||
given:
|
||||
Contract.make {
|
||||
label 'some_label'
|
||||
input {
|
||||
messageFrom('delete')
|
||||
messageBody([
|
||||
bookName: 'foo'
|
||||
])
|
||||
messageHeaders {
|
||||
header('sample', 'header')
|
||||
}
|
||||
assertThat('bookWasDeleted()')
|
||||
}
|
||||
}
|
||||
// generated test should look like this:
|
||||
when:
|
||||
messageVerifier.
|
||||
send(contractVerifierObjectMapper.writeValueAsString([bookName: 'foo']),
|
||||
[sample: 'header'], 'delete')
|
||||
then:
|
||||
noExceptionThrown()
|
||||
bookWasDeleted()
|
||||
}
|
||||
|
||||
void bookReturnedTriggered() {
|
||||
jmsTemplate.convertAndSend("output", '''{"bookName" : "foo" }''', new MessagePostProcessor() {
|
||||
@Override
|
||||
Message postProcessMessage(Message message) throws JMSException {
|
||||
message.setStringProperty("BOOK-NAME", "foo")
|
||||
return message
|
||||
}
|
||||
})
|
||||
}
|
||||
void bookReturnedTriggered() {
|
||||
jmsTemplate.convertAndSend("output", '''{"bookName" : "foo" }''', new MessagePostProcessor() {
|
||||
@Override
|
||||
Message postProcessMessage(Message message) throws JMSException {
|
||||
message.setStringProperty("BOOK-NAME", "foo")
|
||||
return message
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
PollingConditions pollingConditions = new PollingConditions()
|
||||
PollingConditions pollingConditions = new PollingConditions()
|
||||
|
||||
void bookWasDeleted() {
|
||||
pollingConditions.eventually {
|
||||
assert bookDeleter.bookSuccessfulyDeleted.get()
|
||||
}
|
||||
}
|
||||
void bookWasDeleted() {
|
||||
pollingConditions.eventually {
|
||||
assert bookDeleter.bookSuccessfulyDeleted.get()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -26,7 +26,6 @@ import spock.lang.Specification
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration
|
||||
import org.springframework.boot.autoconfigure.ImportAutoConfiguration
|
||||
import org.springframework.boot.test.context.SpringBootContextLoader
|
||||
import org.springframework.boot.test.context.SpringBootTest
|
||||
import org.springframework.cloud.contract.spec.Contract
|
||||
import org.springframework.cloud.contract.verifier.messaging.MessageVerifier
|
||||
@@ -35,134 +34,132 @@ import org.springframework.cloud.contract.verifier.messaging.internal.ContractVe
|
||||
import org.springframework.cloud.stream.binder.test.TestChannelBinderConfiguration
|
||||
import org.springframework.context.annotation.Configuration
|
||||
import org.springframework.messaging.Message
|
||||
import org.springframework.test.context.ContextConfiguration
|
||||
|
||||
/**
|
||||
* SPIKE ON TESTS FROM NOTES IN MessagingSpec
|
||||
*/
|
||||
// Context configuration would end up in base class
|
||||
@ContextConfiguration(classes = [Config, StreamMessagingApplication], loader = SpringBootContextLoader)
|
||||
@SpringBootTest(properties = "debug=true")
|
||||
@SpringBootTest(classes = [Config, StreamMessagingApplication], properties = "debug=true")
|
||||
@AutoConfigureMessageVerifier
|
||||
class StreamMessagingApplicationSpec extends Specification {
|
||||
|
||||
// ALL CASES
|
||||
@Inject
|
||||
MessageVerifier<Message<?>> contractVerifierMessaging
|
||||
ContractVerifierObjectMapper contractVerifierObjectMapper = new ContractVerifierObjectMapper()
|
||||
// ALL CASES
|
||||
@Inject
|
||||
MessageVerifier<Message<?>> contractVerifierMessaging
|
||||
ContractVerifierObjectMapper contractVerifierObjectMapper = new ContractVerifierObjectMapper()
|
||||
|
||||
def "should work for triggered based messaging"() {
|
||||
given:
|
||||
def dsl = Contract.make {
|
||||
label 'some_label'
|
||||
input {
|
||||
triggeredBy('bookReturnedTriggered()')
|
||||
}
|
||||
outputMessage {
|
||||
sentTo('bookReturned')
|
||||
body('''{ "bookName" : "foo" }''')
|
||||
headers {
|
||||
header('BOOK-NAME', 'foo')
|
||||
}
|
||||
}
|
||||
}
|
||||
// generated test should look like this:
|
||||
when:
|
||||
bookReturnedTriggered()
|
||||
then:
|
||||
def response = contractVerifierMessaging.receive('bookReturned')
|
||||
response.headers.get('BOOK-NAME') == 'foo'
|
||||
and:
|
||||
DocumentContext parsedJson = JsonPath.
|
||||
parse(contractVerifierObjectMapper.writeValueAsString(response.payload))
|
||||
JsonAssertion.assertThat(parsedJson).field('bookName').isEqualTo('foo')
|
||||
}
|
||||
def "should work for triggered based messaging"() {
|
||||
given:
|
||||
def dsl = Contract.make {
|
||||
label 'some_label'
|
||||
input {
|
||||
triggeredBy('bookReturnedTriggered()')
|
||||
}
|
||||
outputMessage {
|
||||
sentTo('bookReturned')
|
||||
body('''{ "bookName" : "foo" }''')
|
||||
headers {
|
||||
header('BOOK-NAME', 'foo')
|
||||
}
|
||||
}
|
||||
}
|
||||
// generated test should look like this:
|
||||
when:
|
||||
bookReturnedTriggered()
|
||||
then:
|
||||
def response = contractVerifierMessaging.receive('bookReturned')
|
||||
response.headers.get('BOOK-NAME') == 'foo'
|
||||
and:
|
||||
DocumentContext parsedJson = JsonPath.
|
||||
parse(contractVerifierObjectMapper.writeValueAsString(response.payload))
|
||||
JsonAssertion.assertThat(parsedJson).field('bookName').isEqualTo('foo')
|
||||
}
|
||||
|
||||
def "should generate tests triggered by a message"() {
|
||||
given:
|
||||
def dsl = Contract.make {
|
||||
label 'some_label'
|
||||
input {
|
||||
messageFrom('inputDestination')
|
||||
messageBody([
|
||||
bookName: 'foo'
|
||||
])
|
||||
messageHeaders {
|
||||
header('sample', 'header')
|
||||
}
|
||||
}
|
||||
outputMessage {
|
||||
sentTo('bookReturned')
|
||||
body([
|
||||
bookName: 'foo'
|
||||
])
|
||||
headers {
|
||||
header('BOOK-NAME', 'foo')
|
||||
}
|
||||
}
|
||||
}
|
||||
def "should generate tests triggered by a message"() {
|
||||
given:
|
||||
def dsl = Contract.make {
|
||||
label 'some_label'
|
||||
input {
|
||||
messageFrom('inputDestination')
|
||||
messageBody([
|
||||
bookName: 'foo'
|
||||
])
|
||||
messageHeaders {
|
||||
header('sample', 'header')
|
||||
}
|
||||
}
|
||||
outputMessage {
|
||||
sentTo('bookReturned')
|
||||
body([
|
||||
bookName: 'foo'
|
||||
])
|
||||
headers {
|
||||
header('BOOK-NAME', 'foo')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// generated test should look like this:
|
||||
// generated test should look like this:
|
||||
|
||||
when:
|
||||
contractVerifierMessaging.send(
|
||||
contractVerifierObjectMapper.writeValueAsString([bookName: 'foo']),
|
||||
[sample: 'header'], 'inputDestination')
|
||||
then:
|
||||
def response = contractVerifierMessaging.receive('bookReturned')
|
||||
response.headers.get('BOOK-NAME') == 'foo'
|
||||
and:
|
||||
DocumentContext parsedJson = JsonPath.
|
||||
parse(contractVerifierObjectMapper.writeValueAsString(response.payload))
|
||||
JsonAssertion.assertThat(parsedJson).field('bookName').isEqualTo('foo')
|
||||
}
|
||||
when:
|
||||
contractVerifierMessaging.send(
|
||||
contractVerifierObjectMapper.writeValueAsString([bookName: 'foo']),
|
||||
[sample: 'header'], 'inputDestination')
|
||||
then:
|
||||
def response = contractVerifierMessaging.receive('bookReturned')
|
||||
response.headers.get('BOOK-NAME') == 'foo'
|
||||
and:
|
||||
DocumentContext parsedJson = JsonPath.
|
||||
parse(contractVerifierObjectMapper.writeValueAsString(response.payload))
|
||||
JsonAssertion.assertThat(parsedJson).field('bookName').isEqualTo('foo')
|
||||
}
|
||||
|
||||
def "should generate tests without destination, triggered by a message"() {
|
||||
given:
|
||||
def dsl = Contract.make {
|
||||
label 'some_label'
|
||||
input {
|
||||
messageFrom("bookDeleted")
|
||||
messageBody([
|
||||
bookName: 'foo'
|
||||
])
|
||||
messageHeaders {
|
||||
header('sample', 'header')
|
||||
}
|
||||
assertThat('bookWasDeleted()')
|
||||
}
|
||||
}
|
||||
def "should generate tests without destination, triggered by a message"() {
|
||||
given:
|
||||
def dsl = Contract.make {
|
||||
label 'some_label'
|
||||
input {
|
||||
messageFrom("bookDeleted")
|
||||
messageBody([
|
||||
bookName: 'foo'
|
||||
])
|
||||
messageHeaders {
|
||||
header('sample', 'header')
|
||||
}
|
||||
assertThat('bookWasDeleted()')
|
||||
}
|
||||
}
|
||||
|
||||
// generated test should look like this:
|
||||
// generated test should look like this:
|
||||
|
||||
when:
|
||||
contractVerifierMessaging.
|
||||
send(contractVerifierObjectMapper.writeValueAsString([bookName: 'foo']),
|
||||
[sample: 'header'], "bookDeleted")
|
||||
then:
|
||||
noExceptionThrown()
|
||||
bookWasDeleted()
|
||||
}
|
||||
when:
|
||||
contractVerifierMessaging.
|
||||
send(contractVerifierObjectMapper.writeValueAsString([bookName: 'foo']),
|
||||
[sample: 'header'], "bookDeleted")
|
||||
then:
|
||||
noExceptionThrown()
|
||||
bookWasDeleted()
|
||||
}
|
||||
|
||||
// BASE CLASS WOULD HAVE THIS:
|
||||
// BASE CLASS WOULD HAVE THIS:
|
||||
|
||||
@Autowired
|
||||
BookService bookService
|
||||
@Autowired
|
||||
BookDeletedListener bookDeletedListener
|
||||
@Autowired
|
||||
BookService bookService
|
||||
@Autowired
|
||||
BookDeletedListener bookDeletedListener
|
||||
|
||||
void bookReturnedTriggered() {
|
||||
bookService.returnBook(new BookReturned("foo"))
|
||||
}
|
||||
void bookReturnedTriggered() {
|
||||
bookService.returnBook(new BookReturned("foo"))
|
||||
}
|
||||
|
||||
void bookWasDeleted() {
|
||||
assert bookDeletedListener.bookSuccessfulyDeleted.get()
|
||||
}
|
||||
void bookWasDeleted() {
|
||||
assert bookDeletedListener.bookSuccessfulyDeleted.get()
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
@ImportAutoConfiguration(TestChannelBinderConfiguration)
|
||||
static class Config {
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
@ImportAutoConfiguration(TestChannelBinderConfiguration)
|
||||
static class Config {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,14 +21,13 @@ import org.mockito.Captor
|
||||
import spock.lang.Specification
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import org.springframework.boot.test.context.SpringBootContextLoader
|
||||
import org.springframework.boot.test.context.SpringBootTest
|
||||
import org.springframework.cloud.contract.stubrunner.StubTrigger
|
||||
import org.springframework.cloud.contract.stubrunner.spring.AutoConfigureStubRunner
|
||||
import org.springframework.test.context.ActiveProfiles
|
||||
import org.springframework.test.context.ContextConfiguration
|
||||
|
||||
@ContextConfiguration(classes = [AmqpMessagingApplication], loader = SpringBootContextLoader)
|
||||
@AutoConfigureStubRunner
|
||||
@SpringBootTest(classes = AmqpMessagingApplication)
|
||||
@ActiveProfiles("listener")
|
||||
class AmqpStubRunnerRabbitListenerSpec extends Specification {
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ import spock.lang.Specification
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import org.springframework.boot.test.context.SpringBootContextLoader
|
||||
import org.springframework.boot.test.context.SpringBootTest
|
||||
import org.springframework.boot.test.mock.mockito.SpyBean
|
||||
import org.springframework.cloud.contract.spec.Contract
|
||||
import org.springframework.cloud.contract.stubrunner.StubTrigger
|
||||
@@ -30,8 +31,8 @@ import org.springframework.test.context.ContextConfiguration
|
||||
|
||||
import static org.mockito.BDDMockito.then
|
||||
|
||||
@ContextConfiguration(classes = [AmqpMessagingApplication], loader = SpringBootContextLoader)
|
||||
@AutoConfigureStubRunner
|
||||
@SpringBootTest(classes = AmqpMessagingApplication)
|
||||
class AmqpStubRunnerSpec extends Specification {
|
||||
|
||||
@Autowired
|
||||
|
||||
@@ -55,20 +55,19 @@ import org.springframework.web.client.RestTemplate
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
//TODO: Speed up this test somehow (move it out of Spring Cloud Contract core to samples)
|
||||
@ContextConfiguration(classes = Config, loader = SpringBootContextLoader)
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
||||
properties = ["stubrunner.cloud.eureka.enabled=true",
|
||||
"stubrunner.cloud.stubbed.discovery.enabled=false",
|
||||
"stubrunner.cloud.ribbon.enabled=false",
|
||||
"eureka.client.enabled=true",
|
||||
"eureka.instance.leaseRenewalIntervalInSeconds=1",
|
||||
"ribbon.ServerListRefreshInterval=100"])
|
||||
@SpringBootTest(classes = Config, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
||||
properties = ["stubrunner.cloud.eureka.enabled=true",
|
||||
"stubrunner.cloud.stubbed.discovery.enabled=false",
|
||||
"stubrunner.cloud.ribbon.enabled=false",
|
||||
"eureka.client.enabled=true",
|
||||
"eureka.instance.leaseRenewalIntervalInSeconds=1",
|
||||
"ribbon.ServerListRefreshInterval=100"])
|
||||
@AutoConfigureStubRunner(ids =
|
||||
["org.springframework.cloud.contract.verifier.stubs:loanIssuance",
|
||||
"org.springframework.cloud.contract.verifier.stubs:fraudDetectionServer",
|
||||
"org.springframework.cloud.contract.verifier.stubs:bootService"],
|
||||
repositoryRoot = "classpath:m2repo/repository/",
|
||||
stubsMode = StubRunnerProperties.StubsMode.REMOTE)
|
||||
["org.springframework.cloud.contract.verifier.stubs:loanIssuance",
|
||||
"org.springframework.cloud.contract.verifier.stubs:fraudDetectionServer",
|
||||
"org.springframework.cloud.contract.verifier.stubs:bootService"] ,
|
||||
repositoryRoot = "classpath:m2repo/repository/" ,
|
||||
stubsMode = StubRunnerProperties.StubsMode.REMOTE )
|
||||
class StubRunnerSpringCloudEurekaAutoConfigurationSpec extends Specification {
|
||||
|
||||
@Autowired
|
||||
|
||||
@@ -17,14 +17,11 @@
|
||||
package org.springframework.cloud.contract.stubrunner.spring.cloud.zookeeper
|
||||
|
||||
import org.apache.curator.test.TestingServer
|
||||
import org.junit.AfterClass
|
||||
import org.junit.BeforeClass
|
||||
import spock.lang.Ignore
|
||||
import spock.lang.Specification
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration
|
||||
import org.springframework.boot.test.context.SpringBootContextLoader
|
||||
import org.springframework.boot.test.context.SpringBootTest
|
||||
import org.springframework.cloud.client.discovery.EnableDiscoveryClient
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalanced
|
||||
@@ -35,23 +32,21 @@ import org.springframework.cloud.zookeeper.ZookeeperProperties
|
||||
import org.springframework.cloud.zookeeper.discovery.ZookeeperDiscoveryClient
|
||||
import org.springframework.context.annotation.Bean
|
||||
import org.springframework.context.annotation.Configuration
|
||||
import org.springframework.test.context.ContextConfiguration
|
||||
import org.springframework.util.SocketUtils
|
||||
import org.springframework.web.client.RestTemplate
|
||||
|
||||
/**
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
@ContextConfiguration(classes = Config, loader = SpringBootContextLoader)
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
||||
properties = ["stubrunner.cloud.stubbed.discovery.enabled=false",
|
||||
"debug=true"])
|
||||
@SpringBootTest(classes = Config, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
||||
properties = ["stubrunner.cloud.stubbed.discovery.enabled=false",
|
||||
"debug=true"])
|
||||
@AutoConfigureStubRunner(ids =
|
||||
["org.springframework.cloud.contract.verifier.stubs:loanIssuance",
|
||||
"org.springframework.cloud.contract.verifier.stubs:fraudDetectionServer",
|
||||
"org.springframework.cloud.contract.verifier.stubs:bootService"],
|
||||
repositoryRoot = "classpath:m2repo/repository/",
|
||||
stubsMode = StubRunnerProperties.StubsMode.REMOTE)
|
||||
["org.springframework.cloud.contract.verifier.stubs:loanIssuance",
|
||||
"org.springframework.cloud.contract.verifier.stubs:fraudDetectionServer",
|
||||
"org.springframework.cloud.contract.verifier.stubs:bootService"] ,
|
||||
repositoryRoot = "classpath:m2repo/repository/" ,
|
||||
stubsMode = StubRunnerProperties.StubsMode.REMOTE )
|
||||
class StubRunnerSpringCloudZookeeperAutoConfigurationSpec extends Specification {
|
||||
|
||||
@Autowired
|
||||
@@ -62,13 +57,15 @@ class StubRunnerSpringCloudZookeeperAutoConfigurationSpec extends Specification
|
||||
@Autowired
|
||||
ZookeeperDiscoveryClient zookeeperServiceDiscovery
|
||||
|
||||
@BeforeClass
|
||||
@AfterClass
|
||||
static void setupProps() {
|
||||
void setupSpec() {
|
||||
System.clearProperty("stubrunner.stubs.repository.root")
|
||||
System.clearProperty("stubrunner.stubs.classifier")
|
||||
}
|
||||
|
||||
void cleanupSpec() {
|
||||
setupSpec()
|
||||
}
|
||||
|
||||
@Ignore
|
||||
def 'should make service discovery work'() {
|
||||
expect: 'WireMocks are running'
|
||||
|
||||
@@ -1,283 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.contract.stubrunner.messaging.camel
|
||||
|
||||
import groovy.json.JsonOutput
|
||||
import groovy.json.JsonSlurper
|
||||
import org.apache.activemq.spring.ActiveMQConnectionFactory
|
||||
import org.apache.camel.CamelContext
|
||||
import org.apache.camel.ConsumerTemplate
|
||||
import org.apache.camel.Exchange
|
||||
import org.apache.camel.ProducerTemplate
|
||||
import org.apache.camel.component.activemq.ActiveMQComponent
|
||||
import org.apache.camel.component.jms.JmsConfiguration
|
||||
import org.apache.camel.impl.engine.DefaultShutdownStrategy
|
||||
import spock.lang.Ignore
|
||||
import spock.lang.Specification
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import org.springframework.beans.factory.annotation.Value
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration
|
||||
import org.springframework.boot.test.context.SpringBootContextLoader
|
||||
import org.springframework.boot.test.context.SpringBootTest
|
||||
import org.springframework.cloud.contract.spec.Contract
|
||||
import org.springframework.cloud.contract.stubrunner.StubFinder
|
||||
import org.springframework.cloud.contract.stubrunner.spring.AutoConfigureStubRunner
|
||||
import org.springframework.context.annotation.Bean
|
||||
import org.springframework.context.annotation.ComponentScan
|
||||
import org.springframework.context.annotation.Configuration
|
||||
import org.springframework.test.annotation.DirtiesContext
|
||||
import org.springframework.test.context.ContextConfiguration
|
||||
|
||||
/**
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
@ContextConfiguration(classes = Config, loader = SpringBootContextLoader)
|
||||
@SpringBootTest(properties = "debug=true")
|
||||
@AutoConfigureStubRunner
|
||||
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
|
||||
@Ignore
|
||||
class CamelStubRunnerSpec extends Specification {
|
||||
|
||||
//TODO: fix extremely slow test that causes pipeline to fail and then unignore
|
||||
|
||||
@Autowired
|
||||
StubFinder stubFinder
|
||||
@Autowired
|
||||
CamelContext camelContext
|
||||
ConsumerTemplate consumerTemplate
|
||||
ProducerTemplate producerTemplate
|
||||
|
||||
def setup() {
|
||||
consumerTemplate = camelContext.createConsumerTemplate()
|
||||
producerTemplate = camelContext.createProducerTemplate()
|
||||
}
|
||||
|
||||
def cleanup() {
|
||||
// ensure that message were taken from the queue
|
||||
consumerTemplate.receive('jms:output', 100)
|
||||
consumerTemplate.receive('jms:input', 100)
|
||||
this.producerTemplate.stop()
|
||||
this.consumerTemplate.stop()
|
||||
def strategy = new DefaultShutdownStrategy(this.camelContext)
|
||||
strategy.timeout = 1
|
||||
this.camelContext.shutdownStrategy = strategy
|
||||
}
|
||||
|
||||
def 'should not trigger a message that does not match input'() {
|
||||
when:
|
||||
producerTemplate.
|
||||
sendBodyAndHeaders('jms:input', new BookReturned('notmatching'), [wrong: 'header_value'])
|
||||
then:
|
||||
Exchange receivedMessage = consumerTemplate.receive('jms:output', 100)
|
||||
and:
|
||||
receivedMessage == null
|
||||
}
|
||||
|
||||
def 'should download the stub and register a route for it'() {
|
||||
when:
|
||||
// tag::client_send[]
|
||||
producerTemplate.
|
||||
sendBodyAndHeaders('jms:input', new BookReturned('foo'), [sample: 'header'])
|
||||
// end::client_send[]
|
||||
then:
|
||||
// tag::client_receive[]
|
||||
Exchange receivedMessage = consumerTemplate.receive('jms:output', 5000)
|
||||
// end::client_receive[]
|
||||
and:
|
||||
// tag::client_receive_message[]
|
||||
receivedMessage != null
|
||||
assertThatBodyContainsBookNameFoo(receivedMessage.in.body)
|
||||
receivedMessage.in.headers.get('BOOK-NAME') == 'foo'
|
||||
// end::client_receive_message[]
|
||||
}
|
||||
|
||||
def 'should trigger a message by label'() {
|
||||
when:
|
||||
// tag::client_trigger[]
|
||||
stubFinder.trigger('return_book_1')
|
||||
// end::client_trigger[]
|
||||
then:
|
||||
// tag::client_trigger_receive[]
|
||||
Exchange receivedMessage = consumerTemplate.receive('jms:output', 5000)
|
||||
// end::client_trigger_receive[]
|
||||
and:
|
||||
// tag::client_trigger_message[]
|
||||
receivedMessage != null
|
||||
assertThatBodyContainsBookNameFoo(receivedMessage.in.body)
|
||||
receivedMessage.in.headers.get('BOOK-NAME') == 'foo'
|
||||
// end::client_trigger_message[]
|
||||
}
|
||||
|
||||
def 'should trigger a label for the existing groupId:artifactId'() {
|
||||
when:
|
||||
// tag::trigger_group_artifact[]
|
||||
stubFinder.
|
||||
trigger('org.springframework.cloud.contract.verifier.stubs:camelService', 'return_book_1')
|
||||
// end::trigger_group_artifact[]
|
||||
then:
|
||||
Exchange receivedMessage = consumerTemplate.receive('jms:output', 5000)
|
||||
and:
|
||||
receivedMessage != null
|
||||
assertThatBodyContainsBookNameFoo(receivedMessage.in.body)
|
||||
receivedMessage.in.headers.get('BOOK-NAME') == 'foo'
|
||||
}
|
||||
|
||||
def 'should trigger a label for the existing artifactId'() {
|
||||
when:
|
||||
// tag::trigger_artifact[]
|
||||
stubFinder.trigger('camelService', 'return_book_1')
|
||||
// end::trigger_artifact[]
|
||||
then:
|
||||
Exchange receivedMessage = consumerTemplate.receive('jms:output', 5000)
|
||||
and:
|
||||
receivedMessage != null
|
||||
assertThatBodyContainsBookNameFoo(receivedMessage.in.body)
|
||||
receivedMessage.in.headers.get('BOOK-NAME') == 'foo'
|
||||
}
|
||||
|
||||
def 'should throw an exception when missing label is passed'() {
|
||||
when:
|
||||
stubFinder.trigger('missing label')
|
||||
then:
|
||||
thrown(IllegalArgumentException)
|
||||
}
|
||||
|
||||
def 'should throw an exception when missing label and artifactid is passed'() {
|
||||
when:
|
||||
stubFinder.trigger('some:service', 'return_book_1')
|
||||
then:
|
||||
thrown(IllegalArgumentException)
|
||||
}
|
||||
|
||||
def 'should trigger messages by running all triggers'() {
|
||||
when:
|
||||
// tag::trigger_all[]
|
||||
stubFinder.trigger()
|
||||
// end::trigger_all[]
|
||||
then:
|
||||
Exchange receivedMessage = consumerTemplate.receive('jms:output', 5000)
|
||||
and:
|
||||
receivedMessage != null
|
||||
assertThatBodyContainsBookNameFoo(receivedMessage.in.body)
|
||||
receivedMessage.in.headers.get('BOOK-NAME') == 'foo'
|
||||
}
|
||||
|
||||
def 'should trigger a label with no output message'() {
|
||||
when:
|
||||
// tag::trigger_no_output[]
|
||||
producerTemplate.
|
||||
sendBodyAndHeaders('jms:delete', new BookReturned('foo'), [sample: 'header'])
|
||||
// end::trigger_no_output[]
|
||||
then:
|
||||
noExceptionThrown()
|
||||
}
|
||||
|
||||
private boolean assertThatBodyContainsBookNameFoo(Object payload) {
|
||||
String objectAsString = payload instanceof String ? payload :
|
||||
JsonOutput.toJson(payload)
|
||||
def json = new JsonSlurper().parseText(objectAsString)
|
||||
return json.bookName == 'foo'
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ComponentScan
|
||||
@EnableAutoConfiguration
|
||||
static class Config {
|
||||
|
||||
@Bean
|
||||
ActiveMQConnectionFactory activeMQConnectionFactory(@Value('${activemq.url:vm://localhost?broker.persistent=false}') String url) {
|
||||
ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory(brokerURL: url)
|
||||
try {
|
||||
factory.trustAllPackages = true
|
||||
}
|
||||
catch (Throwable e) {
|
||||
}
|
||||
return factory
|
||||
}
|
||||
|
||||
@Bean
|
||||
JmsConfiguration jmsConfiguration(ActiveMQConnectionFactory activeMQConnectionFactory) {
|
||||
return new JmsConfiguration(connectionFactory: activeMQConnectionFactory)
|
||||
}
|
||||
|
||||
@Bean
|
||||
ActiveMQComponent activeMQComponent(JmsConfiguration jmsConfiguration) {
|
||||
return new ActiveMQComponent(configuration: jmsConfiguration)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Contract dsl =
|
||||
// tag::sample_dsl[]
|
||||
Contract.make {
|
||||
label 'return_book_1'
|
||||
input {
|
||||
triggeredBy('bookReturnedTriggered()')
|
||||
}
|
||||
outputMessage {
|
||||
sentTo('jms:output')
|
||||
body('''{ "bookName" : "foo" }''')
|
||||
headers {
|
||||
header('BOOK-NAME', 'foo')
|
||||
}
|
||||
}
|
||||
}
|
||||
// end::sample_dsl[]
|
||||
|
||||
Contract dsl2 =
|
||||
// tag::sample_dsl_2[]
|
||||
Contract.make {
|
||||
label 'return_book_2'
|
||||
input {
|
||||
messageFrom('jms:input')
|
||||
messageBody([
|
||||
bookName: 'foo'
|
||||
])
|
||||
messageHeaders {
|
||||
header('sample', 'header')
|
||||
}
|
||||
}
|
||||
outputMessage {
|
||||
sentTo('jms:output')
|
||||
body([
|
||||
bookName: 'foo'
|
||||
])
|
||||
headers {
|
||||
header('BOOK-NAME', 'foo')
|
||||
}
|
||||
}
|
||||
}
|
||||
// end::sample_dsl_2[]
|
||||
|
||||
Contract dsl3 =
|
||||
// tag::sample_dsl_3[]
|
||||
Contract.make {
|
||||
label 'delete_book'
|
||||
input {
|
||||
messageFrom('jms:delete')
|
||||
messageBody([
|
||||
bookName: 'foo'
|
||||
])
|
||||
messageHeaders {
|
||||
header('sample', 'header')
|
||||
}
|
||||
assertThat('bookWasDeleted()')
|
||||
}
|
||||
}
|
||||
// end::sample_dsl_3[]
|
||||
}
|
||||
@@ -25,7 +25,7 @@ import spock.lang.Specification
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration
|
||||
import org.springframework.boot.test.context.SpringBootContextLoader
|
||||
import org.springframework.boot.test.context.SpringBootTest
|
||||
import org.springframework.cloud.contract.spec.Contract
|
||||
import org.springframework.cloud.contract.stubrunner.StubFinder
|
||||
import org.springframework.cloud.contract.stubrunner.spring.AutoConfigureStubRunner
|
||||
@@ -34,14 +34,12 @@ import org.springframework.context.annotation.ComponentScan
|
||||
import org.springframework.context.annotation.Configuration
|
||||
import org.springframework.context.annotation.ImportResource
|
||||
import org.springframework.messaging.Message
|
||||
import org.springframework.test.context.ContextConfiguration
|
||||
|
||||
/**
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
@ContextConfiguration(classes = Config, loader = SpringBootContextLoader)
|
||||
@ImportResource("classpath*:integration-context.xml")
|
||||
@AutoConfigureStubRunner
|
||||
@SpringBootTest(classes = Config)
|
||||
@IgnoreIf({ os.windows })
|
||||
class IntegrationStubRunnerSpec extends Specification {
|
||||
|
||||
|
||||
@@ -29,7 +29,6 @@ import spock.lang.Specification
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import org.springframework.beans.factory.annotation.Value
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration
|
||||
import org.springframework.boot.test.context.SpringBootContextLoader
|
||||
import org.springframework.boot.test.context.SpringBootTest
|
||||
import org.springframework.cloud.contract.spec.Contract
|
||||
import org.springframework.cloud.contract.stubrunner.StubFinder
|
||||
@@ -40,13 +39,10 @@ import org.springframework.context.annotation.Configuration
|
||||
import org.springframework.jms.annotation.EnableJms
|
||||
import org.springframework.jms.core.JmsTemplate
|
||||
import org.springframework.jms.core.MessagePostProcessor
|
||||
import org.springframework.test.context.ContextConfiguration
|
||||
|
||||
/**
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
@ContextConfiguration(classes = Config, loader = SpringBootContextLoader)
|
||||
@SpringBootTest(properties = ["debug=true"])
|
||||
@SpringBootTest(classes = Config, properties = ["debug=true"])
|
||||
@AutoConfigureStubRunner
|
||||
@IgnoreIf({ os.windows })
|
||||
class JmsStubRunnerSpec extends Specification {
|
||||
|
||||
@@ -28,9 +28,7 @@ import spock.util.concurrent.PollingConditions
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration
|
||||
import org.springframework.boot.test.context.SpringBootContextLoader
|
||||
import org.springframework.boot.test.context.SpringBootTest
|
||||
import org.springframework.cloud.contract.spec.Contract
|
||||
import org.springframework.cloud.contract.stubrunner.StubFinder
|
||||
import org.springframework.cloud.contract.stubrunner.spring.AutoConfigureStubRunner
|
||||
import org.springframework.context.annotation.Bean
|
||||
@@ -45,230 +43,228 @@ import org.springframework.messaging.Message
|
||||
import org.springframework.messaging.MessageHeaders
|
||||
import org.springframework.messaging.support.MessageBuilder
|
||||
import org.springframework.stereotype.Component
|
||||
import org.springframework.test.context.ContextConfiguration
|
||||
|
||||
/**
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
@ContextConfiguration(classes = Config, loader = SpringBootContextLoader)
|
||||
@SpringBootTest(properties = ["debug=true"])
|
||||
@SpringBootTest(classes = Config, properties = ["debug=true"])
|
||||
@AutoConfigureStubRunner
|
||||
@IgnoreIf({ os.windows })
|
||||
@EmbeddedKafka(topics = ["input", "input2", "output", "delete"])
|
||||
@Commons
|
||||
class KafkaStubRunnerSpec extends Specification {
|
||||
|
||||
@Autowired
|
||||
StubFinder stubFinder
|
||||
@Autowired
|
||||
KafkaTemplate kafkaTemplate
|
||||
@Autowired
|
||||
MyMessageListener myMessageListener
|
||||
PollingConditions await = new PollingConditions(timeout: 15, initialDelay: 1, delay: 1)
|
||||
@Autowired
|
||||
StubFinder stubFinder
|
||||
@Autowired
|
||||
KafkaTemplate kafkaTemplate
|
||||
@Autowired
|
||||
MyMessageListener myMessageListener
|
||||
PollingConditions await = new PollingConditions(timeout: 15, initialDelay: 1, delay: 1)
|
||||
|
||||
def setup() {
|
||||
this.myMessageListener.clear()
|
||||
}
|
||||
def setup() {
|
||||
this.myMessageListener.clear()
|
||||
}
|
||||
|
||||
def cleanup() {
|
||||
this.myMessageListener.clear()
|
||||
}
|
||||
def cleanup() {
|
||||
this.myMessageListener.clear()
|
||||
}
|
||||
|
||||
private Message receiveFromOutput() {
|
||||
Message m = this.myMessageListener.output()
|
||||
log.info("Received message [" + m + "]")
|
||||
return m
|
||||
}
|
||||
private Message receiveFromOutput() {
|
||||
Message m = this.myMessageListener.output()
|
||||
log.info("Received message [" + m + "]")
|
||||
return m
|
||||
}
|
||||
|
||||
// Skipping the test on Jenkins cause it's for some reason flakey only there
|
||||
def 'should download the stub and register a route for it'() {
|
||||
expect:
|
||||
await.eventually {
|
||||
log.info("Sending the message")
|
||||
// tag::client_send[]
|
||||
Message message = MessageBuilder.createMessage(new BookReturned('foo'), new MessageHeaders([sample: "header",]))
|
||||
kafkaTemplate.setDefaultTopic('input')
|
||||
kafkaTemplate.send(message)
|
||||
// end::client_send[]
|
||||
log.info("Message sent")
|
||||
log.info("Receiving the message")
|
||||
// tag::client_receive[]
|
||||
Message receivedMessage = receiveFromOutput()
|
||||
// end::client_receive[]
|
||||
log.info("Message received [" + receivedMessage + "]")
|
||||
// tag::client_receive_message[]
|
||||
assert receivedMessage != null
|
||||
assert assertThatBodyContainsBookNameFoo(receivedMessage.getPayload())
|
||||
assert receivedMessage.getHeaders().get('BOOK-NAME') == 'foo'
|
||||
// end::client_receive_message[]
|
||||
}
|
||||
}
|
||||
// Skipping the test on Jenkins cause it's for some reason flakey only there
|
||||
def 'should download the stub and register a route for it'() {
|
||||
expect:
|
||||
await.eventually {
|
||||
log.info("Sending the message")
|
||||
// tag::client_send[]
|
||||
Message message = MessageBuilder.createMessage(new BookReturned('foo'), new MessageHeaders([sample: "header",]))
|
||||
kafkaTemplate.setDefaultTopic('input')
|
||||
kafkaTemplate.send(message)
|
||||
// end::client_send[]
|
||||
log.info("Message sent")
|
||||
log.info("Receiving the message")
|
||||
// tag::client_receive[]
|
||||
Message receivedMessage = receiveFromOutput()
|
||||
// end::client_receive[]
|
||||
log.info("Message received [" + receivedMessage + "]")
|
||||
// tag::client_receive_message[]
|
||||
assert receivedMessage != null
|
||||
assert assertThatBodyContainsBookNameFoo(receivedMessage.getPayload())
|
||||
assert receivedMessage.getHeaders().get('BOOK-NAME') == 'foo'
|
||||
// end::client_receive_message[]
|
||||
}
|
||||
}
|
||||
|
||||
def 'should propagate the Kafka record key via message headers'() {
|
||||
expect:
|
||||
await.eventually {
|
||||
log.info("Sending the message")
|
||||
// tag::client_send[]
|
||||
Message message = MessageBuilder.createMessage(new BookReturned('bar'), new MessageHeaders([kafka_messageKey: "bar5150",]))
|
||||
kafkaTemplate.setDefaultTopic('input2')
|
||||
kafkaTemplate.send(message)
|
||||
// end::client_send[]
|
||||
log.info("Message sent")
|
||||
log.info("Receiving the message")
|
||||
// tag::client_receive[]
|
||||
Message receivedMessage = receiveFromOutput()
|
||||
// end::client_receive[]
|
||||
log.info("Message received [" + receivedMessage + "]")
|
||||
// tag::client_receive_message[]
|
||||
assert receivedMessage != null
|
||||
assert assertThatBodyContainsBookName(receivedMessage.getPayload(), 'bar')
|
||||
assert receivedMessage.getHeaders().get('BOOK-NAME') == 'bar'
|
||||
assert receivedMessage.getHeaders().get("kafka_receivedMessageKey") == 'bar5150'
|
||||
// end::client_receive_message[]
|
||||
}
|
||||
}
|
||||
def 'should propagate the Kafka record key via message headers'() {
|
||||
expect:
|
||||
await.eventually {
|
||||
log.info("Sending the message")
|
||||
// tag::client_send[]
|
||||
Message message = MessageBuilder.createMessage(new BookReturned('bar'), new MessageHeaders([kafka_messageKey: "bar5150",]))
|
||||
kafkaTemplate.setDefaultTopic('input2')
|
||||
kafkaTemplate.send(message)
|
||||
// end::client_send[]
|
||||
log.info("Message sent")
|
||||
log.info("Receiving the message")
|
||||
// tag::client_receive[]
|
||||
Message receivedMessage = receiveFromOutput()
|
||||
// end::client_receive[]
|
||||
log.info("Message received [" + receivedMessage + "]")
|
||||
// tag::client_receive_message[]
|
||||
assert receivedMessage != null
|
||||
assert assertThatBodyContainsBookName(receivedMessage.getPayload(), 'bar')
|
||||
assert receivedMessage.getHeaders().get('BOOK-NAME') == 'bar'
|
||||
assert receivedMessage.getHeaders().get("kafka_receivedMessageKey") == 'bar5150'
|
||||
// end::client_receive_message[]
|
||||
}
|
||||
}
|
||||
|
||||
def 'should trigger a message by label'() {
|
||||
expect:
|
||||
await.eventually {
|
||||
// tag::client_trigger[]
|
||||
stubFinder.trigger('return_book_1')
|
||||
// end::client_trigger[]
|
||||
// tag::client_trigger_receive[]
|
||||
Message receivedMessage = receiveFromOutput()
|
||||
// end::client_trigger_receive[]
|
||||
// tag::client_trigger_message[]
|
||||
assert receivedMessage != null
|
||||
assert assertThatBodyContainsBookNameFoo(receivedMessage.getPayload())
|
||||
assert receivedMessage.getHeaders().get('BOOK-NAME') == 'foo'
|
||||
// end::client_trigger_message[]
|
||||
}
|
||||
}
|
||||
def 'should trigger a message by label'() {
|
||||
expect:
|
||||
await.eventually {
|
||||
// tag::client_trigger[]
|
||||
stubFinder.trigger('return_book_1')
|
||||
// end::client_trigger[]
|
||||
// tag::client_trigger_receive[]
|
||||
Message receivedMessage = receiveFromOutput()
|
||||
// end::client_trigger_receive[]
|
||||
// tag::client_trigger_message[]
|
||||
assert receivedMessage != null
|
||||
assert assertThatBodyContainsBookNameFoo(receivedMessage.getPayload())
|
||||
assert receivedMessage.getHeaders().get('BOOK-NAME') == 'foo'
|
||||
// end::client_trigger_message[]
|
||||
}
|
||||
}
|
||||
|
||||
def 'should trigger a label for the existing groupId:artifactId'() {
|
||||
expect:
|
||||
await.eventually {
|
||||
// tag::trigger_group_artifact[]
|
||||
stubFinder.
|
||||
trigger('my:stubs', 'return_book_1')
|
||||
// end::trigger_group_artifact[]
|
||||
Message receivedMessage = receiveFromOutput()
|
||||
assert receivedMessage != null
|
||||
assert assertThatBodyContainsBookNameFoo(receivedMessage.getPayload())
|
||||
assert receivedMessage.getHeaders().get('BOOK-NAME') == 'foo'
|
||||
}
|
||||
}
|
||||
def 'should trigger a label for the existing groupId:artifactId'() {
|
||||
expect:
|
||||
await.eventually {
|
||||
// tag::trigger_group_artifact[]
|
||||
stubFinder.
|
||||
trigger('my:stubs', 'return_book_1')
|
||||
// end::trigger_group_artifact[]
|
||||
Message receivedMessage = receiveFromOutput()
|
||||
assert receivedMessage != null
|
||||
assert assertThatBodyContainsBookNameFoo(receivedMessage.getPayload())
|
||||
assert receivedMessage.getHeaders().get('BOOK-NAME') == 'foo'
|
||||
}
|
||||
}
|
||||
|
||||
def 'should trigger a label for the existing artifactId'() {
|
||||
expect:
|
||||
await.eventually {
|
||||
// tag::trigger_artifact[]
|
||||
stubFinder.trigger('stubs', 'return_book_1')
|
||||
// end::trigger_artifact[]
|
||||
Message receivedMessage = receiveFromOutput()
|
||||
assert receivedMessage != null
|
||||
assert assertThatBodyContainsBookNameFoo(receivedMessage.getPayload())
|
||||
assert receivedMessage.getHeaders().get('BOOK-NAME') == 'foo'
|
||||
}
|
||||
}
|
||||
def 'should trigger a label for the existing artifactId'() {
|
||||
expect:
|
||||
await.eventually {
|
||||
// tag::trigger_artifact[]
|
||||
stubFinder.trigger('stubs', 'return_book_1')
|
||||
// end::trigger_artifact[]
|
||||
Message receivedMessage = receiveFromOutput()
|
||||
assert receivedMessage != null
|
||||
assert assertThatBodyContainsBookNameFoo(receivedMessage.getPayload())
|
||||
assert receivedMessage.getHeaders().get('BOOK-NAME') == 'foo'
|
||||
}
|
||||
}
|
||||
|
||||
def 'should throw an exception when missing label is passed'() {
|
||||
when:
|
||||
stubFinder.trigger('missing label')
|
||||
then:
|
||||
thrown(IllegalArgumentException)
|
||||
}
|
||||
def 'should throw an exception when missing label is passed'() {
|
||||
when:
|
||||
stubFinder.trigger('missing label')
|
||||
then:
|
||||
thrown(IllegalArgumentException)
|
||||
}
|
||||
|
||||
def 'should throw an exception when missing label and artifactid is passed'() {
|
||||
when:
|
||||
stubFinder.trigger('some:service', 'return_book_1')
|
||||
then:
|
||||
thrown(IllegalArgumentException)
|
||||
}
|
||||
def 'should throw an exception when missing label and artifactid is passed'() {
|
||||
when:
|
||||
stubFinder.trigger('some:service', 'return_book_1')
|
||||
then:
|
||||
thrown(IllegalArgumentException)
|
||||
}
|
||||
|
||||
def 'should trigger messages by running all triggers'() {
|
||||
expect:
|
||||
await.eventually {
|
||||
// tag::trigger_all[]
|
||||
stubFinder.trigger()
|
||||
// end::trigger_all[]
|
||||
Message receivedMessage = receiveFromOutput()
|
||||
assert receivedMessage != null
|
||||
assert assertThatBodyContainsBookNameFoo(receivedMessage.getPayload())
|
||||
assert receivedMessage.getHeaders().get('BOOK-NAME') == 'foo'
|
||||
}
|
||||
}
|
||||
def 'should trigger messages by running all triggers'() {
|
||||
expect:
|
||||
await.eventually {
|
||||
// tag::trigger_all[]
|
||||
stubFinder.trigger()
|
||||
// end::trigger_all[]
|
||||
Message receivedMessage = receiveFromOutput()
|
||||
assert receivedMessage != null
|
||||
assert assertThatBodyContainsBookNameFoo(receivedMessage.getPayload())
|
||||
assert receivedMessage.getHeaders().get('BOOK-NAME') == 'foo'
|
||||
}
|
||||
}
|
||||
|
||||
def 'should trigger a label with no output message'() {
|
||||
when:
|
||||
// tag::trigger_no_output[]
|
||||
Message message = MessageBuilder.createMessage(new BookReturned('foo'), new MessageHeaders([sample: "header",]))
|
||||
kafkaTemplate.setDefaultTopic('delete')
|
||||
kafkaTemplate.send(message)
|
||||
// end::trigger_no_output[]
|
||||
then:
|
||||
noExceptionThrown()
|
||||
}
|
||||
def 'should trigger a label with no output message'() {
|
||||
when:
|
||||
// tag::trigger_no_output[]
|
||||
Message message = MessageBuilder.createMessage(new BookReturned('foo'), new MessageHeaders([sample: "header",]))
|
||||
kafkaTemplate.setDefaultTopic('delete')
|
||||
kafkaTemplate.send(message)
|
||||
// end::trigger_no_output[]
|
||||
then:
|
||||
noExceptionThrown()
|
||||
}
|
||||
|
||||
def 'should not trigger a message that does not match input'() {
|
||||
when:
|
||||
Message message = MessageBuilder.createMessage(new BookReturned('notmatching'), new MessageHeaders([wrong: "header",]))
|
||||
kafkaTemplate.setDefaultTopic('input')
|
||||
kafkaTemplate.send(message)
|
||||
then:
|
||||
Message receivedMessage = receiveFromOutput()
|
||||
and:
|
||||
receivedMessage == null
|
||||
}
|
||||
def 'should not trigger a message that does not match input'() {
|
||||
when:
|
||||
Message message = MessageBuilder.createMessage(new BookReturned('notmatching'), new MessageHeaders([wrong: "header",]))
|
||||
kafkaTemplate.setDefaultTopic('input')
|
||||
kafkaTemplate.send(message)
|
||||
then:
|
||||
Message receivedMessage = receiveFromOutput()
|
||||
and:
|
||||
receivedMessage == null
|
||||
}
|
||||
|
||||
private boolean assertThatBodyContainsBookNameFoo(Object payload) {
|
||||
return assertThatBodyContainsBookName(payload, 'foo')
|
||||
}
|
||||
private boolean assertThatBodyContainsBookNameFoo(Object payload) {
|
||||
return assertThatBodyContainsBookName(payload, 'foo')
|
||||
}
|
||||
|
||||
private boolean assertThatBodyContainsBookName(Object payload, String expectedValue) {
|
||||
log.info("Got payload [" + payload + "]")
|
||||
String objectAsString = payload instanceof String ? payload :
|
||||
JsonOutput.toJson(payload)
|
||||
def json = new JsonSlurper().parseText(objectAsString)
|
||||
return json.bookName == expectedValue
|
||||
}
|
||||
private boolean assertThatBodyContainsBookName(Object payload, String expectedValue) {
|
||||
log.info("Got payload [" + payload + "]")
|
||||
String objectAsString = payload instanceof String ? payload :
|
||||
JsonOutput.toJson(payload)
|
||||
def json = new JsonSlurper().parseText(objectAsString)
|
||||
return json.bookName == expectedValue
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ComponentScan
|
||||
@EnableAutoConfiguration
|
||||
@EnableKafka
|
||||
static class Config {
|
||||
@Configuration
|
||||
@ComponentScan
|
||||
@EnableAutoConfiguration
|
||||
@EnableKafka
|
||||
static class Config {
|
||||
|
||||
@Bean
|
||||
DefaultKafkaHeaderMapper headerMapper() {
|
||||
return new DefaultKafkaHeaderMapper();
|
||||
}
|
||||
@Bean
|
||||
DefaultKafkaHeaderMapper headerMapper() {
|
||||
return new DefaultKafkaHeaderMapper();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Commons
|
||||
@Component
|
||||
static class MyMessageListener {
|
||||
@Commons
|
||||
@Component
|
||||
static class MyMessageListener {
|
||||
|
||||
CountDownLatch latch = new CountDownLatch(1)
|
||||
CountDownLatch latch = new CountDownLatch(1)
|
||||
|
||||
Message output
|
||||
Message output
|
||||
|
||||
@KafkaListener(topics = ["output"])
|
||||
void output(Message message) {
|
||||
log.info("I got the message [${message}]")
|
||||
this.output = message
|
||||
this.latch.countDown()
|
||||
}
|
||||
@KafkaListener(topics = ["output"])
|
||||
void output(Message message) {
|
||||
log.info("I got the message [${message}]")
|
||||
this.output = message
|
||||
this.latch.countDown()
|
||||
}
|
||||
|
||||
void clear() {
|
||||
this.output = null
|
||||
this.latch = new CountDownLatch(1)
|
||||
}
|
||||
void clear() {
|
||||
this.output = null
|
||||
this.latch = new CountDownLatch(1)
|
||||
}
|
||||
|
||||
Message output() {
|
||||
this.latch.await(2, TimeUnit.SECONDS)
|
||||
return this.output
|
||||
}
|
||||
}
|
||||
Message output() {
|
||||
this.latch.await(2, TimeUnit.SECONDS)
|
||||
return this.output
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,22 +20,19 @@ import spock.lang.Specification
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration
|
||||
import org.springframework.boot.test.context.SpringBootContextLoader
|
||||
import org.springframework.boot.test.context.SpringBootTest
|
||||
import org.springframework.cloud.contract.stubrunner.StubFinder
|
||||
import org.springframework.cloud.contract.stubrunner.spring.AutoConfigureStubRunner
|
||||
import org.springframework.cloud.contract.stubrunner.spring.StubRunnerProperties
|
||||
import org.springframework.context.annotation.Configuration
|
||||
import org.springframework.test.context.ActiveProfiles
|
||||
import org.springframework.test.context.ContextConfiguration
|
||||
/**
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
@ContextConfiguration(classes = MocoConfig, loader = SpringBootContextLoader)
|
||||
// tag::[classpath_stub_runner]
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE)
|
||||
@SpringBootTest(classes = MocoConfig, webEnvironment = SpringBootTest.WebEnvironment.NONE)
|
||||
@AutoConfigureStubRunner(ids = ["com.example:fraudDetectionServerMoco"],
|
||||
stubsMode = StubRunnerProperties.StubsMode.CLASSPATH)
|
||||
stubsMode = StubRunnerProperties.StubsMode.CLASSPATH)
|
||||
// end::[classpath_stub_runner]
|
||||
@ActiveProfiles("test")
|
||||
class MocoHttpServerStubSpec extends Specification {
|
||||
|
||||
@@ -1,225 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.contract.stubrunner.messaging.stream
|
||||
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
import groovy.json.JsonOutput
|
||||
import groovy.json.JsonSlurper
|
||||
import spock.lang.Ignore
|
||||
import spock.lang.Specification
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration
|
||||
import org.springframework.boot.autoconfigure.ImportAutoConfiguration
|
||||
import org.springframework.boot.test.context.SpringBootContextLoader
|
||||
import org.springframework.boot.test.context.SpringBootTest
|
||||
import org.springframework.cloud.contract.spec.Contract
|
||||
import org.springframework.cloud.contract.stubrunner.StubFinder
|
||||
import org.springframework.cloud.contract.stubrunner.spring.AutoConfigureStubRunner
|
||||
import org.springframework.cloud.contract.verifier.messaging.MessageVerifier
|
||||
import org.springframework.cloud.contract.verifier.messaging.boot.AutoConfigureMessageVerifier
|
||||
import org.springframework.cloud.stream.binder.test.TestChannelBinderConfiguration
|
||||
import org.springframework.context.annotation.Configuration
|
||||
import org.springframework.messaging.Message
|
||||
import org.springframework.test.context.ContextConfiguration
|
||||
/**
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
@ContextConfiguration(classes = Config, loader = SpringBootContextLoader)
|
||||
@SpringBootTest(properties = "debug=true")
|
||||
@AutoConfigureStubRunner
|
||||
@AutoConfigureMessageVerifier
|
||||
//@IgnoreIf({ os.windows })
|
||||
@Ignore("Wait until the feature of runtime message sending and polling is available")
|
||||
class StreamStubRunnerSpec extends Specification {
|
||||
|
||||
@Autowired
|
||||
StubFinder stubFinder
|
||||
@Autowired
|
||||
MessageVerifier<Message<?>> messaging
|
||||
|
||||
def 'should download the stub and register a route for it'() {
|
||||
when:
|
||||
// tag::client_send[]
|
||||
messaging.send(new BookReturned('foo'), [sample: 'header'], 'bookStorage')
|
||||
// end::client_send[]
|
||||
then:
|
||||
// tag::client_receive[]
|
||||
Message<?> receivedMessage = messaging.receive('returnBook')
|
||||
// end::client_receive[]
|
||||
and:
|
||||
// tag::client_receive_message[]
|
||||
receivedMessage != null
|
||||
assertJsons(receivedMessage.payload)
|
||||
receivedMessage.headers.get('BOOK-NAME') == 'foo'
|
||||
// end::client_receive_message[]
|
||||
}
|
||||
|
||||
def 'should trigger a message by label'() {
|
||||
when:
|
||||
// tag::client_trigger[]
|
||||
stubFinder.trigger('return_book_1')
|
||||
// end::client_trigger[]
|
||||
then:
|
||||
// tag::client_trigger_receive[]
|
||||
Message<?> receivedMessage = messaging.receive('returnBook')
|
||||
// end::client_trigger_receive[]
|
||||
and:
|
||||
// tag::client_trigger_message[]
|
||||
receivedMessage != null
|
||||
assertJsons(receivedMessage.payload)
|
||||
receivedMessage.headers.get('BOOK-NAME') == 'foo'
|
||||
// end::client_trigger_message[]
|
||||
}
|
||||
|
||||
def 'should trigger a label for the existing groupId:artifactId'() {
|
||||
when:
|
||||
// tag::trigger_group_artifact[]
|
||||
stubFinder.trigger('org.springframework.cloud.contract.verifier.stubs:streamService', 'return_book_1')
|
||||
// end::trigger_group_artifact[]
|
||||
then:
|
||||
Message<?> receivedMessage = messaging.receive('returnBook')
|
||||
and:
|
||||
receivedMessage != null
|
||||
assertJsons(receivedMessage.payload)
|
||||
receivedMessage.headers.get('BOOK-NAME') == 'foo'
|
||||
}
|
||||
|
||||
def 'should trigger a label for the existing artifactId'() {
|
||||
when:
|
||||
// tag::trigger_artifact[]
|
||||
stubFinder.trigger('streamService', 'return_book_1')
|
||||
// end::trigger_artifact[]
|
||||
then:
|
||||
Message<?> receivedMessage = messaging.receive('returnBook')
|
||||
and:
|
||||
receivedMessage != null
|
||||
assertJsons(receivedMessage.payload)
|
||||
receivedMessage.headers.get('BOOK-NAME') == 'foo'
|
||||
}
|
||||
|
||||
def 'should throw exception when missing label is passed'() {
|
||||
when:
|
||||
stubFinder.trigger('missing label')
|
||||
then:
|
||||
thrown(IllegalArgumentException)
|
||||
}
|
||||
|
||||
def 'should throw exception when missing label and artifactid is passed'() {
|
||||
when:
|
||||
stubFinder.trigger('some:service', 'return_book_1')
|
||||
then:
|
||||
thrown(IllegalArgumentException)
|
||||
}
|
||||
|
||||
def 'should trigger messages by running all triggers'() {
|
||||
when:
|
||||
// tag::trigger_all[]
|
||||
stubFinder.trigger()
|
||||
// end::trigger_all[]
|
||||
then:
|
||||
Message<?> receivedMessage = messaging.receive('returnBook')
|
||||
and:
|
||||
receivedMessage != null
|
||||
assertJsons(receivedMessage.payload)
|
||||
receivedMessage.headers.get('BOOK-NAME') == 'foo'
|
||||
}
|
||||
|
||||
def 'should trigger a label with no output message'() {
|
||||
when:
|
||||
// tag::trigger_no_output[]
|
||||
messaging.send(new BookReturned('foo'), [sample: 'header'], 'delete')
|
||||
// end::trigger_no_output[]
|
||||
then:
|
||||
noExceptionThrown()
|
||||
}
|
||||
|
||||
def 'should not trigger a message that does not match input'() {
|
||||
when:
|
||||
messaging.send(new BookReturned('not_matching'), [wrong: 'header_value'], 'bookStorage')
|
||||
then:
|
||||
Message<?> receivedMessage = messaging.receive('returnBook', 100, TimeUnit.MILLISECONDS)
|
||||
and:
|
||||
receivedMessage == null
|
||||
}
|
||||
|
||||
private boolean assertJsons(Object payload) {
|
||||
String objectAsString = payload instanceof String ? payload :
|
||||
payload instanceof byte[] ? new String(payload)
|
||||
: JsonOutput.toJson(payload)
|
||||
def json = new JsonSlurper().parseText(objectAsString)
|
||||
return json.bookName == 'foo'
|
||||
}
|
||||
|
||||
Contract dsl =
|
||||
// tag::sample_dsl[]
|
||||
Contract.make {
|
||||
label 'return_book_1'
|
||||
input { triggeredBy('bookReturnedTriggered()') }
|
||||
outputMessage {
|
||||
sentTo('returnBook')
|
||||
body('''{ "bookName" : "foo" }''')
|
||||
headers { header('BOOK-NAME', 'foo') }
|
||||
}
|
||||
}
|
||||
// end::sample_dsl[]
|
||||
|
||||
Contract dsl2 =
|
||||
// tag::sample_dsl_2[]
|
||||
Contract.make {
|
||||
label 'return_book_2'
|
||||
input {
|
||||
messageFrom('bookStorage')
|
||||
messageBody([
|
||||
bookName: 'foo'
|
||||
])
|
||||
messageHeaders { header('sample', 'header') }
|
||||
}
|
||||
outputMessage {
|
||||
sentTo('returnBook')
|
||||
body([
|
||||
bookName: 'foo'
|
||||
])
|
||||
headers { header('BOOK-NAME', 'foo') }
|
||||
}
|
||||
}
|
||||
// end::sample_dsl_2[]
|
||||
|
||||
Contract dsl3 =
|
||||
// tag::sample_dsl_3[]
|
||||
Contract.make {
|
||||
label 'delete_book'
|
||||
input {
|
||||
messageFrom('delete')
|
||||
messageBody([
|
||||
bookName: 'foo'
|
||||
])
|
||||
messageHeaders { header('sample', 'header') }
|
||||
assertThat('bookWasDeleted()')
|
||||
}
|
||||
}
|
||||
// end::sample_dsl_3[]
|
||||
|
||||
@ImportAutoConfiguration(TestChannelBinderConfiguration.class)
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
protected static class Config {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user