Convert stub runner integration to Java
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
@@ -12,6 +12,9 @@
|
||||
<packaging>jar</packaging>
|
||||
<name>Spring Cloud Contract Stub Runner Integration</name>
|
||||
<description>Spring Cloud Contract Stub Runner Integration</description>
|
||||
<properties>
|
||||
<java.version>1.8</java.version>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
@@ -72,9 +75,6 @@
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>addSources</goal>
|
||||
<goal>addTestSources</goal>
|
||||
<goal>compile</goal>
|
||||
<goal>testCompile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
|
||||
@@ -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<StubConfiguration, Collection<Contract>> contracts = batchStubRunner.contracts
|
||||
contracts.each { StubConfiguration key, Collection<Contract> 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 {}
|
||||
}
|
||||
@@ -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<String, Object> 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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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<StubConfiguration, Collection<Contract>> 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 {
|
||||
}
|
||||
}
|
||||
@@ -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<String, Object> 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;
|
||||
}
|
||||
}
|
||||
@@ -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<?>, Message<?>> {
|
||||
public class StubRunnerIntegrationTransformer implements GenericTransformer<Message<?>, 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<String, Object> headers = groovyDsl.outputMessage.headers.asStubSideMap()
|
||||
return MessageBuilder.createMessage(payload, new MessageHeaders(headers))
|
||||
String payload = BodyExtractor.extractStubValueFrom(groovyDsl.getOutputMessage().getBody());
|
||||
Map<String, Object> headers = groovyDsl.getOutputMessage().getHeaders().asStubSideMap();
|
||||
return MessageBuilder.createMessage(payload, new MessageHeaders(headers));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user