diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/main/java/org/springframework/cloud/contract/stubrunner/messaging/camel/StubRunnerCamelPredicate.java b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/main/java/org/springframework/cloud/contract/stubrunner/messaging/camel/StubRunnerCamelPredicate.java index 74ff128366..51721cbbf5 100644 --- a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/main/java/org/springframework/cloud/contract/stubrunner/messaging/camel/StubRunnerCamelPredicate.java +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/main/java/org/springframework/cloud/contract/stubrunner/messaging/camel/StubRunnerCamelPredicate.java @@ -90,7 +90,7 @@ public class StubRunnerCamelPredicate implements Predicate { Object valueInHeader = headers.get(name); matches &= value instanceof Pattern ? ((Pattern) value).matcher(valueInHeader.toString()).matches() : - valueInHeader.equals(value); + valueInHeader!=null && valueInHeader.equals(value); } return matches; } diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/.jdk8 b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/.jdk8 new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/pom.xml b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/pom.xml index fbe3d59c45..37cbff66af 100644 --- a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/pom.xml +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/pom.xml @@ -1,6 +1,6 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 org.springframework.cloud @@ -12,6 +12,9 @@ jar Spring Cloud Contract Stub Runner Integration Spring Cloud Contract Stub Runner Integration + + 1.8 + org.springframework.cloud @@ -72,9 +75,6 @@ - addSources - addTestSources - compile testCompile diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationConfiguration.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationConfiguration.groovy deleted file mode 100644 index 62442dd699..0000000000 --- a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationConfiguration.groovy +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2013-2016 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 - * - * http://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.integration - -import groovy.transform.CompileStatic -import org.springframework.cloud.contract.spec.Contract -import org.springframework.cloud.contract.stubrunner.StubConfiguration -import org.springframework.beans.factory.config.AutowireCapableBeanFactory -import org.springframework.cloud.contract.stubrunner.BatchStubRunner -import org.springframework.cloud.contract.stubrunner.spring.StubRunnerConfiguration -import org.springframework.context.Lifecycle -import org.springframework.context.annotation.Bean -import org.springframework.context.annotation.Configuration -import org.springframework.context.annotation.Import -import org.springframework.integration.dsl.FilterEndpointSpec -import org.springframework.integration.dsl.GenericEndpointSpec -import org.springframework.integration.dsl.IntegrationFlowBuilder -import org.springframework.integration.dsl.IntegrationFlows -import org.springframework.messaging.Message - -/** - * Spring Integration configuration that iterates over the downloaded Groovy DSLs - * and registers a flow for each DSL. - * - * @author Marcin Grzejszczak - */ -@Configuration -@CompileStatic -class StubRunnerIntegrationConfiguration { - - @Bean - FlowRegistrar flowRegistrar(AutowireCapableBeanFactory beanFactory, BatchStubRunner batchStubRunner) { - Map> contracts = batchStubRunner.contracts - contracts.each { StubConfiguration key, Collection value -> - String name = "${key.groupId}_${key.artifactId}" - value.findAll { it?.input?.messageFrom?.clientValue }.each { Contract dsl -> - String flowName = "${name}_${dsl.label}_${dsl.hashCode()}" - IntegrationFlowBuilder builder = IntegrationFlows.from(dsl.input.messageFrom.clientValue) - .filter(new StubRunnerIntegrationMessageSelector(dsl), { FilterEndpointSpec e -> e.id("${flowName}.filter") } ) - .transform(new StubRunnerIntegrationTransformer(dsl), { GenericEndpointSpec e -> e.id("${flowName}.transformer") }) - if (dsl.outputMessage?.sentTo) { - builder = builder.channel(dsl.outputMessage.sentTo.clientValue) - } else { - builder = builder.handle(new DummyMessageHandler(), "handle") - } - beanFactory.initializeBean(builder.get(), flowName) - beanFactory.getBean("${flowName}.filter", Lifecycle.class).start(); - beanFactory.getBean("${flowName}.transformer", Lifecycle.class).start(); - } - } - return new FlowRegistrar() - } - - @CompileStatic - private static class DummyMessageHandler { - void handle(Message message) {} - } - - static class FlowRegistrar {} -} diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationMessageSelector.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationMessageSelector.groovy deleted file mode 100644 index ff4413d5d5..0000000000 --- a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationMessageSelector.groovy +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2013-2016 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 - * - * http://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.integration - -import com.jayway.jsonpath.DocumentContext -import com.jayway.jsonpath.JsonPath -import com.toomuchcoding.jsonassert.JsonAssertion -import com.toomuchcoding.jsonassert.JsonVerifiable -import groovy.transform.CompileStatic -import org.springframework.cloud.contract.spec.Contract -import org.springframework.cloud.contract.verifier.messaging.ContractVerifierObjectMapper -import org.springframework.cloud.contract.verifier.util.JsonPaths -import org.springframework.cloud.contract.verifier.util.JsonToJsonPathsConverter -import org.springframework.integration.core.MessageSelector -import org.springframework.messaging.Message - -import java.util.regex.Pattern -/** - * Passes through a message that matches the one defined in the DSL - * - * @author Marcin Grzejszczak - */ -@CompileStatic -class StubRunnerIntegrationMessageSelector implements MessageSelector { - - private final Contract groovyDsl - private final ContractVerifierObjectMapper objectMapper = new ContractVerifierObjectMapper() - - StubRunnerIntegrationMessageSelector(Contract groovyDsl) { - this.groovyDsl = groovyDsl - } - - @Override - boolean accept(Message message) { - if(!headersMatch(message)){ - return false - } - Object inputMessage = message.getPayload() - JsonPaths jsonPaths = JsonToJsonPathsConverter.transformToJsonPathWithStubsSideValues(groovyDsl.input.messageBody) - DocumentContext parsedJson = JsonPath.parse(objectMapper.writeValueAsString(inputMessage)) - return jsonPaths.every { matchesJsonPath(parsedJson, it) } - } - - private boolean matchesJsonPath(DocumentContext parsedJson, JsonVerifiable jsonVerifiable) { - try { - JsonAssertion.assertThat(parsedJson).matchesJsonPath(jsonVerifiable.jsonPath()) - return true - } catch (Exception e) { - return false - } - } - - private boolean headersMatch(Message message) { - Map headers = message.getHeaders() - return groovyDsl.input.messageHeaders.entries.every { - String name = it.name - Object value = it.clientValue - Object valueInHeader = headers.get(name) - return value instanceof Pattern ? - value.matcher(valueInHeader.toString()).matches() : - valueInHeader == value - } - } -} diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/main/java/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationConfiguration.java b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/main/java/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationConfiguration.java new file mode 100644 index 0000000000..62e7937191 --- /dev/null +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/main/java/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationConfiguration.java @@ -0,0 +1,85 @@ +/* + * Copyright 2013-2016 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 + * + * http://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.integration; + +import java.util.Collection; +import java.util.Map; + +import org.springframework.beans.factory.config.AutowireCapableBeanFactory; +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.Lifecycle; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.integration.dsl.IntegrationFlowBuilder; +import org.springframework.integration.dsl.IntegrationFlows; +import org.springframework.messaging.Message; + +/** + * Spring Integration configuration that iterates over the downloaded Groovy DSLs and + * registers a flow for each DSL. + * + * @author Marcin Grzejszczak + */ +@Configuration +public class StubRunnerIntegrationConfiguration { + + @Bean + public FlowRegistrar flowRegistrar(AutowireCapableBeanFactory beanFactory, + BatchStubRunner batchStubRunner) { + Map> contracts = batchStubRunner + .getContracts(); + contracts.entrySet().stream().forEach(entry -> { + String name = entry.getKey().getGroupId() + "_" + + entry.getKey().getArtifactId(); + entry.getValue().stream().forEach(dsl -> { + if (dsl.getInput() != null && dsl.getInput().getMessageFrom() != null + && dsl.getInput().getMessageFrom().getClientValue() != null) { + String flowName = name + "_" + dsl.getLabel() + "_" + dsl.hashCode(); + IntegrationFlowBuilder builder = IntegrationFlows + .from(dsl.getInput().getMessageFrom().getClientValue()) + .filter(new StubRunnerIntegrationMessageSelector(dsl), + e -> e.id(flowName + ".filter")) + .transform(new StubRunnerIntegrationTransformer(dsl), + e -> e.id(flowName + ".transformer")); + if (dsl.getOutputMessage() != null) { + builder = builder.channel( + dsl.getOutputMessage().getSentTo().getClientValue()); + } + else { + builder = builder.handle(new DummyMessageHandler(), "handle"); + } + beanFactory.initializeBean(builder.get(), flowName); + beanFactory.getBean(flowName + ".filter", Lifecycle.class).start(); + beanFactory.getBean(flowName + ".transformer", Lifecycle.class) + .start(); + } + }); + }); + return new FlowRegistrar(); + } + + private static class DummyMessageHandler { + @SuppressWarnings("unused") + public void handle(Message message) { + } + } + + static class FlowRegistrar { + } +} diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/main/java/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationMessageSelector.java b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/main/java/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationMessageSelector.java new file mode 100644 index 0000000000..c04b845964 --- /dev/null +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/main/java/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationMessageSelector.java @@ -0,0 +1,102 @@ +/* + * Copyright 2013-2016 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 + * + * http://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.integration; + +import java.util.Map; +import java.util.regex.Pattern; + +import org.springframework.cloud.contract.spec.Contract; +import org.springframework.cloud.contract.spec.internal.Header; +import org.springframework.cloud.contract.verifier.messaging.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 org.springframework.integration.core.MessageSelector; +import org.springframework.messaging.Message; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.jayway.jsonpath.DocumentContext; +import com.jayway.jsonpath.JsonPath; +import com.toomuchcoding.jsonassert.JsonAssertion; +import com.toomuchcoding.jsonassert.JsonVerifiable; + +import groovy.transform.CompileStatic; + +/** + * Passes through a message that matches the one defined in the DSL + * + * @author Marcin Grzejszczak + */ +@CompileStatic +public class StubRunnerIntegrationMessageSelector implements MessageSelector { + + private final Contract groovyDsl; + private final ContractVerifierObjectMapper objectMapper = new ContractVerifierObjectMapper(); + + StubRunnerIntegrationMessageSelector(Contract groovyDsl) { + this.groovyDsl = groovyDsl; + } + + @Override + public boolean accept(Message message) { + if (!headersMatch(message)) { + return false; + } + Object inputMessage = message.getPayload(); + JsonPaths jsonPaths = JsonToJsonPathsConverter + .transformToJsonPathWithStubsSideValues( + groovyDsl.getInput().getMessageBody()); + DocumentContext parsedJson; + try { + parsedJson = JsonPath.parse(objectMapper.writeValueAsString(inputMessage)); + } + catch (JsonProcessingException e) { + throw new IllegalStateException("Cannot serialize to JSON", e); + } + boolean matches = true; + for (MethodBufferingJsonVerifiable path : jsonPaths) { + matches &= matchesJsonPath(parsedJson, path); + } + return matches; + } + + private boolean matchesJsonPath(DocumentContext parsedJson, + JsonVerifiable jsonVerifiable) { + try { + JsonAssertion.assertThat(parsedJson) + .matchesJsonPath(jsonVerifiable.jsonPath()); + return true; + } + catch (Exception e) { + return false; + } + } + + private boolean headersMatch(Message message) { + Map headers = message.getHeaders(); + boolean matches = true; + for (Header it : groovyDsl.getInput().getMessageHeaders().getEntries()) { + String name = it.getName(); + Object value = it.getClientValue(); + Object valueInHeader = headers.get(name); + matches &= value instanceof Pattern ? + ((Pattern) value).matcher(valueInHeader.toString()).matches() : + valueInHeader!=null && valueInHeader.equals(value); + } + return matches; + } +} diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationTransformer.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/main/java/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationTransformer.java similarity index 62% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationTransformer.groovy rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/main/java/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationTransformer.java index 0bf9278b01..59595d138f 100644 --- a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationTransformer.groovy +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/main/java/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationTransformer.java @@ -14,35 +14,37 @@ * limitations under the License. */ -package org.springframework.cloud.contract.stubrunner.messaging.integration +package org.springframework.cloud.contract.stubrunner.messaging.integration; -import org.springframework.cloud.contract.spec.Contract -import org.springframework.cloud.contract.verifier.util.BodyExtractor -import org.springframework.integration.transformer.GenericTransformer -import org.springframework.messaging.Message -import org.springframework.messaging.MessageHeaders -import org.springframework.messaging.support.MessageBuilder +import java.util.Map; + +import org.springframework.cloud.contract.spec.Contract; +import org.springframework.cloud.contract.verifier.util.BodyExtractor; +import org.springframework.integration.transformer.GenericTransformer; +import org.springframework.messaging.Message; +import org.springframework.messaging.MessageHeaders; +import org.springframework.messaging.support.MessageBuilder; /** * Sends forward a message defined in the DSL. * * @author Marcin Grzejszczak */ -class StubRunnerIntegrationTransformer implements GenericTransformer, Message> { +public class StubRunnerIntegrationTransformer implements GenericTransformer, Message> { - private final Contract groovyDsl + private final Contract groovyDsl; StubRunnerIntegrationTransformer(Contract groovyDsl) { - this.groovyDsl = groovyDsl + this.groovyDsl = groovyDsl; } @Override - Message transform(Message source) { - if (!groovyDsl.outputMessage) { - return source + public Message transform(Message source) { + if (groovyDsl.getOutputMessage()==null) { + return source; } - String payload = BodyExtractor.extractStubValueFrom(groovyDsl.outputMessage.body) - Map headers = groovyDsl.outputMessage.headers.asStubSideMap() - return MessageBuilder.createMessage(payload, new MessageHeaders(headers)) + String payload = BodyExtractor.extractStubValueFrom(groovyDsl.getOutputMessage().getBody()); + Map headers = groovyDsl.getOutputMessage().getHeaders().asStubSideMap(); + return MessageBuilder.createMessage(payload, new MessageHeaders(headers)); } }