Merged camel routes into a single one for multiple contracts for the same exchange; fixes gh-791
This commit is contained in:
@@ -16,17 +16,27 @@
|
||||
|
||||
package org.springframework.cloud.contract.stubrunner.messaging.camel;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.camel.Exchange;
|
||||
import org.apache.camel.Processor;
|
||||
import org.apache.camel.RoutesBuilder;
|
||||
import org.apache.camel.spring.SpringRouteBuilder;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
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.context.annotation.*;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Camel configuration that iterates over the downloaded Groovy DSLs and registers a route
|
||||
@@ -39,6 +49,8 @@ import java.util.Map;
|
||||
@ConditionalOnProperty(name = "stubrunner.camel.enabled", havingValue = "true", matchIfMissing = true)
|
||||
public class StubRunnerCamelConfiguration {
|
||||
|
||||
static final String STUBRUNNER_DESTINATION_URL_HEADER_NAME = "STUBRUNNER_DESTINATION_URL";
|
||||
|
||||
@Bean
|
||||
public RoutesBuilder myRouter(final BatchStubRunner batchStubRunner) {
|
||||
return new SpringRouteBuilder() {
|
||||
@@ -46,21 +58,49 @@ public class StubRunnerCamelConfiguration {
|
||||
public void configure() throws Exception {
|
||||
Map<StubConfiguration, Collection<Contract>> contracts = batchStubRunner
|
||||
.getContracts();
|
||||
for (Collection<Contract> list : contracts.values()) {
|
||||
for (Contract it : list) {
|
||||
if (it.getInput() != null
|
||||
&& it.getInput().getMessageFrom() != null
|
||||
&& it.getOutputMessage() != null
|
||||
&& it.getOutputMessage().getSentTo() != null) {
|
||||
from(it.getInput().getMessageFrom().getClientValue())
|
||||
.filter(new StubRunnerCamelPredicate(it))
|
||||
.process(new StubRunnerCamelProcessor(it))
|
||||
.to(it.getOutputMessage().getSentTo()
|
||||
.getClientValue());
|
||||
for (Map.Entry<StubConfiguration, Collection<Contract>> entry : contracts
|
||||
.entrySet()) {
|
||||
Collection<Contract> value = entry.getValue();
|
||||
MultiValueMap<String, Contract> map = new LinkedMultiValueMap<>();
|
||||
for (Contract dsl : value) {
|
||||
if (dsl == null) {
|
||||
continue;
|
||||
}
|
||||
if (dsl.getInput() != null && dsl.getInput()
|
||||
.getMessageFrom() != null
|
||||
&& StringUtils.hasText(
|
||||
dsl.getInput().getMessageFrom().getClientValue())) {
|
||||
String from = dsl.getInput().getMessageFrom()
|
||||
.getClientValue();
|
||||
map.add(from, dsl);
|
||||
}
|
||||
}
|
||||
for (Map.Entry<String, List<Contract>> entries : map.entrySet()) {
|
||||
from(entries.getKey())
|
||||
.filter(new StubRunnerCamelPredicate(entries.getValue()))
|
||||
.process(new StubRunnerCamelProcessor())
|
||||
.dynamicRouter(header(StubRunnerCamelConfiguration.STUBRUNNER_DESTINATION_URL_HEADER_NAME));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@Bean DummyProcessor dummyStubRunnerProcessor() {
|
||||
return new DummyProcessor();
|
||||
}
|
||||
}
|
||||
|
||||
private static class DummyProcessor implements Processor {
|
||||
|
||||
private static final Log log = LogFactory.getLog(DummyProcessor.class);
|
||||
|
||||
@Override
|
||||
public void process(Exchange exchange) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Got exchange [" + exchange + "]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package org.springframework.cloud.contract.stubrunner.messaging.camel;
|
||||
|
||||
import org.springframework.cloud.contract.spec.Contract;
|
||||
|
||||
/**
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
class StubRunnerCamelPayload {
|
||||
final Object payload;
|
||||
final Contract contract;
|
||||
|
||||
StubRunnerCamelPayload(Contract contract) {
|
||||
this.contract = contract;
|
||||
this.payload = null;
|
||||
}
|
||||
}
|
||||
@@ -16,25 +16,30 @@
|
||||
|
||||
package org.springframework.cloud.contract.stubrunner.messaging.camel;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.apache.camel.Exchange;
|
||||
import org.apache.camel.Predicate;
|
||||
import org.springframework.cloud.contract.spec.Contract;
|
||||
import org.springframework.cloud.contract.spec.internal.BodyMatcher;
|
||||
import org.springframework.cloud.contract.spec.internal.BodyMatchers;
|
||||
import org.springframework.cloud.contract.spec.internal.Header;
|
||||
import org.springframework.cloud.contract.verifier.util.MapConverter;
|
||||
import org.springframework.cloud.contract.verifier.messaging.internal.ContractVerifierObjectMapper;
|
||||
import org.springframework.cloud.contract.verifier.util.JsonPaths;
|
||||
import org.springframework.cloud.contract.verifier.util.JsonToJsonPathsConverter;
|
||||
import org.springframework.cloud.contract.verifier.util.MethodBufferingJsonVerifiable;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.jayway.jsonpath.DocumentContext;
|
||||
import com.jayway.jsonpath.JsonPath;
|
||||
import com.toomuchcoding.jsonassert.JsonAssertion;
|
||||
import org.apache.camel.Exchange;
|
||||
import org.apache.camel.Message;
|
||||
import org.apache.camel.Predicate;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.cloud.contract.spec.Contract;
|
||||
import org.springframework.cloud.contract.spec.internal.BodyMatcher;
|
||||
import org.springframework.cloud.contract.spec.internal.BodyMatchers;
|
||||
import org.springframework.cloud.contract.spec.internal.Header;
|
||||
import org.springframework.cloud.contract.verifier.messaging.internal.ContractVerifierObjectMapper;
|
||||
import org.springframework.cloud.contract.verifier.util.JsonPaths;
|
||||
import org.springframework.cloud.contract.verifier.util.JsonToJsonPathsConverter;
|
||||
import org.springframework.cloud.contract.verifier.util.MapConverter;
|
||||
import org.springframework.cloud.contract.verifier.util.MethodBufferingJsonVerifiable;
|
||||
|
||||
/**
|
||||
* Passes through a message that matches the one defined in the DSL
|
||||
@@ -43,50 +48,55 @@ import com.toomuchcoding.jsonassert.JsonAssertion;
|
||||
*/
|
||||
class StubRunnerCamelPredicate implements Predicate {
|
||||
|
||||
private final Contract groovyDsl;
|
||||
private static final Log log = LogFactory.getLog(StubRunnerCamelPredicate.class);
|
||||
|
||||
private final List<Contract> groovyDsls;
|
||||
private final ContractVerifierObjectMapper objectMapper = new ContractVerifierObjectMapper();
|
||||
|
||||
public StubRunnerCamelPredicate(Contract groovyDsl) {
|
||||
this.groovyDsl = groovyDsl;
|
||||
public StubRunnerCamelPredicate(List<Contract> groovyDsls) {
|
||||
this.groovyDsls = groovyDsls;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(Exchange exchange) {
|
||||
if (!headersMatch(exchange.getIn().getHeaders())) {
|
||||
Contract contract = getContract(exchange.getMessage());
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("For exchange [" + exchange + "] found contract [" + contract + "]");
|
||||
}
|
||||
if (contract == null) {
|
||||
return false;
|
||||
}
|
||||
Object inputMessage = exchange.getIn().getBody();
|
||||
BodyMatchers matchers = this.groovyDsl.getInput().getBodyMatchers();
|
||||
Object dslBody = MapConverter.getStubSideValues(this.groovyDsl.getInput().getMessageBody());
|
||||
|
||||
DocumentContext parsedJson = deserialize(inputMessage);
|
||||
return matchMessage(matchers, dslBody, parsedJson);
|
||||
exchange.getIn().setBody(new StubRunnerCamelPayload(contract));
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean matchMessage(BodyMatchers matchers, Object dslBody, DocumentContext parsedJson) {
|
||||
boolean matches = true;
|
||||
JsonPaths jsonPaths = getJsonPaths(matchers, dslBody);
|
||||
for (MethodBufferingJsonVerifiable path : jsonPaths) {
|
||||
matches &= matchesJsonPath(parsedJson, path.jsonPath());
|
||||
}
|
||||
if (matchers != null && matchers.hasMatchers()) {
|
||||
for (BodyMatcher matcher : matchers.jsonPathMatchers()) {
|
||||
String jsonPath = JsonToJsonPathsConverter.convertJsonPathAndRegexToAJsonPath(matcher, dslBody);
|
||||
matches &= matchesJsonPath(parsedJson, jsonPath);
|
||||
private Contract getContract(Message message) {
|
||||
for (Contract groovyDsl : this.groovyDsls) {
|
||||
Contract contract = matchContract(message, groovyDsl);
|
||||
if (contract != null) {
|
||||
return contract;
|
||||
}
|
||||
}
|
||||
return matches;
|
||||
return null;
|
||||
}
|
||||
|
||||
private JsonPaths getJsonPaths(BodyMatchers matchers, Object dslBody) {
|
||||
private Contract matchContract(Message message, Contract groovyDsl) {
|
||||
List<String> unmatchedHeaders = headersMatch(message, groovyDsl);
|
||||
if (!unmatchedHeaders.isEmpty()) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Contract [" + groovyDsl
|
||||
+ "] hasn't matched the following headers " + unmatchedHeaders);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
Object inputMessage = message.getBody();
|
||||
BodyMatchers matchers = groovyDsl.getInput().getBodyMatchers();
|
||||
Object dslBody = MapConverter.getStubSideValues(groovyDsl.getInput().getMessageBody());
|
||||
Object matchingInputMessage = JsonToJsonPathsConverter
|
||||
.removeMatchingJsonPaths(dslBody, matchers);
|
||||
return JsonToJsonPathsConverter
|
||||
JsonPaths jsonPaths = JsonToJsonPathsConverter
|
||||
.transformToJsonPathWithStubsSideValuesAndNoArraySizeCheck(
|
||||
matchingInputMessage);
|
||||
}
|
||||
|
||||
private DocumentContext deserialize(Object inputMessage) {
|
||||
DocumentContext parsedJson;
|
||||
try {
|
||||
parsedJson = JsonPath
|
||||
@@ -95,32 +105,72 @@ class StubRunnerCamelPredicate implements Predicate {
|
||||
catch (JsonProcessingException e) {
|
||||
throw new IllegalStateException("Cannot serialize to JSON", e);
|
||||
}
|
||||
return parsedJson;
|
||||
List<String> unmatchedJsonPath = new ArrayList<>();
|
||||
boolean matches = true;
|
||||
for (MethodBufferingJsonVerifiable path : jsonPaths) {
|
||||
matches &= matchesJsonPath(unmatchedJsonPath, parsedJson, path.jsonPath());
|
||||
}
|
||||
if (matchers != null && matchers.hasMatchers()) {
|
||||
for (BodyMatcher matcher : matchers.jsonPathMatchers()) {
|
||||
String jsonPath = JsonToJsonPathsConverter
|
||||
.convertJsonPathAndRegexToAJsonPath(matcher, dslBody);
|
||||
matches &= matchesJsonPath(unmatchedJsonPath, parsedJson, jsonPath);
|
||||
}
|
||||
}
|
||||
if (!unmatchedJsonPath.isEmpty()) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Contract [" + groovyDsl + "] didn't much the body due to "
|
||||
+ unmatchedJsonPath);
|
||||
}
|
||||
}
|
||||
if (matches) {
|
||||
return groovyDsl;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean matchesJsonPath(DocumentContext parsedJson, String jsonPath) {
|
||||
private boolean matchesJsonPath(List<String> unmatchedJsonPath,
|
||||
DocumentContext parsedJson, String jsonPath) {
|
||||
try {
|
||||
JsonAssertion.assertThat(parsedJson).matchesJsonPath(jsonPath);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
}
|
||||
catch (Exception e) {
|
||||
unmatchedJsonPath.add(e.getLocalizedMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean headersMatch(Map<String, Object> headers) {
|
||||
boolean matches = true;
|
||||
for (Header it : this.groovyDsl.getInput().getMessageHeaders().getEntries()) {
|
||||
private List<String> headersMatch(Message message, Contract groovyDsl) {
|
||||
List<String> unmatchedHeaders = new ArrayList<>();
|
||||
Map<String, Object> headers = message.getHeaders();
|
||||
for (Header it : groovyDsl.getInput().getMessageHeaders().getEntries()) {
|
||||
String name = it.getName();
|
||||
Object value = it.getClientValue();
|
||||
Object valueInHeader = headers.get(name);
|
||||
matches &= matchValue(value, valueInHeader);
|
||||
boolean matches;
|
||||
if (value instanceof Pattern) {
|
||||
Pattern pattern = (Pattern) value;
|
||||
matches = pattern.matcher(valueInHeader.toString()).matches();
|
||||
}
|
||||
else {
|
||||
matches = valueInHeader != null
|
||||
&& valueInHeader.toString().equals(value.toString());
|
||||
}
|
||||
if (!matches) {
|
||||
unmatchedHeaders.add("Header with name [" + name + "] was supposed to "
|
||||
+ unmatchedText(value) + " but the value is ["
|
||||
+ (valueInHeader != null ? valueInHeader.toString() : "null")
|
||||
+ "]");
|
||||
}
|
||||
}
|
||||
return matches;
|
||||
return unmatchedHeaders;
|
||||
}
|
||||
|
||||
private boolean matchValue(Object value, Object valueInHeader) {
|
||||
return value instanceof Pattern ?
|
||||
((Pattern) value).matcher(valueInHeader.toString()).matches() :
|
||||
valueInHeader!=null && valueInHeader.equals(value);
|
||||
private String unmatchedText(Object expectedValue) {
|
||||
return expectedValue instanceof Pattern
|
||||
? "match pattern [" + ((Pattern) expectedValue).pattern() + "]"
|
||||
: "be equal to [" + expectedValue + "]";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,12 +16,15 @@
|
||||
|
||||
package org.springframework.cloud.contract.stubrunner.messaging.camel;
|
||||
|
||||
import org.springframework.cloud.contract.verifier.util.BodyExtractor;
|
||||
import org.apache.camel.Exchange;
|
||||
import org.apache.camel.Message;
|
||||
import org.apache.camel.Processor;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.cloud.contract.spec.Contract;
|
||||
import org.springframework.cloud.contract.spec.internal.Header;
|
||||
import org.springframework.cloud.contract.verifier.util.BodyExtractor;
|
||||
|
||||
/**
|
||||
* Sends forward a message defined in the DSL. Also removes headers from the input message
|
||||
@@ -31,29 +34,45 @@ import org.springframework.cloud.contract.spec.internal.Header;
|
||||
*/
|
||||
class StubRunnerCamelProcessor implements Processor {
|
||||
|
||||
private final Contract groovyDsl;
|
||||
private static final Log log = LogFactory.getLog(StubRunnerCamelProcessor.class);
|
||||
|
||||
StubRunnerCamelProcessor(Contract groovyDsl) {
|
||||
this.groovyDsl = groovyDsl;
|
||||
}
|
||||
private static final String DUMMY_BEAN_URL = "bean:dummyStubRunnerProcessor";
|
||||
|
||||
@Override
|
||||
public void process(Exchange exchange) throws Exception {
|
||||
public void process(Exchange exchange) {
|
||||
Message input = exchange.getIn();
|
||||
if (this.groovyDsl.getInput().getMessageHeaders() != null) {
|
||||
for (Header entry : this.groovyDsl.getInput().getMessageHeaders().getEntries()) {
|
||||
StubRunnerCamelPayload body = input.getBody(StubRunnerCamelPayload.class);
|
||||
Contract groovyDsl = body.contract;
|
||||
setStubRunnerDestinationHeader(exchange, body);
|
||||
if (groovyDsl.getInput().getMessageHeaders() != null) {
|
||||
for (Header entry : groovyDsl.getInput().getMessageHeaders().getEntries()) {
|
||||
input.removeHeader(entry.getName());
|
||||
}
|
||||
}
|
||||
if (this.groovyDsl.getOutputMessage() == null) {
|
||||
if (groovyDsl.getOutputMessage() == null) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("No output message provided, will not modify the body");
|
||||
}
|
||||
return;
|
||||
}
|
||||
input.setBody(BodyExtractor
|
||||
.extractStubValueFrom(this.groovyDsl.getOutputMessage().getBody()));
|
||||
if (this.groovyDsl.getOutputMessage().getHeaders() != null) {
|
||||
for (Header entry : this.groovyDsl.getOutputMessage().getHeaders().getEntries()) {
|
||||
.extractStubValueFrom(groovyDsl.getOutputMessage().getBody()));
|
||||
if (groovyDsl.getOutputMessage().getHeaders() != null) {
|
||||
for (Header entry : groovyDsl.getOutputMessage().getHeaders().getEntries()) {
|
||||
input.setHeader(entry.getName(), entry.getClientValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void setStubRunnerDestinationHeader(Exchange exchange, StubRunnerCamelPayload body) {
|
||||
boolean outputPart = body.contract.getOutputMessage() != null;
|
||||
String url = DUMMY_BEAN_URL;
|
||||
if (outputPart && body.contract.getOutputMessage().getSentTo() != null) {
|
||||
url = body.contract.getOutputMessage().getSentTo().getClientValue();
|
||||
}
|
||||
exchange.getIn().setHeader(StubRunnerCamelConfiguration.STUBRUNNER_DESTINATION_URL_HEADER_NAME, url);
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Set stub runner destination header to [" + url + "]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,10 @@ package org.springframework.cloud.contract.stubrunner.messaging.camel
|
||||
|
||||
import org.apache.camel.Exchange
|
||||
import org.apache.camel.Message
|
||||
import org.apache.camel.impl.DefaultCamelContext
|
||||
import org.apache.camel.impl.DefaultExchange
|
||||
import org.apache.camel.impl.DefaultMessage
|
||||
|
||||
import org.springframework.cloud.contract.spec.Contract
|
||||
import spock.lang.Specification
|
||||
|
||||
@@ -9,8 +13,8 @@ import spock.lang.Specification
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
class StubRunnerCamelPredicateSpec extends Specification {
|
||||
Exchange exchange = Stub(Exchange)
|
||||
Message message = Stub(Message)
|
||||
Exchange exchange = new DefaultExchange(new DefaultCamelContext())
|
||||
Message message = new DefaultMessage()
|
||||
|
||||
def "should return false if headers don't match"() {
|
||||
given:
|
||||
@@ -24,9 +28,9 @@ class StubRunnerCamelPredicateSpec extends Specification {
|
||||
}
|
||||
}
|
||||
and:
|
||||
StubRunnerCamelPredicate predicate = new StubRunnerCamelPredicate(dsl)
|
||||
exchange.in >> message
|
||||
message.headers >> [
|
||||
StubRunnerCamelPredicate predicate = new StubRunnerCamelPredicate([dsl])
|
||||
exchange.in = message
|
||||
message.headers = [
|
||||
foo: "non matching stuff"
|
||||
]
|
||||
expect:
|
||||
@@ -45,12 +49,12 @@ class StubRunnerCamelPredicateSpec extends Specification {
|
||||
}
|
||||
}
|
||||
and:
|
||||
StubRunnerCamelPredicate predicate = new StubRunnerCamelPredicate(dsl)
|
||||
exchange.in >> message
|
||||
message.headers >> [
|
||||
StubRunnerCamelPredicate predicate = new StubRunnerCamelPredicate([dsl])
|
||||
exchange.in = message
|
||||
message.headers = [
|
||||
foo: 123
|
||||
]
|
||||
message.body >> [
|
||||
message.body = [
|
||||
foo: "non matching stuff"
|
||||
]
|
||||
expect:
|
||||
@@ -66,13 +70,13 @@ class StubRunnerCamelPredicateSpec extends Specification {
|
||||
header("foo", 123)
|
||||
}
|
||||
messageBody(foo: "non matching stuff")
|
||||
stubMatchers {
|
||||
bodyMatchers {
|
||||
jsonPath('$.foo', byRegex("[0-9]{3}"))
|
||||
}
|
||||
}
|
||||
}
|
||||
and:
|
||||
StubRunnerCamelPredicate predicate = new StubRunnerCamelPredicate(dsl)
|
||||
StubRunnerCamelPredicate predicate = new StubRunnerCamelPredicate([dsl])
|
||||
exchange.in >> message
|
||||
message.headers >> [
|
||||
foo: 123
|
||||
@@ -92,22 +96,21 @@ class StubRunnerCamelPredicateSpec extends Specification {
|
||||
header("foo", 123)
|
||||
}
|
||||
messageBody(foo: $(c(regex("[0-9]{3}")), p(123)))
|
||||
|
||||
}
|
||||
}
|
||||
and:
|
||||
StubRunnerCamelPredicate predicate = new StubRunnerCamelPredicate(dsl)
|
||||
exchange.in >> message
|
||||
message.headers >> [
|
||||
StubRunnerCamelPredicate predicate = new StubRunnerCamelPredicate([dsl])
|
||||
exchange.in = message
|
||||
message.headers = [
|
||||
foo: 123
|
||||
]
|
||||
message.body >> [
|
||||
message.body = [
|
||||
foo: 123
|
||||
]
|
||||
expect:
|
||||
predicate.matches(exchange)
|
||||
|
||||
}
|
||||
|
||||
def "should return true if headers and body using matchers match"() {
|
||||
given:
|
||||
Contract dsl = Contract.make {
|
||||
@@ -123,12 +126,12 @@ class StubRunnerCamelPredicateSpec extends Specification {
|
||||
}
|
||||
}
|
||||
and:
|
||||
StubRunnerCamelPredicate predicate = new StubRunnerCamelPredicate(dsl)
|
||||
exchange.in >> message
|
||||
message.headers >> [
|
||||
StubRunnerCamelPredicate predicate = new StubRunnerCamelPredicate([dsl])
|
||||
exchange.in = message
|
||||
message.headers = [
|
||||
foo: 123
|
||||
]
|
||||
message.body >> [
|
||||
message.body = [
|
||||
foo: 123
|
||||
]
|
||||
expect:
|
||||
|
||||
@@ -21,8 +21,14 @@ import groovy.json.JsonSlurper
|
||||
import org.apache.activemq.camel.component.ActiveMQComponent
|
||||
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.jms.JmsConfiguration
|
||||
import org.apache.camel.impl.DefaultShutdownStrategy
|
||||
import spock.lang.IgnoreIf
|
||||
import spock.lang.Specification
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import org.springframework.beans.factory.annotation.Value
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration
|
||||
@@ -34,34 +40,47 @@ import org.springframework.cloud.contract.stubrunner.spring.AutoConfigureStubRun
|
||||
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
|
||||
import spock.lang.IgnoreIf
|
||||
import spock.lang.Specification
|
||||
/**
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
@ContextConfiguration(classes = Config, loader = SpringBootContextLoader)
|
||||
@SpringBootTest(properties = "debug=true")
|
||||
@AutoConfigureStubRunner
|
||||
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
|
||||
@IgnoreIf({ os.windows })
|
||||
class CamelStubRunnerSpec extends Specification {
|
||||
|
||||
@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
|
||||
camelContext.createConsumerTemplate().receive('jms:output', 100)
|
||||
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 download the stub and register a route for it'() {
|
||||
when:
|
||||
// tag::client_send[]
|
||||
camelContext.createProducerTemplate().sendBodyAndHeaders('jms:input', new BookReturned('foo'), [sample: 'header'])
|
||||
producerTemplate.sendBodyAndHeaders('jms:input', new BookReturned('foo'), [sample: 'header'])
|
||||
// end::client_send[]
|
||||
then:
|
||||
// tag::client_receive[]
|
||||
Exchange receivedMessage = camelContext.createConsumerTemplate().receive('jms:output', 5000)
|
||||
Exchange receivedMessage = consumerTemplate.receive('jms:output', 5000)
|
||||
// end::client_receive[]
|
||||
and:
|
||||
// tag::client_receive_message[]
|
||||
@@ -78,7 +97,7 @@ class CamelStubRunnerSpec extends Specification {
|
||||
// end::client_trigger[]
|
||||
then:
|
||||
// tag::client_trigger_receive[]
|
||||
Exchange receivedMessage = camelContext.createConsumerTemplate().receive('jms:output', 5000)
|
||||
Exchange receivedMessage = consumerTemplate.receive('jms:output', 5000)
|
||||
// end::client_trigger_receive[]
|
||||
and:
|
||||
// tag::client_trigger_message[]
|
||||
@@ -94,7 +113,7 @@ class CamelStubRunnerSpec extends Specification {
|
||||
stubFinder.trigger('org.springframework.cloud.contract.verifier.stubs:camelService', 'return_book_1')
|
||||
// end::trigger_group_artifact[]
|
||||
then:
|
||||
Exchange receivedMessage = camelContext.createConsumerTemplate().receive('jms:output', 5000)
|
||||
Exchange receivedMessage = consumerTemplate.receive('jms:output', 5000)
|
||||
and:
|
||||
receivedMessage != null
|
||||
assertThatBodyContainsBookNameFoo(receivedMessage.in.body)
|
||||
@@ -107,7 +126,7 @@ class CamelStubRunnerSpec extends Specification {
|
||||
stubFinder.trigger('camelService', 'return_book_1')
|
||||
// end::trigger_artifact[]
|
||||
then:
|
||||
Exchange receivedMessage = camelContext.createConsumerTemplate().receive('jms:output', 5000)
|
||||
Exchange receivedMessage = consumerTemplate.receive('jms:output', 5000)
|
||||
and:
|
||||
receivedMessage != null
|
||||
assertThatBodyContainsBookNameFoo(receivedMessage.in.body)
|
||||
@@ -134,7 +153,7 @@ class CamelStubRunnerSpec extends Specification {
|
||||
stubFinder.trigger()
|
||||
// end::trigger_all[]
|
||||
then:
|
||||
Exchange receivedMessage = camelContext.createConsumerTemplate().receive('jms:output', 5000)
|
||||
Exchange receivedMessage = consumerTemplate.receive('jms:output', 5000)
|
||||
and:
|
||||
receivedMessage != null
|
||||
assertThatBodyContainsBookNameFoo(receivedMessage.in.body)
|
||||
@@ -144,7 +163,7 @@ class CamelStubRunnerSpec extends Specification {
|
||||
def 'should trigger a label with no output message'() {
|
||||
when:
|
||||
// tag::trigger_no_output[]
|
||||
camelContext.createProducerTemplate().sendBodyAndHeaders('jms:delete', new BookReturned('foo'), [sample: 'header'])
|
||||
producerTemplate.sendBodyAndHeaders('jms:delete', new BookReturned('foo'), [sample: 'header'])
|
||||
// end::trigger_no_output[]
|
||||
then:
|
||||
noExceptionThrown()
|
||||
@@ -152,9 +171,9 @@ class CamelStubRunnerSpec extends Specification {
|
||||
|
||||
def 'should not trigger a message that does not match input'() {
|
||||
when:
|
||||
camelContext.createProducerTemplate().sendBodyAndHeaders('jms:input', new BookReturned('notmatching'), [wrong: 'header_value'])
|
||||
producerTemplate.sendBodyAndHeaders('jms:input', new BookReturned('notmatching'), [wrong: 'header_value'])
|
||||
then:
|
||||
Exchange receivedMessage = camelContext.createConsumerTemplate().receive('jms:output', 100)
|
||||
Exchange receivedMessage = consumerTemplate.receive('jms:output', 100)
|
||||
and:
|
||||
receivedMessage == null
|
||||
}
|
||||
|
||||
@@ -27,8 +27,9 @@ class StubRunnerCamelProcessorSpec extends Specification {
|
||||
|
||||
def 'should not process the message if there is no output message'() {
|
||||
given:
|
||||
StubRunnerCamelProcessor processor = new StubRunnerCamelProcessor(noOutputMessageContract)
|
||||
StubRunnerCamelProcessor processor = new StubRunnerCamelProcessor()
|
||||
when:
|
||||
message.in.body = new StubRunnerCamelPayload(noOutputMessageContract)
|
||||
processor.process(message)
|
||||
then:
|
||||
noExceptionThrown()
|
||||
@@ -58,8 +59,9 @@ class StubRunnerCamelProcessorSpec extends Specification {
|
||||
|
||||
def 'should process message when it has an output message section'() {
|
||||
given:
|
||||
StubRunnerCamelProcessor processor = new StubRunnerCamelProcessor(dsl)
|
||||
StubRunnerCamelProcessor processor = new StubRunnerCamelProcessor()
|
||||
when:
|
||||
message.in.body = new StubRunnerCamelPayload(dsl)
|
||||
processor.process(message)
|
||||
then:
|
||||
message.getIn().getBody(String) == '{"responseId":"123"}'
|
||||
@@ -89,8 +91,9 @@ class StubRunnerCamelProcessorSpec extends Specification {
|
||||
|
||||
def 'should convert dsl into message with regex in GString'() {
|
||||
given:
|
||||
StubRunnerCamelProcessor processor = new StubRunnerCamelProcessor(dslWithRegexInGString)
|
||||
StubRunnerCamelProcessor processor = new StubRunnerCamelProcessor()
|
||||
when:
|
||||
message.in.body = new StubRunnerCamelPayload(dslWithRegexInGString)
|
||||
processor.process(message)
|
||||
then:
|
||||
message.getIn().getBody(String) == '''{"id":"99","temperature":"123.45"}'''
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
stubrunner:
|
||||
repositoryRoot: classpath:m2repo/repository/
|
||||
repository-root: classpath:m2repo/repository/
|
||||
ids: org.springframework.cloud.contract.verifier.stubs:camelService:0.0.1-SNAPSHOT:stubs
|
||||
stubs-mode: remote
|
||||
server:
|
||||
port: 0
|
||||
debug: true
|
||||
debug: true
|
||||
logging.level.org.springframework.cloud.contract: debug
|
||||
Reference in New Issue
Block a user