diff --git a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubRunnerOptionsBuilder.java b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubRunnerOptionsBuilder.java
index 64d99e7dfd..b1488333b8 100644
--- a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubRunnerOptionsBuilder.java
+++ b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubRunnerOptionsBuilder.java
@@ -161,11 +161,17 @@ public class StubRunnerOptionsBuilder {
public StubRunnerOptionsBuilder withStubsMode(
StubRunnerProperties.StubsMode stubsMode) {
+ if (stubsMode == null) {
+ return this;
+ }
this.stubsMode = stubsMode;
return this;
}
public StubRunnerOptionsBuilder withStubsMode(String stubsMode) {
+ if (stubsMode == null) {
+ return this;
+ }
this.stubsMode = StubRunnerProperties.StubsMode.valueOf(stubsMode);
return this;
}
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 4b89970fe6..db36e7c643 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
@@ -16,6 +16,7 @@
package org.springframework.cloud.contract.stubrunner.spring;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
@@ -78,7 +79,7 @@ public class StubRunnerConfiguration {
if (this.props.getProxyHost() != null) {
builder.withProxy(this.props.getProxyHost(), this.props.getProxyPort());
}
- StubRunnerOptions stubRunnerOptions = builder.build();
+ StubRunnerOptions stubRunnerOptions = stubRunnerOptions(builder);
BatchStubRunner batchStubRunner = new BatchStubRunnerFactory(stubRunnerOptions,
this.provider.get(stubRunnerOptions),
this.contractVerifierMessaging != null ? this.contractVerifierMessaging
@@ -89,26 +90,54 @@ public class StubRunnerConfiguration {
return batchStubRunner;
}
+ private StubRunnerOptions stubRunnerOptions(StubRunnerOptionsBuilder builder) {
+ return builder.build();
+ }
+
private StubRunnerOptionsBuilder builder() {
return new StubRunnerOptionsBuilder()
- .withMinMaxPort(this.props.getMinPort(), this.props.getMaxPort())
+ .withMinMaxPort(
+ Integer.valueOf(resolvePlaceholder(this.props.getMinPort(),
+ this.props.getMinPort())),
+ Integer.valueOf(resolvePlaceholder(this.props.getMaxPort(),
+ this.props.getMaxPort())))
.withStubRepositoryRoot(this.props.getRepositoryRoot())
- .withStubsMode(this.props.getStubsMode())
- .withStubsClassifier(this.props.getClassifier())
- .withStubs(this.props.getIds()).withUsername(this.props.getUsername())
- .withPassword(this.props.getPassword())
- .withStubPerConsumer(this.props.isStubsPerConsumer())
+ .withStubsMode(resolvePlaceholder(this.props.getStubsMode()))
+ .withStubsClassifier(resolvePlaceholder(this.props.getClassifier()))
+ .withStubs(resolvePlaceholder(this.props.getIds()))
+ .withUsername(resolvePlaceholder(this.props.getUsername()))
+ .withPassword(resolvePlaceholder(this.props.getPassword()))
+ .withStubPerConsumer(Boolean.parseBoolean(
+ resolvePlaceholder(this.props.isStubsPerConsumer())))
.withConsumerName(consumerName())
- .withMappingsOutputFolder(this.props.getMappingsOutputFolder())
- .withDeleteStubsAfterTest(this.props.isDeleteStubsAfterTest())
- .withGenerateStubs(this.props.isGenerateStubs())
+ .withMappingsOutputFolder(
+ resolvePlaceholder(this.props.getMappingsOutputFolder()))
+ .withDeleteStubsAfterTest(Boolean.parseBoolean(
+ resolvePlaceholder(this.props.isDeleteStubsAfterTest())))
+ .withGenerateStubs(Boolean
+ .parseBoolean(resolvePlaceholder(this.props.isGenerateStubs())))
.withProperties(this.props.getProperties())
.withHttpServerStubConfigurer(this.props.getHttpServerStubConfigurer());
}
+ private String[] resolvePlaceholder(String[] string) {
+ return Arrays.stream(string).map(this::resolvePlaceholder).toArray(String[]::new);
+ }
+
+ private String resolvePlaceholder(Object string) {
+ return resolvePlaceholder(string, null);
+ }
+
+ private String resolvePlaceholder(Object string, Object defaultValue) {
+ if (string == null) {
+ return defaultValue != null ? defaultValue.toString() : null;
+ }
+ return this.environment.resolvePlaceholders(string.toString());
+ }
+
private String consumerName() {
if (StringUtils.hasText(this.props.getConsumerName())) {
- return this.props.getConsumerName();
+ return resolvePlaceholder(this.props.getConsumerName());
}
return this.environment.getProperty("spring.application.name");
}
diff --git a/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/spring/StubRunnerOptionsBuilderSpec.groovy b/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/spring/StubRunnerOptionsBuilderSpec.groovy
new file mode 100644
index 0000000000..dde58a1dee
--- /dev/null
+++ b/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/spring/StubRunnerOptionsBuilderSpec.groovy
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2013-2019 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.spring
+
+
+import spock.lang.Specification
+
+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.context.annotation.Configuration
+import org.springframework.test.context.ActiveProfiles
+import org.springframework.test.context.ContextConfiguration
+/**
+ * @author Marcin Grzejszczak
+ */
+
+@ContextConfiguration(classes = Config, loader = SpringBootContextLoader)
+@SpringBootTest(properties = ['some.property1=org.springframework.cloud.contract.verifier.stubs:loanIssuance'])
+@AutoConfigureStubRunner
+@ActiveProfiles("test-with-placeholders")
+class StubRunnerOptionsBuilderSpec extends Specification {
+
+ @StubRunnerPort("fraudDetectionServer")
+ int fraudDetectionServerPort
+
+ @StubRunnerPort("loanIssuance")
+ int loanIssuancePort
+
+ @Value('${stub.port}')
+ int stubPort
+
+ def 'should resolve placeholders'() {
+ expect:
+ fraudDetectionServerPort > 1000
+ loanIssuancePort > 1000
+ and:
+ stubPort == fraudDetectionServerPort
+ }
+
+ @Configuration
+ @EnableAutoConfiguration
+ static class Config {}
+}
diff --git a/spring-cloud-contract-stub-runner/src/test/resources/application-test-with-placeholders.yml b/spring-cloud-contract-stub-runner/src/test/resources/application-test-with-placeholders.yml
new file mode 100644
index 0000000000..f146989f96
--- /dev/null
+++ b/spring-cloud-contract-stub-runner/src/test/resources/application-test-with-placeholders.yml
@@ -0,0 +1,23 @@
+provider.stub.artifact.id: fraudDetectionServer
+
+stubrunner:
+ repositoryRoot: classpath:m2repo/repository/
+ ids:
+ - ${some.property1}
+ - 'org.springframework.cloud.contract.verifier.stubs:${provider.stub.artifact.id}'
+ stubs-mode: ${some.stubsmode:remote}
+ min-port: ${some.minport:1000}
+ max-port: ${some.maxport:20000}
+ classifier: ${some.classifier:stubs}
+ username: ${some.username:user}
+ password: ${some.password:pass}
+ stubs-per-consumer: ${some.stubsperconsumer:false}
+ consumer-name: ${some.consumername:name}
+ mappings-output-folder: ${some.mappingsoutputfolder:target}
+ delete-stubs-after-test: ${some.deletestubsaftertest:true}
+ generate-stubs: ${some.generatestubs:false}
+spring:
+ main:
+ allow-bean-definition-overriding: true
+
+stub.port: ${stubrunner.runningstubs.${provider.stub.artifact.id}.port}
\ No newline at end of file
diff --git a/tests/spring-cloud-contract-stub-runner-kafka/pom.xml b/tests/spring-cloud-contract-stub-runner-kafka/pom.xml
index f5579cf799..cc3a2c97b3 100644
--- a/tests/spring-cloud-contract-stub-runner-kafka/pom.xml
+++ b/tests/spring-cloud-contract-stub-runner-kafka/pom.xml
@@ -11,8 +11,8 @@
spring-cloud-contract-stub-runner-kafka
jar
- Spring Cloud Contract Stub Runner JMS
- Spring Cloud Contract Stub Runner JMS
+ Spring Cloud Contract Stub Runner Kafka
+ Spring Cloud Contract Stub Runner Kafka
org.springframework.cloud
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 34bdee670c..554a76dc05 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
@@ -45,6 +45,7 @@ import org.springframework.kafka.test.context.EmbeddedKafka
import org.springframework.messaging.Message
import org.springframework.messaging.MessageHeaders
import org.springframework.messaging.support.MessageBuilder
+import org.springframework.test.annotation.DirtiesContext
import org.springframework.test.context.ContextConfiguration
/**
* @author Marcin Grzejszczak