diff --git a/docs/pom.xml b/docs/pom.xml
index 4550fde76e..cacfde52de 100644
--- a/docs/pom.xml
+++ b/docs/pom.xml
@@ -19,8 +19,7 @@
${basedir}/..
3.4
stubrunner.*|wiremock.*|
-
-
+ deploy
4.0.0
@@ -149,11 +148,10 @@
org.asciidoctor
asciidoctor-maven-plugin
-
-
+
maven-deploy-plugin
diff --git a/pom.xml b/pom.xml
index 6438ba9e64..d5342f3fbc 100644
--- a/pom.xml
+++ b/pom.xml
@@ -50,6 +50,8 @@
1.13.0
3.0.0-M7
4.2.0
+ ${artemis-jms-server.version}
+ 1.17.5
4.0.0
@@ -70,6 +72,7 @@
false
false
+ 2.26.0
@@ -119,6 +122,26 @@
camel-spring-boot
${camel.version}
+
+ org.apache.camel.springboot
+ camel-rabbitmq-starter
+ ${camel.version}
+
+
+ org.apache.camel.springboot
+ camel-direct-starter
+ ${camel.version}
+
+
+ org.apache.camel.springboot
+ camel-bean-starter
+ ${camel.version}
+
+
+ org.apache.camel.springboot
+ camel-jackson-starter
+ ${camel.version}
+
org.apache.camel
camel-core
@@ -144,6 +167,11 @@
camel-activemq
${camel.version}
+
+ org.apache.activemq
+ artemis-jms-server
+ ${artemis-jms-server.version}
+
net.sf.jopt-simple
jopt-simple
@@ -477,7 +505,21 @@
org.awaitility
awaitility
${awaitility.version}
- test
+
+
+ org.apache.activemq
+ artemis-junit
+ ${artemis.version}
+
+
+ org.testcontainers
+ rabbitmq
+ ${testcontainers.version}
+
+
+ org.testcontainers
+ junit-jupiter
+ ${testcontainers.version}
@@ -620,6 +662,24 @@
true
+
+
+
+
+ netflix-candidates
+ Netflix Candidates
+ https://artifactory-oss.prod.netflix.net/artifactory/maven-oss-candidates
+
+ false
+
+
diff --git a/spring-cloud-contract-stub-runner/pom.xml b/spring-cloud-contract-stub-runner/pom.xml
index 50aa6d7cca..6cfd44ddcf 100644
--- a/spring-cloud-contract-stub-runner/pom.xml
+++ b/spring-cloud-contract-stub-runner/pom.xml
@@ -75,11 +75,6 @@
jopt-simple
true
-
org.springframework.kafka
spring-kafka
diff --git a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/BatchStubRunnerFactory.java b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/BatchStubRunnerFactory.java
index 45e0b5bd7f..a16d126151 100644
--- a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/BatchStubRunnerFactory.java
+++ b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/BatchStubRunnerFactory.java
@@ -16,7 +16,7 @@
package org.springframework.cloud.contract.stubrunner;
-import org.springframework.cloud.contract.verifier.messaging.MessageVerifier;
+import org.springframework.cloud.contract.verifier.messaging.MessageVerifierSender;
import org.springframework.cloud.contract.verifier.messaging.noop.NoOpStubMessages;
/**
@@ -32,13 +32,13 @@ public class BatchStubRunnerFactory {
private final StubDownloader stubDownloader;
- private final MessageVerifier> contractVerifierMessaging;
+ private final MessageVerifierSender> contractVerifierMessaging;
public BatchStubRunnerFactory(StubRunnerOptions stubRunnerOptions) {
this(stubRunnerOptions, new NoOpStubMessages());
}
- public BatchStubRunnerFactory(StubRunnerOptions stubRunnerOptions, MessageVerifier verifier) {
+ public BatchStubRunnerFactory(StubRunnerOptions stubRunnerOptions, MessageVerifierSender> verifier) {
this(stubRunnerOptions, aetherStubDownloader(stubRunnerOptions), verifier);
}
@@ -47,7 +47,7 @@ public class BatchStubRunnerFactory {
}
public BatchStubRunnerFactory(StubRunnerOptions stubRunnerOptions, StubDownloader stubDownloader,
- MessageVerifier> contractVerifierMessaging) {
+ MessageVerifierSender> contractVerifierMessaging) {
this.stubRunnerOptions = stubRunnerOptions;
this.stubDownloader = stubDownloader;
this.contractVerifierMessaging = contractVerifierMessaging;
diff --git a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubRunner.java b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubRunner.java
index 29b6967cf7..6a337eccaf 100644
--- a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubRunner.java
+++ b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubRunner.java
@@ -30,7 +30,7 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.cloud.contract.spec.Contract;
-import org.springframework.cloud.contract.verifier.messaging.MessageVerifier;
+import org.springframework.cloud.contract.verifier.messaging.MessageVerifierSender;
import org.springframework.cloud.contract.verifier.messaging.noop.NoOpStubMessages;
import org.springframework.core.io.support.SpringFactoriesLoader;
import org.springframework.util.StringUtils;
@@ -60,7 +60,7 @@ public class StubRunner implements StubRunning {
}
public StubRunner(StubRunnerOptions stubRunnerOptions, String repositoryPath, StubConfiguration stubsConfiguration,
- MessageVerifier> contractVerifierMessaging) {
+ MessageVerifierSender> contractVerifierMessaging) {
this.stubsConfiguration = stubsConfiguration;
this.stubRunnerOptions = stubRunnerOptions;
List serverStubs = SpringFactoriesLoader.loadFactories(HttpServerStub.class, null);
diff --git a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubRunnerExecutor.java b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubRunnerExecutor.java
index d05767254b..371a1f48bf 100644
--- a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubRunnerExecutor.java
+++ b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubRunnerExecutor.java
@@ -41,7 +41,7 @@ import org.springframework.cloud.contract.stubrunner.AvailablePortScanner.PortCa
import org.springframework.cloud.contract.stubrunner.provider.wiremock.WireMockHttpServerStub;
import org.springframework.cloud.contract.verifier.converter.YamlContract;
import org.springframework.cloud.contract.verifier.converter.YamlContractConverter;
-import org.springframework.cloud.contract.verifier.messaging.MessageVerifier;
+import org.springframework.cloud.contract.verifier.messaging.MessageVerifierSender;
import org.springframework.cloud.contract.verifier.messaging.internal.ContractVerifierMessageMetadata;
import org.springframework.cloud.contract.verifier.messaging.noop.NoOpStubMessages;
import org.springframework.cloud.contract.verifier.util.BodyExtractor;
@@ -57,7 +57,7 @@ class StubRunnerExecutor implements StubFinder {
private final AvailablePortScanner portScanner;
- private final MessageVerifier> contractVerifierMessaging;
+ private final MessageVerifierSender> contractVerifierMessaging;
private final List serverStubs;
@@ -65,7 +65,7 @@ class StubRunnerExecutor implements StubFinder {
private final YamlContractConverter yamlContractConverter = new YamlContractConverter();
- StubRunnerExecutor(AvailablePortScanner portScanner, MessageVerifier> contractVerifierMessaging,
+ StubRunnerExecutor(AvailablePortScanner portScanner, MessageVerifierSender> contractVerifierMessaging,
List serverStubs) {
this.portScanner = portScanner;
this.contractVerifierMessaging = contractVerifierMessaging;
diff --git a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubRunnerFactory.java b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubRunnerFactory.java
index b26970e919..106e77aa11 100644
--- a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubRunnerFactory.java
+++ b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubRunnerFactory.java
@@ -36,7 +36,7 @@ import org.springframework.cloud.contract.stubrunner.provider.wiremock.WireMockH
import org.springframework.cloud.contract.verifier.converter.RecursiveFilesConverter;
import org.springframework.cloud.contract.verifier.converter.StubGenerator;
import org.springframework.cloud.contract.verifier.converter.StubGeneratorProvider;
-import org.springframework.cloud.contract.verifier.messaging.MessageVerifier;
+import org.springframework.cloud.contract.verifier.messaging.MessageVerifierSender;
import org.springframework.cloud.contract.verifier.wiremock.DslToWireMockClientConverter;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.SpringFactoriesLoader;
@@ -53,10 +53,10 @@ class StubRunnerFactory {
private final StubDownloader stubDownloader;
- private final MessageVerifier> contractVerifierMessaging;
+ private final MessageVerifierSender> contractVerifierMessaging;
StubRunnerFactory(StubRunnerOptions stubRunnerOptions, StubDownloader stubDownloader,
- MessageVerifier> contractVerifierMessaging) {
+ MessageVerifierSender> contractVerifierMessaging) {
this.stubRunnerOptions = stubRunnerOptions;
this.stubDownloader = stubDownloader;
this.contractVerifierMessaging = contractVerifierMessaging;
diff --git a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/messaging/kafka/StubRunnerKafkaConfiguration.java b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/messaging/kafka/StubRunnerKafkaConfiguration.java
index 7543e615b7..284408f95e 100644
--- a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/messaging/kafka/StubRunnerKafkaConfiguration.java
+++ b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/messaging/kafka/StubRunnerKafkaConfiguration.java
@@ -17,7 +17,6 @@
package org.springframework.cloud.contract.stubrunner.messaging.kafka;
import java.util.Collection;
-import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
@@ -26,7 +25,6 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
-import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
@@ -34,8 +32,6 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cloud.contract.spec.Contract;
import org.springframework.cloud.contract.stubrunner.BatchStubRunner;
import org.springframework.cloud.contract.stubrunner.StubConfiguration;
-import org.springframework.cloud.contract.verifier.messaging.kafka.ContractVerifierKafkaConfiguration;
-import org.springframework.cloud.contract.verifier.messaging.kafka.KafkaStubMessagesInitializer;
import org.springframework.cloud.contract.verifier.util.MapConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -59,21 +55,10 @@ import org.springframework.util.StringUtils;
@ConditionalOnClass({ KafkaTemplate.class, EmbeddedKafkaBroker.class })
@ConditionalOnProperty(name = "stubrunner.kafka.enabled", havingValue = "true", matchIfMissing = true)
@ConditionalOnBean(EmbeddedKafkaBroker.class)
-@AutoConfigureBefore(ContractVerifierKafkaConfiguration.class)
public class StubRunnerKafkaConfiguration {
private static final Log log = LogFactory.getLog(StubRunnerKafkaConfiguration.class);
- @Bean
- @ConditionalOnMissingBean
- @ConditionalOnProperty(name = "stubrunner.kafka.initializer.enabled", havingValue = "true", matchIfMissing = true)
- KafkaStubMessagesInitializer stubRunnerKafkaStubMessagesInitializer() {
- if (log.isDebugEnabled()) {
- log.debug("Registering a noop kafka messages initializer");
- }
- return (broker, kafkaProperties) -> new HashMap<>();
- }
-
@Bean
@ConditionalOnMissingBean(name = "stubFlowRegistrar")
public FlowRegistrar stubFlowRegistrar(ConfigurableListableBeanFactory beanFactory,
diff --git a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/spring/StubRunnerConfiguration.java b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/spring/StubRunnerConfiguration.java
index e22050cf05..0c3cb2772c 100644
--- a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/spring/StubRunnerConfiguration.java
+++ b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/spring/StubRunnerConfiguration.java
@@ -21,7 +21,6 @@ import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
-import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanPostProcessor;
@@ -36,6 +35,8 @@ import org.springframework.cloud.contract.stubrunner.StubRunnerOptions;
import org.springframework.cloud.contract.stubrunner.StubRunnerOptionsBuilder;
import org.springframework.cloud.contract.verifier.converter.YamlContract;
import org.springframework.cloud.contract.verifier.messaging.MessageVerifier;
+import org.springframework.cloud.contract.verifier.messaging.MessageVerifierReceiver;
+import org.springframework.cloud.contract.verifier.messaging.MessageVerifierSender;
import org.springframework.cloud.contract.verifier.messaging.noop.NoOpStubMessages;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -156,9 +157,12 @@ public class StubRunnerConfiguration {
}
+@SuppressWarnings("unchecked")
class LazyMessageVerifier implements MessageVerifier {
- private MessageVerifier> messageVerifier;
+ private MessageVerifierSender> messageVerifierSender;
+
+ private MessageVerifierReceiver> messageVerifierReceiver;
private final BeanFactory beanFactory;
@@ -166,36 +170,40 @@ class LazyMessageVerifier implements MessageVerifier {
this.beanFactory = beanFactory;
}
- private MessageVerifier messageVerifier() {
- if (this.messageVerifier == null) {
- try {
- this.messageVerifier = this.beanFactory.getBean(MessageVerifier.class);
- }
- catch (BeansException ex) {
- this.messageVerifier = new NoOpStubMessages();
- }
+ private MessageVerifierSender messageVerifierSender() {
+ if (this.messageVerifierSender == null) {
+ this.messageVerifierSender = this.beanFactory.getBeanProvider(MessageVerifierSender.class)
+ .getIfAvailable(NoOpStubMessages::new);
}
- return this.messageVerifier;
+ return this.messageVerifierSender;
+ }
+
+ private MessageVerifierReceiver messageVerifierReceiver() {
+ if (this.messageVerifierReceiver == null) {
+ this.messageVerifierReceiver = this.beanFactory.getBeanProvider(MessageVerifierReceiver.class)
+ .getIfAvailable(NoOpStubMessages::new);
+ }
+ return this.messageVerifierReceiver;
}
@Override
public void send(Object message, String destination, YamlContract contract) {
- messageVerifier().send(message, destination, contract);
+ messageVerifierSender().send(message, destination, contract);
}
@Override
public Object receive(String destination, long timeout, TimeUnit timeUnit, YamlContract contract) {
- return messageVerifier().receive(destination, timeout, timeUnit, contract);
+ return messageVerifierReceiver().receive(destination, timeout, timeUnit, contract);
}
@Override
public Object receive(String destination, YamlContract contract) {
- return messageVerifier().receive(destination, contract);
+ return messageVerifierReceiver().receive(destination, contract);
}
@Override
public void send(Object payload, Map headers, String destination, YamlContract contract) {
- messageVerifier().send(payload, headers, destination, contract);
+ messageVerifierSender().send(payload, headers, destination, contract);
}
}
diff --git a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/spring/cloud/eureka/EurekaStubsRegistrar.java b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/spring/cloud/eureka/EurekaStubsRegistrar.java
index ad13b2e6c0..7d9d3983eb 100644
--- a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/spring/cloud/eureka/EurekaStubsRegistrar.java
+++ b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/spring/cloud/eureka/EurekaStubsRegistrar.java
@@ -30,14 +30,17 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
+import org.springframework.boot.actuate.health.StatusAggregator;
import org.springframework.cloud.client.serviceregistry.ServiceRegistry;
import org.springframework.cloud.commons.util.InetUtils;
import org.springframework.cloud.contract.stubrunner.StubConfiguration;
import org.springframework.cloud.contract.stubrunner.StubRunning;
import org.springframework.cloud.contract.stubrunner.spring.cloud.StubMapperProperties;
import org.springframework.cloud.contract.stubrunner.spring.cloud.StubsRegistrar;
+import org.springframework.cloud.loadbalancer.support.SimpleObjectProvider;
import org.springframework.cloud.netflix.eureka.CloudEurekaClient;
import org.springframework.cloud.netflix.eureka.EurekaClientConfigBean;
+import org.springframework.cloud.netflix.eureka.EurekaHealthCheckHandler;
import org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean;
import org.springframework.cloud.netflix.eureka.InstanceInfoFactory;
import org.springframework.cloud.netflix.eureka.serviceregistry.EurekaRegistration;
@@ -92,11 +95,16 @@ public class EurekaStubsRegistrar implements StubsRegistrar {
+ ", " + instance.getNonSecurePort() + ", " + instance.getInstanceId() + "]");
InstanceInfo instanceInfo = new InstanceInfoFactory().create(instance);
ApplicationInfoManager applicationInfoManager = new ApplicationInfoManager(instance, instanceInfo);
- AbstractDiscoveryClientOptionalArgs args = args();
+ AbstractDiscoveryClientOptionalArgs> args = args();
EurekaClient client = new CloudEurekaClient(applicationInfoManager, this.eurekaClientConfigBean, args,
this.context);
EurekaRegistration registration = EurekaRegistration.builder(instance)
.with(this.eurekaClientConfigBean, this.context).with(client).build();
+ EurekaHealthCheckHandler eurekaHealthCheckHandler = new EurekaHealthCheckHandler(
+ StatusAggregator.getDefault());
+ eurekaHealthCheckHandler.setApplicationContext(context);
+ eurekaHealthCheckHandler.afterPropertiesSet();
+ registration.setHealthCheckHandler(new SimpleObjectProvider<>(eurekaHealthCheckHandler));
this.registrations.add(registration);
try {
this.serviceRegistry.register(registration);
@@ -110,7 +118,7 @@ public class EurekaStubsRegistrar implements StubsRegistrar {
}
}
- private AbstractDiscoveryClientOptionalArgs args() {
+ private AbstractDiscoveryClientOptionalArgs> args() {
try {
return this.context.getBean(AbstractDiscoveryClientOptionalArgs.class);
}
diff --git a/spring-cloud-contract-stub-runner/src/main/resources/META-INF/spring/org.springframework.cloud.contract.stubrunner.spring.AutoConfigureStubRunner.imports b/spring-cloud-contract-stub-runner/src/main/resources/META-INF/spring/org.springframework.cloud.contract.stubrunner.spring.AutoConfigureStubRunner.imports
index 59fd232984..15c6286085 100644
--- a/spring-cloud-contract-stub-runner/src/main/resources/META-INF/spring/org.springframework.cloud.contract.stubrunner.spring.AutoConfigureStubRunner.imports
+++ b/spring-cloud-contract-stub-runner/src/main/resources/META-INF/spring/org.springframework.cloud.contract.stubrunner.spring.AutoConfigureStubRunner.imports
@@ -4,6 +4,7 @@ org.springframework.cloud.contract.stubrunner.spring.cloud.loadbalancer.SpringCl
org.springframework.cloud.contract.stubrunner.messaging.integration.StubRunnerIntegrationConfiguration
org.springframework.cloud.contract.stubrunner.messaging.jms.StubRunnerJmsConfiguration
org.springframework.cloud.contract.stubrunner.messaging.stream.StubRunnerStreamConfiguration
+org.springframework.cloud.contract.stubrunner.spring.cloud.eureka.StubRunnerSpringCloudEurekaAutoConfiguration
org.springframework.cloud.contract.stubrunner.spring.cloud.zookeeper.StubRunnerSpringCloudZookeeperAutoConfiguration
org.springframework.cloud.contract.stubrunner.spring.cloud.consul.StubRunnerSpringCloudConsulAutoConfiguration
org.springframework.cloud.contract.stubrunner.messaging.StubRunnerStreamsIntegrationAutoConfiguration
diff --git a/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/serverexamples/StubRunnerBootEurekaExample.java b/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/serverexamples/StubRunnerBootEurekaExample.java
index 5158dda531..1c33b26645 100644
--- a/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/serverexamples/StubRunnerBootEurekaExample.java
+++ b/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/serverexamples/StubRunnerBootEurekaExample.java
@@ -20,7 +20,6 @@ import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.contract.stubrunner.server.EnableStubRunnerServer;
import org.springframework.cloud.contract.stubrunner.spring.AutoConfigureStubRunner;
-import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
/**
* @author Marcin Grzejszczak
@@ -28,7 +27,6 @@ import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
// tag::stubrunnereureka[]
@SpringBootApplication
@EnableStubRunnerServer
-@EnableEurekaClient
@AutoConfigureStubRunner
public class StubRunnerBootEurekaExample {
diff --git a/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/StubRunnerSpringCloudAutoConfigurationSpec.groovy b/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/StubRunnerSpringCloudAutoConfigurationSpec.groovy
index aafcf1e6ff..5183c14507 100644
--- a/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/StubRunnerSpringCloudAutoConfigurationSpec.groovy
+++ b/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/StubRunnerSpringCloudAutoConfigurationSpec.groovy
@@ -16,7 +16,10 @@
package org.springframework.cloud.contract.stubrunner.spring.cloud
-import spock.lang.Specification
+import org.junit.jupiter.api.AfterAll
+import org.junit.jupiter.api.BeforeAll
+import org.junit.jupiter.api.BeforeEach
+import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.autoconfigure.EnableAutoConfiguration
@@ -42,55 +45,59 @@ import org.springframework.web.client.RestTemplate
@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 {
+class StubRunnerSpringCloudAutoConfigurationSpec {
- @Autowired
- StubFinder stubFinder
- @Autowired
- @LoadBalanced
- RestTemplate restTemplate
- @Autowired
- LoadBalancerClientFactory loadBalancerClientFactory;
+ @Autowired
+ StubFinder stubFinder
+ @Autowired
+ @LoadBalanced
+ RestTemplate restTemplate
+ @Autowired
+ LoadBalancerClientFactory loadBalancerClientFactory;
- void setupSpec() {
- System.clearProperty("stubrunner.repository.root")
- System.clearProperty("stubrunner.classifier")
- }
+ @BeforeAll
+ static void setupSpec() {
+ System.clearProperty("stubrunner.repository.root")
+ System.clearProperty("stubrunner.classifier")
+ }
- void cleanupSpec() {
- setupSpec()
- }
+ @AfterAll
+ static void cleanupSpec() {
+ setupSpec()
+ }
- def setup() {
- assert loadBalancerClientFactory instanceof StubRunnerLoadBalancerClientFactory
- }
+ @BeforeEach
+ void setup() {
+ assert loadBalancerClientFactory.getClass().getSimpleName() == "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'
- restTemplate.getForObject('http://loanIssuance/name', String) == 'loanIssuance'
- restTemplate.getForObject('http://someNameThatShouldMapFraudDetectionServer/name', String) == 'fraudDetectionServer'
- }
- // end::test[]
+ // tag::test[]
+ @Test
+ void 'should make service discovery work'() {
+ expect: 'WireMocks are running'
+ assert "${stubFinder.findStubUrl('loanIssuance').toString()}/name".toURL().text == 'loanIssuance'
+ assert "${stubFinder.findStubUrl('fraudDetectionServer').toString()}/name".toURL().text == 'fraudDetectionServer'
+ and: 'Stubs can be reached via load service discovery'
+ assert restTemplate.getForObject('http://loanIssuance/name', String) == 'loanIssuance'
+ assert restTemplate.getForObject('http://someNameThatShouldMapFraudDetectionServer/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()
+ }
+ }
}
diff --git a/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/StubRunnerSpringCloudReactiveAutoConfigurationSpec.groovy b/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/StubRunnerSpringCloudReactiveAutoConfigurationSpec.groovy
index 1cd17eacab..6466928c58 100644
--- a/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/StubRunnerSpringCloudReactiveAutoConfigurationSpec.groovy
+++ b/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/StubRunnerSpringCloudReactiveAutoConfigurationSpec.groovy
@@ -18,7 +18,8 @@ package org.springframework.cloud.contract.stubrunner.spring.cloud
import org.junit.AfterClass
import org.junit.BeforeClass
-import spock.lang.Specification
+import org.junit.jupiter.api.BeforeEach
+import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.autoconfigure.EnableAutoConfiguration
@@ -45,53 +46,55 @@ import org.springframework.web.client.RestTemplate
@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/")
-class StubRunnerSpringCloudReactiveAutoConfigurationSpec extends Specification {
- @Autowired
- StubFinder stubFinder
- @Autowired
- ReactiveDiscoveryClient reactiveDiscoveryClient;
- @Autowired
- LoadBalancerClientFactory loadBalancerClientFactory;
- RestTemplate restTemplate = new RestTemplate()
+ 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 {
+ @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
- }
+ @BeforeEach
+ void setup() {
+ assert loadBalancerClientFactory.getClass().getSimpleName() == "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[]
+ @Test
+ void 'should make service discovery work'() {
+ expect: 'WireMocks are running'
+ assert "${stubFinder.findStubUrl('loanIssuance').toString()}/name".toURL().text == 'loanIssuance'
+ assert "${stubFinder.findStubUrl('fraudDetectionServer').toString()}/name".toURL().text == 'fraudDetectionServer'
+ and: 'Stubs can be reached via load service discovery'
+ ServiceInstance loanIssuance = reactiveDiscoveryClient.getInstances('loanIssuance').blockFirst()
+ assert restTemplate.getForObject(loanIssuance.uri.toString() + '/name', String) == 'loanIssuance'
+ ServiceInstance fraudDetection = reactiveDiscoveryClient.getInstances('someNameThatShouldMapFraudDetectionServer').blockFirst()
+ assert 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()
+ }
+ }
}
diff --git a/spring-cloud-contract-verifier/src/main/java/org/springframework/cloud/contract/verifier/messaging/amqp/ContractVerifierAmqpAutoConfiguration.java b/spring-cloud-contract-verifier/src/main/java/org/springframework/cloud/contract/verifier/messaging/amqp/ContractVerifierAmqpAutoConfiguration.java
deleted file mode 100644
index d08583d99c..0000000000
--- a/spring-cloud-contract-verifier/src/main/java/org/springframework/cloud/contract/verifier/messaging/amqp/ContractVerifierAmqpAutoConfiguration.java
+++ /dev/null
@@ -1,119 +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.verifier.messaging.amqp;
-
-import java.util.List;
-
-import org.springframework.amqp.core.Binding;
-import org.springframework.amqp.core.Message;
-import org.springframework.amqp.rabbit.core.RabbitTemplate;
-import org.springframework.amqp.rabbit.listener.RabbitListenerEndpointRegistry;
-import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
-import org.springframework.amqp.support.SimpleAmqpHeaderMapper;
-import org.springframework.amqp.support.converter.MessageConverter;
-import org.springframework.amqp.support.converter.MessagingMessageConverter;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.autoconfigure.AutoConfigureAfter;
-import org.springframework.boot.autoconfigure.AutoConfigureBefore;
-import org.springframework.boot.autoconfigure.amqp.RabbitProperties;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
-import org.springframework.boot.test.mock.mockito.SpyBean;
-import org.springframework.cloud.contract.verifier.messaging.MessageVerifier;
-import org.springframework.cloud.contract.verifier.messaging.integration.ContractVerifierIntegrationConfiguration;
-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.stream.ContractVerifierStreamAutoConfiguration;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-
-import static java.util.Collections.emptyList;
-
-/**
- * Configuration setting up {@link MessageVerifier} for use with plain
- * spring-rabbit/spring-amqp.
- *
- * @author Mathias Düsterhöft
- * @since 1.0.2
- */
-@Configuration(proxyBeanMethods = false)
-@ConditionalOnClass(RabbitTemplate.class)
-@AutoConfigureBefore(ContractVerifierIntegrationConfiguration.class)
-@AutoConfigureAfter(ContractVerifierStreamAutoConfiguration.class)
-public class ContractVerifierAmqpAutoConfiguration {
-
- @Bean
- @ConditionalOnBean({ RabbitTemplate.class, MessageVerifier.class })
- @ConditionalOnMissingBean
- public ContractVerifierMessaging contractVerifierMessaging(MessageVerifier exchange,
- RabbitTemplate rabbitTemplate) {
- return new ContractVerifierHelper(exchange, rabbitTemplate.getMessageConverter());
- }
-
- @Configuration
- @ConditionalOnProperty(name = "stubrunner.amqp.enabled", havingValue = "true")
- static class ContractVerifierAmqpSpyAutoConfiguration {
-
- @SpyBean
- private RabbitTemplate rabbitTemplate;
-
- @Autowired(required = false)
- private RabbitListenerEndpointRegistry rabbitListenerEndpointRegistry;
-
- @Autowired(required = false)
- private List simpleMessageListenerContainers = emptyList();
-
- @Autowired(required = false)
- private List bindings = emptyList();
-
- @Autowired
- private RabbitProperties rabbitProperties;
-
- @Bean
- @ConditionalOnMissingBean
- public MessageVerifier contractVerifierMessageExchange() {
- return new SpringAmqpStubMessages(this.rabbitTemplate,
- new MessageListenerAccessor(this.rabbitListenerEndpointRegistry,
- this.simpleMessageListenerContainers, this.bindings),
- this.rabbitProperties);
- }
-
- }
-
-}
-
-class ContractVerifierHelper extends ContractVerifierMessaging {
-
- private final MessageConverter messageConverter;
-
- ContractVerifierHelper(MessageVerifier exchange, MessageConverter messageConverter) {
- super(exchange);
- this.messageConverter = messageConverter;
- }
-
- @Override
- protected ContractVerifierMessage convert(Message message) {
- MessagingMessageConverter messageConverter = new MessagingMessageConverter(this.messageConverter,
- new SimpleAmqpHeaderMapper());
- org.springframework.messaging.Message> messagingMessage;
- messagingMessage = (org.springframework.messaging.Message>) messageConverter.fromMessage(message);
- return new ContractVerifierMessage(messagingMessage.getPayload(), messagingMessage.getHeaders());
- }
-
-}
diff --git a/spring-cloud-contract-verifier/src/main/java/org/springframework/cloud/contract/verifier/messaging/amqp/MessageListenerAccessor.java b/spring-cloud-contract-verifier/src/main/java/org/springframework/cloud/contract/verifier/messaging/amqp/MessageListenerAccessor.java
deleted file mode 100644
index 7c0e036a5e..0000000000
--- a/spring-cloud-contract-verifier/src/main/java/org/springframework/cloud/contract/verifier/messaging/amqp/MessageListenerAccessor.java
+++ /dev/null
@@ -1,109 +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.verifier.messaging.amqp;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import org.springframework.amqp.core.Binding;
-import org.springframework.amqp.core.Binding.DestinationType;
-import org.springframework.amqp.rabbit.listener.MessageListenerContainer;
-import org.springframework.amqp.rabbit.listener.RabbitListenerEndpointRegistry;
-import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
-
-/**
- * Abstraction hiding details of the different sources of message listeners.
- *
- * Needed because
- * {@link org.springframework.amqp.rabbit.annotation.RabbitListenerAnnotationBeanPostProcessor}
- * adds the listeners to the {@link RabbitListenerEndpointRegistry} so that the registry
- * is empty when wired into an auto configuration class so we wrap it in the accessor to
- * access the listeners late at runtime.
- *
- * @author Mathias Düsterhöft
- * @since 1.0.2
- */
-class MessageListenerAccessor {
-
- private final RabbitListenerEndpointRegistry rabbitListenerEndpointRegistry;
-
- private final List simpleMessageListenerContainers;
-
- private final List bindings;
-
- MessageListenerAccessor(RabbitListenerEndpointRegistry rabbitListenerEndpointRegistry,
- List simpleMessageListenerContainers, List bindings) {
- this.rabbitListenerEndpointRegistry = rabbitListenerEndpointRegistry;
- this.simpleMessageListenerContainers = simpleMessageListenerContainers;
- this.bindings = bindings;
- }
-
- List getListenerContainersForDestination(String destination, String routingKey) {
- List listenerContainers = collectListenerContainers();
- // we interpret the destination as exchange name and collect all the queues bound
- // to this exchange
- Set queueNames = collectQueuesBoundToDestination(destination, routingKey);
- return getListenersByBoundQueues(listenerContainers, queueNames);
- }
-
- private List getListenersByBoundQueues(
- List listenerContainers, Set queueNames) {
- List matchingContainers = new ArrayList<>();
- for (SimpleMessageListenerContainer listenerContainer : listenerContainers) {
- if (listenerContainer.getQueueNames() != null) {
- for (String queueName : listenerContainer.getQueueNames()) {
- if (queueNames.contains(queueName)) {
- matchingContainers.add(listenerContainer);
- break;
- }
- }
- }
- }
- return matchingContainers;
- }
-
- private Set collectQueuesBoundToDestination(String destination, String routingKey) {
- Set queueNames = new HashSet<>();
- for (Binding binding : this.bindings) {
- if (destination.equals(binding.getExchange())
- && (routingKey == null || routingKey.equals(binding.getRoutingKey()))
- && DestinationType.QUEUE.equals(binding.getDestinationType())) {
- queueNames.add(binding.getDestination());
- }
- }
- return queueNames;
- }
-
- private List collectListenerContainers() {
- List listenerContainers = new ArrayList<>();
- if (this.simpleMessageListenerContainers != null) {
- listenerContainers.addAll(this.simpleMessageListenerContainers);
- }
- if (this.rabbitListenerEndpointRegistry != null) {
- for (MessageListenerContainer listenerContainer : this.rabbitListenerEndpointRegistry
- .getListenerContainers()) {
- if (listenerContainer instanceof SimpleMessageListenerContainer) {
- listenerContainers.add((SimpleMessageListenerContainer) listenerContainer);
- }
- }
- }
- return listenerContainers;
- }
-
-}
diff --git a/spring-cloud-contract-verifier/src/main/java/org/springframework/cloud/contract/verifier/messaging/amqp/RabbitMockConnectionFactoryAutoConfiguration.java b/spring-cloud-contract-verifier/src/main/java/org/springframework/cloud/contract/verifier/messaging/amqp/RabbitMockConnectionFactoryAutoConfiguration.java
deleted file mode 100644
index 61d0a517b4..0000000000
--- a/spring-cloud-contract-verifier/src/main/java/org/springframework/cloud/contract/verifier/messaging/amqp/RabbitMockConnectionFactoryAutoConfiguration.java
+++ /dev/null
@@ -1,88 +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.verifier.messaging.amqp;
-
-import com.rabbitmq.client.AMQP;
-import com.rabbitmq.client.Channel;
-import com.rabbitmq.client.Connection;
-import org.mockito.Mockito;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
-
-import org.springframework.amqp.rabbit.connection.AbstractConnectionFactory;
-import org.springframework.amqp.rabbit.connection.ConnectionFactory;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.lang.NonNull;
-
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-/**
- * Spring rabbit test utility that provides a mock ConnectionFactory to avoid having to
- * connect against a running broker.
- *
- * Set verifier.amqp.mockConnection=true to enable the mocked ConnectionFactory
- *
- * @author Mathias Düsterhöft
- * @since 1.0.2
- */
-@Configuration(proxyBeanMethods = false)
-@ConditionalOnBean(ContractVerifierAmqpAutoConfiguration.class)
-@ConditionalOnProperty(value = "stubrunner.amqp.mockConnection", havingValue = "true", matchIfMissing = true)
-public class RabbitMockConnectionFactoryAutoConfiguration {
-
- @Bean
- public ConnectionFactory connectionFactory() {
- final Connection mockConnection = mock(Connection.class);
- final AMQP.Queue.DeclareOk mockDeclareOk = mock(AMQP.Queue.DeclareOk.class);
- com.rabbitmq.client.ConnectionFactory mockConnectionFactory = mock(com.rabbitmq.client.ConnectionFactory.class,
- new Answer() {
- @Override
- public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
- // hack for keeping backward compatibility with #303
- if ("newConnection".equals(invocationOnMock.getMethod().getName())) {
- return mockConnection;
- }
- return Mockito.RETURNS_DEFAULTS.answer(invocationOnMock);
- }
- });
- try {
- final Channel mockChannel = mock(Channel.class, invocationOnMock -> {
- if ("queueDeclare".equals(invocationOnMock.getMethod().getName())) {
- return mockDeclareOk;
- }
- return Mockito.RETURNS_DEFAULTS.answer(invocationOnMock);
- });
- when(mockConnection.isOpen()).thenReturn(true);
- when(mockConnection.createChannel()).thenReturn(mockChannel);
- when(mockConnection.createChannel(Mockito.anyInt())).thenReturn(mockChannel);
- }
- catch (Exception e) {
- throw new RuntimeException(e);
- }
- return new AbstractConnectionFactory(mockConnectionFactory) {
- @Override
- public @NonNull org.springframework.amqp.rabbit.connection.Connection createConnection() {
- return super.createBareConnection();
- }
- };
- }
-
-}
diff --git a/spring-cloud-contract-verifier/src/main/java/org/springframework/cloud/contract/verifier/messaging/amqp/SpringAmqpStubMessages.java b/spring-cloud-contract-verifier/src/main/java/org/springframework/cloud/contract/verifier/messaging/amqp/SpringAmqpStubMessages.java
deleted file mode 100644
index fc57ec19fb..0000000000
--- a/spring-cloud-contract-verifier/src/main/java/org/springframework/cloud/contract/verifier/messaging/amqp/SpringAmqpStubMessages.java
+++ /dev/null
@@ -1,212 +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.verifier.messaging.amqp;
-
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.TimeUnit;
-
-import com.rabbitmq.client.Channel;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.mockito.ArgumentCaptor;
-import org.mockito.ArgumentMatchers;
-
-import org.springframework.amqp.core.Message;
-import org.springframework.amqp.core.MessageListener;
-import org.springframework.amqp.core.MessageProperties;
-import org.springframework.amqp.core.MessagePropertiesBuilder;
-import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
-import org.springframework.amqp.rabbit.core.RabbitTemplate;
-import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
-import org.springframework.amqp.rabbit.listener.api.ChannelAwareMessageListener;
-import org.springframework.amqp.support.AmqpHeaders;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.autoconfigure.amqp.RabbitProperties;
-import org.springframework.cloud.contract.verifier.converter.YamlContract;
-import org.springframework.cloud.contract.verifier.messaging.MessageVerifier;
-import org.springframework.cloud.contract.verifier.messaging.internal.ContractVerifierMessageMetadata;
-import org.springframework.cloud.contract.verifier.util.MetadataUtil;
-import org.springframework.messaging.MessageHeaders;
-import org.springframework.util.Assert;
-
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.atLeastOnce;
-import static org.mockito.Mockito.mockingDetails;
-import static org.mockito.Mockito.verify;
-import static org.springframework.amqp.support.converter.DefaultClassMapper.DEFAULT_CLASSID_FIELD_NAME;
-
-/**
- * {@link MessageVerifier} implementation to integrate with plain
- * spring-amqp/spring-rabbit. It is meant to be used without interacting with a running
- * bus.
- *
- * It relies on the RabbitTemplate to be a spy to be able to capture send messages.
- *
- * Messages are not sent to the bus - but are handed over to a
- * {@link SimpleMessageListenerContainer} which allows us to test the full deserialization
- * and listener invocation.
- *
- * @author Mathias Düsterhöft
- * @since 1.0.2
- */
-public class SpringAmqpStubMessages implements MessageVerifier {
-
- private static final Log log = LogFactory.getLog(SpringAmqpStubMessages.class);
-
- private final RabbitTemplate rabbitTemplate;
-
- private final MessageListenerAccessor messageListenerAccessor;
-
- private RabbitProperties rabbitProperties;
-
- @Autowired
- public SpringAmqpStubMessages(RabbitTemplate rabbitTemplate, MessageListenerAccessor messageListenerAccessor,
- RabbitProperties rabbitProperties) {
- Assert.notNull(rabbitTemplate, "RabbitTemplate must be set");
- Assert.isTrue(mockingDetails(rabbitTemplate).isSpy() || mockingDetails(rabbitTemplate).isMock(),
- "StubRunner AMQP will work only if RabbiTemplate is a spy");
- this.rabbitTemplate = rabbitTemplate;
- this.messageListenerAccessor = messageListenerAccessor;
- this.rabbitProperties = rabbitProperties;
- }
-
- @Override
- public void send(T payload, Map messageHeaders, String destination, YamlContract contract) {
- final MessageHeaders headers = new MessageHeaders(messageHeaders);
- Message message = org.springframework.amqp.core.MessageBuilder.withBody(((String) payload).getBytes())
- .andProperties(MessagePropertiesBuilder.newInstance()
- .setContentType(header(headers, MessageHeaders.CONTENT_TYPE)).copyHeaders(headers).build())
- .build();
- if (headers.containsKey(DEFAULT_CLASSID_FIELD_NAME)) {
- message.getMessageProperties().setHeader(DEFAULT_CLASSID_FIELD_NAME,
- headers.get(DEFAULT_CLASSID_FIELD_NAME));
- }
- if (headers.containsKey(AmqpHeaders.RECEIVED_ROUTING_KEY)) {
- message.getMessageProperties().setReceivedRoutingKey(header(headers, AmqpHeaders.RECEIVED_ROUTING_KEY));
- }
- send(message, destination, contract);
- }
-
- private String header(MessageHeaders headers, String headerName) {
- Object value = headers.get(headerName);
-
- if (value == null) {
- return "";
- }
- else if (value instanceof String) {
- return (String) value;
- }
- else if (value instanceof Iterable) {
- Iterable values = ((Iterable) value);
- return values.iterator().hasNext() ? (String) values.iterator().next() : "";
- }
- return value.toString();
- }
-
- public void mergeMessagePropertiesFromMetadata(YamlContract contract, Message message) {
- if (contract != null && contract.metadata.containsKey(AmqpMetadata.METADATA_KEY)) {
- AmqpMetadata amqpMetadata = AmqpMetadata.fromMetadata(contract.metadata);
- ContractVerifierMessageMetadata messageMetadata = ContractVerifierMessageMetadata
- .fromMetadata(contract.metadata);
- boolean isInput = isInputMessage(messageMetadata);
- MessageProperties fromMetadata = isInput ? amqpMetadata.getInput().getMessageProperties()
- : amqpMetadata.getOutputMessage().getMessageProperties();
- MetadataUtil.merge(message.getMessageProperties(), fromMetadata);
- }
- }
-
- public boolean isInputMessage(ContractVerifierMessageMetadata messageMetadata) {
- return messageMetadata.getMessageType() == ContractVerifierMessageMetadata.MessageType.INPUT;
- }
-
- @Override
- public void send(Message message, String destination, YamlContract contract) {
- mergeMessagePropertiesFromMetadata(contract, message);
- final String routingKey = message.getMessageProperties().getReceivedRoutingKey();
- List listenerContainers = this.messageListenerAccessor
- .getListenerContainersForDestination(destination, routingKey);
- if (listenerContainers.isEmpty()) {
- throw new IllegalStateException("no listeners found for destination " + destination);
- }
- for (SimpleMessageListenerContainer listenerContainer : listenerContainers) {
- Object messageListener = listenerContainer.getMessageListener();
- if (isChannelAwareListener(listenerContainer, messageListener)) {
- try {
- ((ChannelAwareMessageListener) messageListener).onMessage(message,
- createChannel(listenerContainer, transactionalChannel()));
- }
- catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
- else {
- ((MessageListener) messageListener).onMessage(message);
- }
- }
- }
-
- Channel createChannel(SimpleMessageListenerContainer listenerContainer, boolean transactional) {
- return listenerContainer.getConnectionFactory().createConnection().createChannel(transactional);
- }
-
- boolean isChannelAwareListener(SimpleMessageListenerContainer listenerContainer, Object messageListener) {
- return messageListener instanceof ChannelAwareMessageListener
- && listenerContainer.getConnectionFactory() != null;
- }
-
- private boolean transactionalChannel() {
- if (this.rabbitProperties == null) {
- // backward compatibility
- return true;
- }
- return this.rabbitProperties.getPublisherConfirmType() == null
- || this.rabbitProperties.getPublisherConfirmType() == CachingConnectionFactory.ConfirmType.NONE;
- }
-
- @Override
- public Message receive(String destination, long timeout, TimeUnit timeUnit, YamlContract contract) {
- ArgumentCaptor messageCaptor = ArgumentCaptor.forClass(Message.class);
- ArgumentCaptor routingKeyCaptor = ArgumentCaptor.forClass(String.class);
- verify(this.rabbitTemplate, atLeastOnce()).send(eq(destination), routingKeyCaptor.capture(),
- messageCaptor.capture(), ArgumentMatchers.any());
- if (messageCaptor.getAllValues().isEmpty()) {
- log.info("no messages found on destination [" + destination + "]");
- return null;
- }
- else if (messageCaptor.getAllValues().size() > 1) {
- log.info("multiple messages found on destination [" + destination + "] returning last one");
- return messageCaptor.getValue();
- }
- Message message = messageCaptor.getValue();
- if (message == null) {
- log.info("no messages found on destination [" + destination + "]");
- return null;
- }
- if (!routingKeyCaptor.getValue().isEmpty()) {
- log.info("routing key passed [" + routingKeyCaptor.getValue() + "]");
- message.getMessageProperties().setReceivedRoutingKey(routingKeyCaptor.getValue());
- }
- return message;
- }
-
- @Override
- public Message receive(String destination, YamlContract contract) {
- return receive(destination, 5, TimeUnit.SECONDS, contract);
- }
-
-}
diff --git a/spring-cloud-contract-verifier/src/main/java/org/springframework/cloud/contract/verifier/messaging/camel/ContractVerifierCamelConfiguration.java b/spring-cloud-contract-verifier/src/main/java/org/springframework/cloud/contract/verifier/messaging/camel/ContractVerifierCamelConfiguration.java
index 005c3b62f3..041872911d 100644
--- a/spring-cloud-contract-verifier/src/main/java/org/springframework/cloud/contract/verifier/messaging/camel/ContractVerifierCamelConfiguration.java
+++ b/spring-cloud-contract-verifier/src/main/java/org/springframework/cloud/contract/verifier/messaging/camel/ContractVerifierCamelConfiguration.java
@@ -27,6 +27,8 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cloud.contract.verifier.messaging.MessageVerifier;
+import org.springframework.cloud.contract.verifier.messaging.MessageVerifierReceiver;
+import org.springframework.cloud.contract.verifier.messaging.MessageVerifierSender;
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.jms.ContractVerifierJmsConfiguration;
@@ -54,16 +56,16 @@ public class ContractVerifierCamelConfiguration {
@Bean
@ConditionalOnMissingBean
- public ContractVerifierMessaging contractVerifierMessaging(MessageVerifier exchange) {
- return new ContractVerifierCamelHelper(exchange);
+ public ContractVerifierMessaging contractVerifierMessaging(MessageVerifierSender sender, MessageVerifierReceiver receiver) {
+ return new ContractVerifierCamelHelper(sender, receiver);
}
}
class ContractVerifierCamelHelper extends ContractVerifierMessaging {
- ContractVerifierCamelHelper(MessageVerifier exchange) {
- super(exchange);
+ ContractVerifierCamelHelper(MessageVerifierSender sender, MessageVerifierReceiver receiver) {
+ super(sender, receiver);
}
@Override
diff --git a/spring-cloud-contract-verifier/src/main/java/org/springframework/cloud/contract/verifier/messaging/integration/ContractVerifierIntegrationConfiguration.java b/spring-cloud-contract-verifier/src/main/java/org/springframework/cloud/contract/verifier/messaging/integration/ContractVerifierIntegrationConfiguration.java
index a439ec94ae..87c1aca775 100644
--- a/spring-cloud-contract-verifier/src/main/java/org/springframework/cloud/contract/verifier/messaging/integration/ContractVerifierIntegrationConfiguration.java
+++ b/spring-cloud-contract-verifier/src/main/java/org/springframework/cloud/contract/verifier/messaging/integration/ContractVerifierIntegrationConfiguration.java
@@ -21,6 +21,8 @@ import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.cloud.contract.verifier.messaging.MessageVerifier;
+import org.springframework.cloud.contract.verifier.messaging.MessageVerifierReceiver;
+import org.springframework.cloud.contract.verifier.messaging.MessageVerifierSender;
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.noop.NoOpContractVerifierAutoConfiguration;
@@ -47,16 +49,16 @@ public class ContractVerifierIntegrationConfiguration {
@Bean
@ConditionalOnMissingBean
- public ContractVerifierMessaging> contractVerifierMessaging(MessageVerifier> exchange) {
- return new ContractVerifierHelper(exchange);
+ public ContractVerifierMessaging> contractVerifierMessaging(MessageVerifierSender> sender, MessageVerifierReceiver> receiver) {
+ return new ContractVerifierHelper(sender, receiver);
}
}
class ContractVerifierHelper extends ContractVerifierMessaging> {
- ContractVerifierHelper(MessageVerifier> exchange) {
- super(exchange);
+ ContractVerifierHelper(MessageVerifierSender> sender, MessageVerifierReceiver> receiver) {
+ super(sender, receiver);
}
@Override
diff --git a/spring-cloud-contract-verifier/src/main/java/org/springframework/cloud/contract/verifier/messaging/internal/ContractVerifierMessaging.java b/spring-cloud-contract-verifier/src/main/java/org/springframework/cloud/contract/verifier/messaging/internal/ContractVerifierMessaging.java
index 987cc27e77..f7737e4923 100644
--- a/spring-cloud-contract-verifier/src/main/java/org/springframework/cloud/contract/verifier/messaging/internal/ContractVerifierMessaging.java
+++ b/spring-cloud-contract-verifier/src/main/java/org/springframework/cloud/contract/verifier/messaging/internal/ContractVerifierMessaging.java
@@ -25,6 +25,8 @@ import org.apache.commons.logging.LogFactory;
import org.springframework.cloud.contract.verifier.converter.YamlContract;
import org.springframework.cloud.contract.verifier.messaging.MessageVerifier;
+import org.springframework.cloud.contract.verifier.messaging.MessageVerifierReceiver;
+import org.springframework.cloud.contract.verifier.messaging.MessageVerifierSender;
/**
* Wrapper around messaging. Abstracts all message related operations like sending,
@@ -38,12 +40,18 @@ public class ContractVerifierMessaging {
private static final Log log = LogFactory.getLog(ContractVerifierMessaging.class);
- private final MessageVerifier exchange;
+ private final MessageVerifierSender sender;
- public ContractVerifierMessaging(MessageVerifier exchange) {
- this.exchange = exchange;
- if (exchange != null) {
- log.info("The message verifier implementation is of type [" + exchange.getClass() + "]");
+ private final MessageVerifierReceiver receiver;
+
+ public ContractVerifierMessaging(MessageVerifierSender sender, MessageVerifierReceiver receiver) {
+ this.sender = sender;
+ this.receiver = receiver;
+ if (sender != null) {
+ log.info("The message verifier sender implementation is of type [" + sender.getClass() + "]");
+ }
+ if (receiver != null) {
+ log.info("The message verifier receiver implementation is of type [" + receiver.getClass() + "]");
}
}
@@ -51,7 +59,7 @@ public class ContractVerifierMessaging {
if (contract != null) {
setMessageType(contract, ContractVerifierMessageMetadata.MessageType.INPUT);
}
- this.exchange.send(message.getPayload(), message.getHeaders(), destination, contract);
+ this.sender.send(message.getPayload(), message.getHeaders(), destination, contract);
}
public void send(ContractVerifierMessage message, String destination) {
@@ -62,7 +70,7 @@ public class ContractVerifierMessaging {
if (contract != null) {
setMessageType(contract, ContractVerifierMessageMetadata.MessageType.OUTPUT);
}
- return convert(this.exchange.receive(destination, contract));
+ return convert(this.receiver.receive(destination, contract));
}
private void setMessageType(YamlContract contract, ContractVerifierMessageMetadata.MessageType output) {
diff --git a/spring-cloud-contract-verifier/src/main/java/org/springframework/cloud/contract/verifier/messaging/jms/ContractVerifierJmsConfiguration.java b/spring-cloud-contract-verifier/src/main/java/org/springframework/cloud/contract/verifier/messaging/jms/ContractVerifierJmsConfiguration.java
index 298fdbb10d..199921df02 100644
--- a/spring-cloud-contract-verifier/src/main/java/org/springframework/cloud/contract/verifier/messaging/jms/ContractVerifierJmsConfiguration.java
+++ b/spring-cloud-contract-verifier/src/main/java/org/springframework/cloud/contract/verifier/messaging/jms/ContractVerifierJmsConfiguration.java
@@ -34,6 +34,8 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cloud.contract.verifier.messaging.MessageVerifier;
+import org.springframework.cloud.contract.verifier.messaging.MessageVerifierReceiver;
+import org.springframework.cloud.contract.verifier.messaging.MessageVerifierSender;
import org.springframework.cloud.contract.verifier.messaging.integration.ContractVerifierIntegrationConfiguration;
import org.springframework.cloud.contract.verifier.messaging.internal.ContractVerifierMessage;
import org.springframework.cloud.contract.verifier.messaging.internal.ContractVerifierMessaging;
@@ -60,8 +62,8 @@ public class ContractVerifierJmsConfiguration {
@Bean
@ConditionalOnMissingBean
- ContractVerifierMessaging contractVerifierJmsMessaging(MessageVerifier exchange) {
- return new ContractVerifierJmsHelper(exchange);
+ ContractVerifierMessaging contractVerifierJmsMessaging(MessageVerifierSender sender, MessageVerifierReceiver receiver) {
+ return new ContractVerifierJmsHelper(sender, receiver);
}
}
@@ -70,8 +72,8 @@ class ContractVerifierJmsHelper extends ContractVerifierMessaging {
private static final Log log = LogFactory.getLog(ContractVerifierJmsHelper.class);
- ContractVerifierJmsHelper(MessageVerifier exchange) {
- super(exchange);
+ ContractVerifierJmsHelper(MessageVerifierSender sender, MessageVerifierReceiver receiver) {
+ super(sender, receiver);
}
@Override
diff --git a/spring-cloud-contract-verifier/src/main/java/org/springframework/cloud/contract/verifier/messaging/kafka/ContractVerifierKafkaConfiguration.java b/spring-cloud-contract-verifier/src/main/java/org/springframework/cloud/contract/verifier/messaging/kafka/ContractVerifierKafkaConfiguration.java
deleted file mode 100644
index 3ad1e9ab6a..0000000000
--- a/spring-cloud-contract-verifier/src/main/java/org/springframework/cloud/contract/verifier/messaging/kafka/ContractVerifierKafkaConfiguration.java
+++ /dev/null
@@ -1,116 +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.verifier.messaging.kafka;
-
-import java.nio.charset.StandardCharsets;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.function.Supplier;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import org.springframework.boot.autoconfigure.AutoConfigureBefore;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
-import org.springframework.boot.autoconfigure.kafka.KafkaProperties;
-import org.springframework.cloud.contract.verifier.messaging.MessageVerifier;
-import org.springframework.cloud.contract.verifier.messaging.integration.ContractVerifierIntegrationConfiguration;
-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.noop.NoOpContractVerifierAutoConfiguration;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.kafka.core.KafkaTemplate;
-import org.springframework.kafka.test.EmbeddedKafkaBroker;
-import org.springframework.messaging.Message;
-import org.springframework.messaging.MessageHeaders;
-
-/**
- * @author Marcin Grzejszczak
- */
-@Configuration(proxyBeanMethods = false)
-@ConditionalOnClass({ KafkaTemplate.class, EmbeddedKafkaBroker.class })
-@ConditionalOnProperty(name = "stubrunner.kafka.enabled", havingValue = "true", matchIfMissing = true)
-@AutoConfigureBefore({ ContractVerifierIntegrationConfiguration.class, NoOpContractVerifierAutoConfiguration.class })
-@ConditionalOnBean(EmbeddedKafkaBroker.class)
-public class ContractVerifierKafkaConfiguration {
-
- private static final Log log = LogFactory.getLog(ContractVerifierKafkaConfiguration.class);
-
- @Bean
- @ConditionalOnMissingBean
- MessageVerifier> contractVerifierKafkaMessageExchange(Supplier kafkaTemplate,
- EmbeddedKafkaBroker broker, KafkaProperties kafkaProperties, KafkaStubMessagesInitializer initializer) {
- return new KafkaStubMessages(kafkaTemplate.get(), broker, kafkaProperties, initializer);
- }
-
- @Bean
- @ConditionalOnMissingBean
- Supplier contractVerifierKafkaTemplateSupplier(KafkaTemplate kafkaTemplate) {
- return () -> kafkaTemplate;
- }
-
- @Bean
- @ConditionalOnMissingBean
- KafkaStubMessagesInitializer contractVerifierKafkaStubMessagesInitializer() {
- if (log.isDebugEnabled()) {
- log.debug("Registering contract verifier stub messages initializer");
- }
- return new ContractVerifierKafkaStubMessagesInitializer();
- }
-
- @Bean
- @ConditionalOnMissingBean
- ContractVerifierMessaging> contractVerifierKafkaMessaging(MessageVerifier> exchange) {
- return new ContractVerifierKafkaHelper(exchange);
- }
-
-}
-
-class ContractVerifierKafkaHelper extends ContractVerifierMessaging> {
-
- ContractVerifierKafkaHelper(MessageVerifier> exchange) {
- super(exchange);
- }
-
- @Override
- protected ContractVerifierMessage convert(Message> message) {
- return new ContractVerifierMessage(message.getPayload(), convertHeaders(message.getHeaders()));
- }
-
- private MessageHeaders convertHeaders(Map headers) {
- final Map headersMap = new HashMap<>();
- if (headers != null) {
- headers.forEach((k, v) -> headersMap.put(k, maybeConvertValue(v)));
- }
- return new MessageHeaders(headersMap);
- }
-
- private Object maybeConvertValue(Object value) {
- if (value == null) {
- return value;
- }
- if (!(value instanceof byte[])) {
- return value;
- }
- return new String((byte[]) value, StandardCharsets.UTF_8);
- }
-
-}
diff --git a/spring-cloud-contract-verifier/src/main/java/org/springframework/cloud/contract/verifier/messaging/kafka/ContractVerifierKafkaStubMessagesInitializer.java b/spring-cloud-contract-verifier/src/main/java/org/springframework/cloud/contract/verifier/messaging/kafka/ContractVerifierKafkaStubMessagesInitializer.java
deleted file mode 100644
index 8c9f2988ee..0000000000
--- a/spring-cloud-contract-verifier/src/main/java/org/springframework/cloud/contract/verifier/messaging/kafka/ContractVerifierKafkaStubMessagesInitializer.java
+++ /dev/null
@@ -1,67 +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.verifier.messaging.kafka;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.kafka.clients.consumer.Consumer;
-import org.apache.kafka.clients.consumer.ConsumerConfig;
-
-import org.springframework.boot.autoconfigure.kafka.KafkaProperties;
-import org.springframework.kafka.core.DefaultKafkaConsumerFactory;
-import org.springframework.kafka.test.EmbeddedKafkaBroker;
-import org.springframework.kafka.test.utils.KafkaTestUtils;
-
-class ContractVerifierKafkaStubMessagesInitializer implements KafkaStubMessagesInitializer {
-
- private static final Log log = LogFactory.getLog(ContractVerifierKafkaStubMessagesInitializer.class);
-
- @Override
- public Map initialize(EmbeddedKafkaBroker broker, KafkaProperties kafkaProperties) {
- Map map = new HashMap<>();
- for (String topic : broker.getTopics()) {
- map.put(topic, prepareListener(broker, topic, kafkaProperties));
- }
- return map;
- }
-
- private Consumer prepareListener(EmbeddedKafkaBroker broker, String destination, KafkaProperties kafkaProperties) {
- Map consumerProperties = KafkaTestUtils
- .consumerProps(kafkaProperties.getConsumer().getGroupId(), "false", broker);
-
- // Respect custom key/value deserializers and any additional props under
- // 'spring.kafka.consumer.properties'
- consumerProperties.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG,
- kafkaProperties.getConsumer().getKeyDeserializer());
- consumerProperties.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG,
- kafkaProperties.getConsumer().getValueDeserializer());
- consumerProperties.putAll(kafkaProperties.getConsumer().getProperties());
-
- DefaultKafkaConsumerFactory consumerFactory = new DefaultKafkaConsumerFactory<>(
- consumerProperties);
- Consumer consumer = consumerFactory.createConsumer();
- broker.consumeFromAnEmbeddedTopic(consumer, destination);
- if (log.isDebugEnabled()) {
- log.debug("Prepared consumer for destination [" + destination + "]");
- }
- return consumer;
- }
-
-}
diff --git a/spring-cloud-contract-verifier/src/main/java/org/springframework/cloud/contract/verifier/messaging/kafka/KafkaStubMessages.java b/spring-cloud-contract-verifier/src/main/java/org/springframework/cloud/contract/verifier/messaging/kafka/KafkaStubMessages.java
deleted file mode 100644
index d5b57da11f..0000000000
--- a/spring-cloud-contract-verifier/src/main/java/org/springframework/cloud/contract/verifier/messaging/kafka/KafkaStubMessages.java
+++ /dev/null
@@ -1,171 +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.verifier.messaging.kafka;
-
-import java.time.Duration;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.TimeUnit;
-
-import net.minidev.json.JSONObject;
-import net.minidev.json.parser.JSONParser;
-import net.minidev.json.parser.ParseException;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.kafka.clients.consumer.Consumer;
-import org.apache.kafka.clients.consumer.ConsumerRecord;
-import org.apache.kafka.common.header.Header;
-import org.apache.kafka.common.header.Headers;
-
-import org.springframework.boot.autoconfigure.kafka.KafkaProperties;
-import org.springframework.cloud.contract.verifier.converter.YamlContract;
-import org.springframework.cloud.contract.verifier.messaging.MessageVerifier;
-import org.springframework.kafka.core.KafkaTemplate;
-import org.springframework.kafka.support.KafkaHeaders;
-import org.springframework.kafka.support.converter.MessagingMessageConverter;
-import org.springframework.kafka.test.EmbeddedKafkaBroker;
-import org.springframework.kafka.test.utils.KafkaTestUtils;
-import org.springframework.messaging.Message;
-import org.springframework.messaging.MessageHeaders;
-import org.springframework.messaging.support.MessageBuilder;
-
-class KafkaStubMessages implements MessageVerifier> {
-
- private static final Log log = LogFactory.getLog(KafkaStubMessages.class);
-
- final KafkaTemplate kafkaTemplate;
-
- private final Receiver receiver;
-
- KafkaStubMessages(KafkaTemplate kafkaTemplate, EmbeddedKafkaBroker broker, KafkaProperties kafkaProperties,
- KafkaStubMessagesInitializer initializer) {
- this.kafkaTemplate = kafkaTemplate;
- Map topicToConsumer = initializer.initialize(broker, kafkaProperties);
- this.receiver = new Receiver(topicToConsumer);
- }
-
- @Override
- public void send(Message> message, String destination, YamlContract contract) {
- String defaultTopic = this.kafkaTemplate.getDefaultTopic();
- try {
- this.kafkaTemplate.setDefaultTopic(destination);
- if (log.isDebugEnabled()) {
- log.debug("Will send a message [" + message + "] to destination [" + destination + "]");
- }
- this.kafkaTemplate.send(message).get(5, TimeUnit.SECONDS);
- this.kafkaTemplate.flush();
- }
- catch (Exception ex) {
- throw new IllegalStateException(ex);
- }
- finally {
- this.kafkaTemplate.setDefaultTopic(defaultTopic);
- }
- }
-
- @Override
- public Message receive(String destination, long timeout, TimeUnit timeUnit, YamlContract contract) {
- return this.receiver.receive(destination, timeout, timeUnit, contract);
- }
-
- @Override
- public Message receive(String destination, YamlContract contract) {
- return receive(destination, 5, TimeUnit.SECONDS, contract);
- }
-
- @Override
- public void send(Object payload, Map headers, String destination, YamlContract contract) {
- Message> message = MessageBuilder.createMessage(payload, new MessageHeaders(headers));
- send(message, destination, contract);
- }
-
-}
-
-class Receiver {
-
- private static final Log log = LogFactory.getLog(Receiver.class);
-
- private final MessagingMessageConverter messagingMessageConverter = new MessagingMessageConverter();
-
- private final Map consumers;
-
- Receiver(Map consumers) {
- this.consumers = consumers;
- }
-
- Message receive(String topic, long timeout, TimeUnit timeUnit, YamlContract contract) {
- Consumer consumer = this.consumers.get(topic);
- if (consumer == null) {
- throw new IllegalStateException("No consumer set up for topic [" + topic + "]");
- }
- ConsumerRecord, ?> record = KafkaTestUtils.getSingleRecord(consumer, topic, Duration.ofMillis(timeout));
- if (log.isDebugEnabled()) {
- log.debug("Got a single record for destination [" + topic + "]");
- }
- return toMessage(consumer, record);
- }
-
- Message toMessage(Consumer consumer, ConsumerRecord, ?> record) {
- Map headersMap = toMap(record.headers());
-
- // Leverage spring-kafka to add the headers
- messagingMessageConverter.commonHeaders(null, consumer, headersMap, record.key(), record.topic(),
- record.partition(), record.offset(),
- record.timestampType() != null ? record.timestampType().name() : null, record.timestamp());
- // commonHeaders() maps the record key under 'kafka_receivedMessageKey' - put
- // under 'kafka_messageKey' as well to satisfy both client/server usages as there
- // is not currently a way to set a header name based on client/server
- headersMap.put(KafkaHeaders.KEY, record.key());
-
- // TODO explore using MessagingMessageConverter to do all of the conversion
- // (ideally delete this entire method)
- Object textPayload = record.value();
- // sometimes it's a message sometimes just payload
- if (textPayload instanceof String && ((String) textPayload).contains("payload")
- && ((String) textPayload).contains("headers")) {
- try {
- Object object = new JSONParser(JSONParser.DEFAULT_PERMISSIVE_MODE).parse((String) textPayload);
- JSONObject jo = (JSONObject) object;
- String payload = (String) jo.get("payload");
- JSONObject headersInJson = (JSONObject) jo.get("headers");
- headersMap.putAll(headersInJson);
- return MessageBuilder.createMessage(unquoted(payload), new MessageHeaders(headersMap));
- }
- catch (ParseException ex) {
- throw new IllegalStateException(ex);
- }
- }
- return MessageBuilder.createMessage(unquoted(textPayload), new MessageHeaders(headersMap));
- }
-
- private Map toMap(Headers headers) {
- Map map = new HashMap<>();
- for (Header header : headers) {
- map.put(header.key(), header.value());
- }
- return map;
- }
-
- private Object unquoted(Object value) {
- String textPayload = value instanceof byte[] ? new String((byte[]) value) : value.toString();
- if (textPayload.startsWith("\"") && textPayload.endsWith("\"")) {
- return textPayload.substring(1, textPayload.length() - 1).replace("\\\"", "\"");
- }
- return textPayload;
- }
-
-}
diff --git a/spring-cloud-contract-verifier/src/main/java/org/springframework/cloud/contract/verifier/messaging/kafka/KafkaStubMessagesInitializer.java b/spring-cloud-contract-verifier/src/main/java/org/springframework/cloud/contract/verifier/messaging/kafka/KafkaStubMessagesInitializer.java
deleted file mode 100644
index 1cbe67439b..0000000000
--- a/spring-cloud-contract-verifier/src/main/java/org/springframework/cloud/contract/verifier/messaging/kafka/KafkaStubMessagesInitializer.java
+++ /dev/null
@@ -1,43 +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.verifier.messaging.kafka;
-
-import java.util.Map;
-
-import org.apache.kafka.clients.consumer.Consumer;
-
-import org.springframework.boot.autoconfigure.kafka.KafkaProperties;
-import org.springframework.kafka.test.EmbeddedKafkaBroker;
-
-/**
- * Logic used to initialize {@link KafkaStubMessages}. This interface might have a
- * different implementation for the producer side and for the consumer side. That's
- * because you can't poll for a single message by different consumers.
- *
- * @author Marcin Grzejszczak
- * @since 2.2.0
- */
-public interface KafkaStubMessagesInitializer {
-
- /**
- * @param broker - embedded Kafka broker
- * @param kafkaProperties - kafka properties
- * @return topic to initialized consumer mapping
- */
- Map initialize(EmbeddedKafkaBroker broker, KafkaProperties kafkaProperties);
-
-}
diff --git a/spring-cloud-contract-verifier/src/main/java/org/springframework/cloud/contract/verifier/messaging/noop/NoOpContractVerifierAutoConfiguration.java b/spring-cloud-contract-verifier/src/main/java/org/springframework/cloud/contract/verifier/messaging/noop/NoOpContractVerifierAutoConfiguration.java
index cac30e2962..04b8d27e4d 100644
--- a/spring-cloud-contract-verifier/src/main/java/org/springframework/cloud/contract/verifier/messaging/noop/NoOpContractVerifierAutoConfiguration.java
+++ b/spring-cloud-contract-verifier/src/main/java/org/springframework/cloud/contract/verifier/messaging/noop/NoOpContractVerifierAutoConfiguration.java
@@ -22,6 +22,8 @@ import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.AutoConfigureOrder;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.cloud.contract.verifier.messaging.MessageVerifier;
+import org.springframework.cloud.contract.verifier.messaging.MessageVerifierReceiver;
+import org.springframework.cloud.contract.verifier.messaging.MessageVerifierSender;
import org.springframework.cloud.contract.verifier.messaging.internal.ContractVerifierMessaging;
import org.springframework.cloud.contract.verifier.messaging.internal.ContractVerifierObjectMapper;
import org.springframework.context.annotation.Bean;
@@ -39,14 +41,14 @@ public class NoOpContractVerifierAutoConfiguration {
@Bean
@ConditionalOnMissingBean(MessageVerifier.class)
- public MessageVerifier> contractVerifierMessageExchange() {
+ public NoOpStubMessages contractVerifierMessageExchange() {
return new NoOpStubMessages();
}
@Bean
@ConditionalOnMissingBean(ContractVerifierMessaging.class)
- public ContractVerifierMessaging> contractVerifierMessaging(MessageVerifier> exchange) {
- return new ContractVerifierMessaging<>(exchange);
+ public ContractVerifierMessaging
-
- junit
- junit
- test
-
-
- org.apache.groovy
- groovy
-
org.spockframework
spock-core
test
-
- org.spockframework
- spock-spring
- test
-
org.springframework.boot
spring-boot-starter-test
@@ -60,11 +46,6 @@
camel-activemq
test
-
- org.apache.activemq
- activemq-pool
- test
-
org.springframework.boot
spring-boot-starter-web
diff --git a/tests/spring-cloud-contract-stub-runner-camel/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy b/tests/spring-cloud-contract-stub-runner-camel/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy
deleted file mode 100644
index 71e254a0bd..0000000000
--- a/tests/spring-cloud-contract-stub-runner-camel/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy
+++ /dev/null
@@ -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[]
-}
diff --git a/tests/spring-cloud-contract-stub-runner-jms/pom.xml b/tests/spring-cloud-contract-stub-runner-jms/pom.xml
index fbc018143e..40f76b55e7 100644
--- a/tests/spring-cloud-contract-stub-runner-jms/pom.xml
+++ b/tests/spring-cloud-contract-stub-runner-jms/pom.xml
@@ -14,38 +14,24 @@
Spring Cloud Contract Stub Runner JMS
Spring Cloud Contract Stub Runner JMS
+
+ org.springframework.boot
+ spring-boot-starter-artemis
+
+
+ org.apache.activemq
+ artemis-jms-server
+
org.springframework.cloud
spring-cloud-contract-stub-runner
-
-
- org.springframework.cloud
- spring-cloud-starter-contract-stub-runner-jetty
test
-
- org.springframework.boot
- spring-boot-starter-activemq
-
-
- junit
- junit
- test
-
-
- org.apache.groovy
- groovy
-
org.spockframework
spock-core
test
-
- org.spockframework
- spock-spring
- test
-
org.springframework.boot
spring-boot-starter-test
diff --git a/tests/spring-cloud-contract-stub-runner-jms/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/jms/JmsStubRunnerSpec.groovy b/tests/spring-cloud-contract-stub-runner-jms/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/jms/JmsStubRunnerSpec.groovy
index 5cc194286c..633fb44ec4 100644
--- a/tests/spring-cloud-contract-stub-runner-jms/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/jms/JmsStubRunnerSpec.groovy
+++ b/tests/spring-cloud-contract-stub-runner-jms/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/jms/JmsStubRunnerSpec.groovy
@@ -16,24 +16,23 @@
package org.springframework.cloud.contract.stubrunner.messaging.jms
-import javax.jms.JMSException
-import javax.jms.Message
-import javax.jms.TextMessage
-
import groovy.json.JsonOutput
import groovy.json.JsonSlurper
-import org.apache.activemq.ActiveMQConnectionFactory
-import spock.lang.IgnoreIf
-import spock.lang.Specification
+import jakarta.jms.JMSException
+import jakarta.jms.Message
+import jakarta.jms.TextMessage
+import org.assertj.core.api.BDDAssertions
+import org.junit.jupiter.api.AfterEach
+import org.junit.jupiter.api.Test
+import org.junit.jupiter.api.condition.DisabledOnOs
+import org.junit.jupiter.api.condition.OS
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.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.jms.annotation.EnableJms
@@ -44,21 +43,23 @@ import org.springframework.jms.core.MessagePostProcessor
*/
@SpringBootTest(classes = Config, properties = ["debug=true"])
@AutoConfigureStubRunner
-@IgnoreIf({ os.windows })
-class JmsStubRunnerSpec extends Specification {
+@DisabledOnOs(OS.WINDOWS)
+class JmsStubRunnerSpec {
@Autowired
StubFinder stubFinder
@Autowired
JmsTemplate jmsTemplate
- def cleanup() {
+ @AfterEach
+ void cleanup() {
// ensure that message were taken from the queue
jmsTemplate.receive('output')
jmsTemplate.receive('input')
}
- def 'should download the stub and register a route for it'() {
+ @Test
+ void 'should download the stub and register a route for it'() {
when:
// tag::client_send[]
jmsTemplate.
@@ -76,13 +77,14 @@ class JmsStubRunnerSpec extends Specification {
// end::client_receive[]
and:
// tag::client_receive_message[]
- receivedMessage != null
- assertThatBodyContainsBookNameFoo(receivedMessage.getText())
- receivedMessage.getStringProperty('BOOK-NAME') == 'foo'
+ assert receivedMessage != null
+ assert assertThatBodyContainsBookNameFoo(receivedMessage.getText())
+ assert receivedMessage.getStringProperty('BOOKNAME') == 'foo'
// end::client_receive_message[]
}
- def 'should trigger a message by label'() {
+ @Test
+ void 'should trigger a message by label'() {
when:
// tag::client_trigger[]
stubFinder.trigger('return_book_1')
@@ -93,13 +95,14 @@ class JmsStubRunnerSpec extends Specification {
// end::client_trigger_receive[]
and:
// tag::client_trigger_message[]
- receivedMessage != null
- assertThatBodyContainsBookNameFoo(receivedMessage.getText())
- receivedMessage.getStringProperty('BOOK-NAME') == 'foo'
+ assert receivedMessage != null
+ assert assertThatBodyContainsBookNameFoo(receivedMessage.getText())
+ assert receivedMessage.getStringProperty('BOOKNAME') == 'foo'
// end::client_trigger_message[]
}
- def 'should trigger a label for the existing groupId:artifactId'() {
+ @Test
+ void 'should trigger a label for the existing groupId:artifactId'() {
when:
// tag::trigger_group_artifact[]
stubFinder.
@@ -108,12 +111,13 @@ class JmsStubRunnerSpec extends Specification {
then:
TextMessage receivedMessage = (TextMessage) jmsTemplate.receive('output')
and:
- receivedMessage != null
- assertThatBodyContainsBookNameFoo(receivedMessage.getText())
- receivedMessage.getStringProperty('BOOK-NAME') == 'foo'
+ assert receivedMessage != null
+ assert assertThatBodyContainsBookNameFoo(receivedMessage.getText())
+ assert receivedMessage.getStringProperty('BOOKNAME') == 'foo'
}
- def 'should trigger a label for the existing artifactId'() {
+ @Test
+ void 'should trigger a label for the existing artifactId'() {
when:
// tag::trigger_artifact[]
stubFinder.trigger('stubs', 'return_book_1')
@@ -121,26 +125,25 @@ class JmsStubRunnerSpec extends Specification {
then:
TextMessage receivedMessage = (TextMessage) jmsTemplate.receive('output')
and:
- receivedMessage != null
- assertThatBodyContainsBookNameFoo(receivedMessage.getText())
- receivedMessage.getStringProperty('BOOK-NAME') == 'foo'
+ assert receivedMessage != null
+ assert assertThatBodyContainsBookNameFoo(receivedMessage.getText())
+ assert receivedMessage.getStringProperty('BOOKNAME') == 'foo'
}
- def 'should throw an exception when missing label is passed'() {
+ @Test
+ void 'should throw an exception when missing label is passed'() {
when:
- stubFinder.trigger('missing label')
- then:
- thrown(IllegalArgumentException)
+ BDDAssertions.thenThrownBy(() -> stubFinder.trigger('missing label')).isInstanceOf(IllegalArgumentException)
}
- def 'should throw an exception when missing label and artifactid is passed'() {
+ @Test
+ void 'should throw an exception when missing label and artifactid is passed'() {
when:
- stubFinder.trigger('some:service', 'return_book_1')
- then:
- thrown(IllegalArgumentException)
+ BDDAssertions.thenThrownBy(() -> stubFinder.trigger('some:service', 'return_book_1')).isInstanceOf(IllegalArgumentException)
}
- def 'should trigger messages by running all triggers'() {
+ @Test
+ void 'should trigger messages by running all triggers'() {
when:
// tag::trigger_all[]
stubFinder.trigger()
@@ -148,12 +151,13 @@ class JmsStubRunnerSpec extends Specification {
then:
TextMessage receivedMessage = (TextMessage) jmsTemplate.receive('output')
and:
- receivedMessage != null
- assertThatBodyContainsBookNameFoo(receivedMessage.getText())
- receivedMessage.getStringProperty('BOOK-NAME') == 'foo'
+ assert receivedMessage != null
+ assert assertThatBodyContainsBookNameFoo(receivedMessage.getText())
+ assert receivedMessage.getStringProperty('BOOKNAME') == 'foo'
}
- def 'should trigger a label with no output message'() {
+ @Test
+ void 'should trigger a label with no output message'() {
when:
// tag::trigger_no_output[]
jmsTemplate.
@@ -165,11 +169,10 @@ class JmsStubRunnerSpec extends Specification {
}
})
// end::trigger_no_output[]
- then:
- noExceptionThrown()
}
- def 'should not trigger a message that does not match input'() {
+ @Test
+ void 'should not trigger a message that does not match input'() {
when:
jmsTemplate.
convertAndSend('input', new BookReturned('notmatching'), new MessagePostProcessor() {
@@ -182,7 +185,7 @@ class JmsStubRunnerSpec extends Specification {
then:
TextMessage receivedMessage = (TextMessage) jmsTemplate.receive('output')
and:
- receivedMessage == null
+ assert receivedMessage == null
}
private boolean assertThatBodyContainsBookNameFoo(Object payload) {
@@ -197,16 +200,7 @@ class JmsStubRunnerSpec extends Specification {
@EnableAutoConfiguration
@EnableJms
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
- }
+
}
Contract dsl =
@@ -220,7 +214,7 @@ class JmsStubRunnerSpec extends Specification {
sentTo('output')
body('''{ "bookName" : "foo" }''')
headers {
- header('BOOK-NAME', 'foo')
+ header('BOOKNAME', 'foo')
}
}
}
@@ -245,7 +239,7 @@ class JmsStubRunnerSpec extends Specification {
bookName: 'foo'
])
headers {
- header('BOOK-NAME', 'foo')
+ header('BOOKNAME', 'foo')
}
}
}
diff --git a/tests/spring-cloud-contract-stub-runner-jms/src/test/resources/stubs/bookReturned1.groovy b/tests/spring-cloud-contract-stub-runner-jms/src/test/resources/stubs/bookReturned1.groovy
index 0094bc7b1d..7fc403e12f 100644
--- a/tests/spring-cloud-contract-stub-runner-jms/src/test/resources/stubs/bookReturned1.groovy
+++ b/tests/spring-cloud-contract-stub-runner-jms/src/test/resources/stubs/bookReturned1.groovy
@@ -7,7 +7,7 @@ org.springframework.cloud.contract.spec.Contract.make {
sentTo('output')
body('''{ "bookName" : "foo" }''')
headers {
- header('BOOK-NAME', 'foo')
+ header('BOOKNAME', 'foo')
}
}
-}
\ No newline at end of file
+}
diff --git a/tests/spring-cloud-contract-stub-runner-jms/src/test/resources/stubs/bookReturned2.groovy b/tests/spring-cloud-contract-stub-runner-jms/src/test/resources/stubs/bookReturned2.groovy
index e0d53098d5..0f568e0d8d 100644
--- a/tests/spring-cloud-contract-stub-runner-jms/src/test/resources/stubs/bookReturned2.groovy
+++ b/tests/spring-cloud-contract-stub-runner-jms/src/test/resources/stubs/bookReturned2.groovy
@@ -15,7 +15,7 @@ org.springframework.cloud.contract.spec.Contract.make {
bookName: 'foo'
])
headers {
- header('BOOK-NAME', 'foo')
+ header('BOOKNAME', 'foo')
}
}
-}
\ No newline at end of file
+}
diff --git a/tests/spring-cloud-contract-stub-runner-kafka/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/kafka/KafkaStubRunnerSpec.groovy b/tests/spring-cloud-contract-stub-runner-kafka/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/kafka/KafkaStubRunnerSpec.groovy
index f661e097c1..2160bb0d83 100644
--- a/tests/spring-cloud-contract-stub-runner-kafka/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/kafka/KafkaStubRunnerSpec.groovy
+++ b/tests/spring-cloud-contract-stub-runner-kafka/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/kafka/KafkaStubRunnerSpec.groovy
@@ -27,6 +27,7 @@ import org.assertj.core.api.BDDAssertions
import org.awaitility.Awaitility
import org.junit.jupiter.api.AfterEach
import org.junit.jupiter.api.BeforeEach
+import org.junit.jupiter.api.Disabled
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.condition.DisabledOnOs
import org.junit.jupiter.api.condition.OS
@@ -55,6 +56,7 @@ import org.springframework.stereotype.Component
@DisabledOnOs(value = OS.WINDOWS)
@EmbeddedKafka(topics = ["input", "input2", "output", "delete"])
@Commons
+@Disabled("TODO: Migrate to middleware based approach")
class KafkaStubRunnerSpec {
@Autowired