Merge branch '1.1.x' into 1.2.x

This commit is contained in:
Marcin Grzejszczak
2017-12-20 16:33:24 +01:00
5 changed files with 123 additions and 21 deletions

View File

@@ -48,9 +48,10 @@ public class EurekaStubsRegistrar implements StubsRegistrar {
.validNamesAndPorts();
for (Map.Entry<StubConfiguration, Integer> entry : activeStubs.entrySet()) {
Application application = new Application(name(entry.getKey()), entry.getKey().getArtifactId(),
StringUtils.hasText(this.eurekaInstanceConfigBean.getHostname()) ?
this.eurekaInstanceConfigBean.getHostname() :
this.inetUtils.findFirstNonLoopbackAddress().getHostName(), entry.getValue());
StringUtils.hasText(hostName(entry)) ?
hostName(entry) :
this.inetUtils.findFirstNonLoopbackAddress().getHostName(),
port(entry));
try {
Registration register = this.eurekaClient.register(application);
this.discoveryList.add(new Renewer(
@@ -67,6 +68,14 @@ public class EurekaStubsRegistrar implements StubsRegistrar {
}
}
protected String hostName(Map.Entry<StubConfiguration, Integer> entry) {
return this.eurekaInstanceConfigBean.getHostname();
}
protected int port(Map.Entry<StubConfiguration, Integer> entry) {
return entry.getValue();
}
private String name(StubConfiguration stubConfiguration) {
String resolvedName = this.stubMapperProperties.fromIvyNotationToId(
stubConfiguration.toColonSeparatedDependencyNotation());

View File

@@ -16,10 +16,19 @@
package org.springframework.cloud.contract.stubrunner.spring.cloud.eureka;
import java.util.Map;
import com.netflix.appinfo.ApplicationInfoManager;
import com.netflix.discovery.EurekaClientConfig;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.bind.RelaxedPropertyResolver;
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.StubRunnerConfiguration;
import org.springframework.cloud.contract.stubrunner.spring.cloud.ConditionalOnStubbedDiscoveryDisabled;
@@ -32,9 +41,8 @@ import org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.netflix.appinfo.ApplicationInfoManager;
import com.netflix.discovery.EurekaClientConfig;
import org.springframework.context.annotation.Profile;
import org.springframework.core.env.Environment;
/**
* Autoconfiguration for registering stubs in a Eureka Service discovery
@@ -51,10 +59,43 @@ import com.netflix.discovery.EurekaClientConfig;
@ConditionalOnProperty(value = "stubrunner.cloud.eureka.enabled", matchIfMissing = true)
public class StubRunnerSpringCloudEurekaAutoConfiguration {
@Bean(initMethod = "registerStubs")
public StubsRegistrar stubsRegistrar(StubRunning stubRunning, Eureka eureka,
StubMapperProperties stubMapperProperties, InetUtils inetUtils, EurekaInstanceConfigBean eurekaInstanceConfigBean) {
return new EurekaStubsRegistrar(stubRunning, eureka, stubMapperProperties, inetUtils, eurekaInstanceConfigBean);
@Profile("!cloud")
@Configuration
protected static class NonCloudConfig {
@Bean(initMethod = "registerStubs")
public StubsRegistrar stubsRegistrar(StubRunning stubRunning, Eureka eureka,
StubMapperProperties stubMapperProperties, InetUtils inetUtils, EurekaInstanceConfigBean eurekaInstanceConfigBean) {
return new EurekaStubsRegistrar(stubRunning, eureka, stubMapperProperties, inetUtils, eurekaInstanceConfigBean);
}
}
@Profile("cloud")
@Configuration
protected static class CloudConfig {
private static final int DEFAULT_PORT = 80;
private static final Log log = LogFactory.getLog(CloudConfig.class);
@Autowired Environment environment;
@Bean(initMethod = "registerStubs")
public StubsRegistrar cloudStubsRegistrar(StubRunning stubRunning, Eureka eureka,
StubMapperProperties stubMapperProperties, InetUtils inetUtils, EurekaInstanceConfigBean eurekaInstanceConfigBean) {
final RelaxedPropertyResolver resolver = new RelaxedPropertyResolver(
CloudConfig.this.environment);
return new EurekaStubsRegistrar(stubRunning, eureka, stubMapperProperties, inetUtils, eurekaInstanceConfigBean) {
@Override protected String hostName(Map.Entry<StubConfiguration, Integer> entry) {
String hostname =
resolver.getProperty("application.hostname") +
"-" + entry.getValue() + "." + resolver.getProperty("application.domain");
log.info("Registering stub [" + entry.getKey().getArtifactId() + "] with hostname [" + hostname + "]");
return hostname;
}
@Override protected int port(Map.Entry<StubConfiguration, Integer> entry) {
return DEFAULT_PORT;
}
};
}
}
@Bean(name = "eurekaRegistrar")

View File

@@ -47,7 +47,6 @@ import org.springframework.cloud.contract.verifier.util.MapConverter
import org.springframework.util.SerializationUtils
import org.springframework.util.StringUtils
import java.lang.invoke.MethodHandles
import java.util.regex.Pattern
import static org.springframework.cloud.contract.verifier.util.ContentUtils.extractValue
@@ -64,7 +63,7 @@ import static org.springframework.cloud.contract.verifier.util.ContentUtils.extr
@PackageScope
abstract class MethodBodyBuilder {
private static final Log log = LogFactory.getLog(MethodHandles.lookup().lookupClass())
private static final Closure GET_SERVER_VALUE = { it instanceof DslProperty ? it.serverValue : it }
protected final ContractVerifierConfigProperties configProperties
protected final TemplateProcessor templateProcessor
@@ -592,9 +591,11 @@ abstract class MethodBodyBuilder {
*/
protected Object extractServerValueFromBody(bodyValue) {
if (bodyValue instanceof GString) {
bodyValue = extractValue(bodyValue, { DslProperty dslProperty -> dslProperty.serverValue })
bodyValue = extractValue(bodyValue, ContentType.from(MapConverter.getTestSideValues(this.contract.request.headers?.entries?.find {
it.name.toLowerCase() == "Content-Type".toLowerCase()
}).toString()), GET_SERVER_VALUE)
} else {
bodyValue = MapConverter.transformValues(bodyValue, { it instanceof DslProperty ? it.serverValue : it })
bodyValue = MapConverter.transformValues(bodyValue, GET_SERVER_VALUE)
}
return bodyValue
}

View File

@@ -17,7 +17,7 @@
package org.springframework.cloud.contract.verifier.util
/**
* Represents content type
* Represents content type. Used to pick the way bodies are parsed.
*
* @since 1.0.0
*/
@@ -34,4 +34,19 @@ enum ContentType {
this.mimeType = mimeType
}
static ContentType from(String header) {
try {
if (header.contains("json")) {
return JSON
} else if (header.contains("xml")) {
return XML
} else if (header.contains("text") ||
header.contains("application/x-www-form-urlencoded")) {
// we want both to be treated as text
return TEXT
}
} catch(e) {}
return UNKNOWN
}
}

View File

@@ -349,7 +349,7 @@ DocumentContext parsedJson = JsonPath.parse(json);
}
@Issue("#458")
def "should reference request from body whtn body is a string [#methodBuilderName]"() {
def "should reference request from body when body is a string [#methodBuilderName]"() {
given:
Contract contractDsl = Contract.make {
request {
@@ -367,15 +367,17 @@ DocumentContext parsedJson = JsonPath.parse(json);
when:
builder.appendTo(blockBuilder)
then:
SyntaxChecker.tryToCompileWithoutCompileStatic(methodBuilderName, blockBuilder.toString())
String test = blockBuilder.toString()
SyntaxChecker.tryToCompileWithoutCompileStatic(methodBuilderName, test)
responseAsserter(test)
and:
stubMappingIsValidWireMockStub(contractDsl)
where:
methodBuilderName | methodBuilder | responseAsserter
"MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | { String string -> assert string.contains('responseBody == "My name"') }
"MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | { String string -> assert string.contains('assertThat(responseBody).isEqualTo("My name");') }
"JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | { String string -> assert string.contains('responseBody == "My name"') }
"JaxRsClientJUnitMethodBodyBuilder" | { Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } | { String string -> assert string.contains('assertThat(responseBody).isEqualTo("My name");') }
"MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | { String string -> string.contains('responseBody == "My name"') }
"MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | { String string -> string.contains('assertThat(responseBody).isEqualTo("My name");') }
"JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | { String string -> string.contains('responseBody == "My name"') }
"JaxRsClientJUnitMethodBodyBuilder" | { Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } | { String string -> string.contains('assertThat(responseBody).isEqualTo("My name");') }
}
@Issue("#465")
@@ -451,4 +453,38 @@ DocumentContext parsedJson = JsonPath.parse(json);
"MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) }
}
@Issue("#493")
def "should not escape a form URL encoded request body [#methodBuilderName]"() {
given:
Contract contractDsl = Contract.make {
request {
method 'POST'
url '/api/form-endpoint'
headers {
header("Content-Type": 'application/x-www-form-urlencoded')
}
body('a=abc&b=123')
}
response {
status 200
}
}
MethodBodyBuilder builder = methodBuilder(contractDsl)
BlockBuilder blockBuilder = new BlockBuilder(" ")
when:
builder.appendTo(blockBuilder)
then:
String test = blockBuilder.toString()
SyntaxChecker.tryToCompileWithoutCompileStatic(methodBuilderName, test)
!test.contains("a=abc&amp;b=123")
and:
stubMappingIsValidWireMockStub(contractDsl)
where:
methodBuilderName | methodBuilder
"MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) }
"MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) }
"JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) }
"JaxRsClientJUnitMethodBodyBuilder" | { Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) }
}
}