diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/pom.xml b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/pom.xml
index 8e45a3af9e..bd2858f538 100644
--- a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/pom.xml
+++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/pom.xml
@@ -73,7 +73,7 @@
org.spockframework
- spock-core
+ spock-spring
test
diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/spring/AutoConfigureStubRunner.java b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/spring/AutoConfigureStubRunner.java
new file mode 100644
index 0000000000..c5eb9af52a
--- /dev/null
+++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/spring/AutoConfigureStubRunner.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2012-2015 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.spring;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
+
+/**
+ * @author Dave Syer
+ *
+ */
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@ImportAutoConfiguration
+public @interface AutoConfigureStubRunner {
+
+}
diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/spring/StubRunnerConfiguration.java b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/spring/StubRunnerConfiguration.java
new file mode 100644
index 0000000000..3a9e2d040c
--- /dev/null
+++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/spring/StubRunnerConfiguration.java
@@ -0,0 +1,86 @@
+/*
+ * 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.spring;
+
+import java.io.IOException;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.cloud.contract.stubrunner.AetherStubDownloader;
+import org.springframework.cloud.contract.stubrunner.BatchStubRunner;
+import org.springframework.cloud.contract.stubrunner.BatchStubRunnerFactory;
+import org.springframework.cloud.contract.stubrunner.StubDownloader;
+import org.springframework.cloud.contract.stubrunner.StubRunner;
+import org.springframework.cloud.contract.stubrunner.StubRunnerOptions;
+import org.springframework.cloud.contract.stubrunner.StubRunnerOptionsBuilder;
+import org.springframework.cloud.contract.verifier.messaging.ContractVerifierMessaging;
+import org.springframework.cloud.contract.verifier.messaging.noop.NoOpContractVerifierMessaging;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.io.Resource;
+
+/**
+ * Configuration that initializes a {@link BatchStubRunner} that runs {@link StubRunner} instance for each stub
+ */
+@Configuration
+@ConditionalOnMissingBean(type="org.springframework.cloud.contract.wiremock.WiremockServerConfiguration")
+public class StubRunnerConfiguration {
+
+ @Autowired(required = false) ContractVerifierMessaging,?> contractVerifierMessaging;
+ @Autowired(required = false) StubDownloader stubDownloader;
+
+ /**
+ * Bean that initializes stub runners, runs them and on shutdown closes them. Upon its instantiation
+ * JAR with stubs is downloaded and unpacked to a temporary folder and WireMock server are started
+ * for each of those stubs
+ *
+ * @param minPortValue min port value of the WireMock instance for stubs
+ * @param maxPortValue max port value of the WireMock instance for stubs
+ * @param stubRepositoryRoot root URL from where the JAR with stub mappings will be downloaded
+ * @param stubsSuffix classifier for the jar containing stubs
+ * @param workOffline forces offline work
+ * @param stubs comma separated list of stubs presented in Ivy notation
+ */
+ @Bean
+ public BatchStubRunner batchStubRunner(
+ @Value("${stubrunner.port.range.min:10000}") Integer minPortValue,
+ @Value("${stubrunner.port.range.max:15000}") Integer maxPortValue,
+ @Value("${stubrunner.stubs.repository.root:}") Resource stubRepositoryRoot,
+ @Value("${stubrunner.stubs.classifier:stubs}") String stubsSuffix,
+ @Value("${stubrunner.work-offline:false}") boolean workOffline,
+ @Value("${stubrunner.stubs.ids:}") String stubs) throws IOException {
+ StubRunnerOptions stubRunnerOptions = new StubRunnerOptionsBuilder()
+ .withMinMaxPort(minPortValue, maxPortValue)
+ .withStubRepositoryRoot(uriStringOrEmpty(stubRepositoryRoot))
+ .withWorkOffline(stubRepositoryRoot == null || workOffline)
+ .withStubsClassifier(stubsSuffix)
+ .withStubs(stubs)
+ .build();
+ BatchStubRunner batchStubRunner = new BatchStubRunnerFactory(stubRunnerOptions,
+ stubDownloader != null ? stubDownloader : new AetherStubDownloader(stubRunnerOptions),
+ contractVerifierMessaging != null ? contractVerifierMessaging : new NoOpContractVerifierMessaging()).buildBatchStubRunner();
+ // TODO: Consider running it in a separate thread
+ batchStubRunner.runStubs();
+ return batchStubRunner;
+ }
+
+ private String uriStringOrEmpty(Resource stubRepositoryRoot) throws IOException {
+ return stubRepositoryRoot != null ? stubRepositoryRoot.getURI().toString() : "";
+ }
+
+}
diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/resources/META-INF/spring.factories b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/resources/META-INF/spring.factories
new file mode 100644
index 0000000000..a0e462c04c
--- /dev/null
+++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/resources/META-INF/spring.factories
@@ -0,0 +1,3 @@
+# Auto Configuration
+org.springframework.cloud.contract.stubrunner.spring.AutoConfigureStubRunner=\
+org.springframework.cloud.contract.stubrunner.spring.StubRunnerConfiguration
\ No newline at end of file
diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/spring/StubRunnerConfigurationSpec.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/spring/StubRunnerConfigurationSpec.groovy
new file mode 100644
index 0000000000..6d749e0efa
--- /dev/null
+++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/spring/StubRunnerConfigurationSpec.groovy
@@ -0,0 +1,58 @@
+/*
+ * 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.spring
+
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration
+import org.springframework.boot.test.IntegrationTest;
+import org.springframework.boot.test.context.SpringBootContextLoader
+import org.springframework.cloud.contract.stubrunner.StubFinder
+import org.springframework.context.annotation.Configuration
+import org.springframework.test.context.ContextConfiguration
+
+import spock.lang.Specification
+
+/**
+ * @author Marcin Grzejszczak
+ */
+// tag::test[]
+@ContextConfiguration(classes = Config, loader = SpringBootContextLoader)
+@AutoConfigureStubRunner
+class StubRunnerConfigurationSpec extends Specification {
+
+ @Autowired StubFinder stubFinder
+
+ def 'should start WireMock servers'() {
+ expect: 'WireMocks are running'
+ stubFinder.findStubUrl('org.springframework.cloud.contract.verifier.stubs', 'loanIssuance') != null
+ stubFinder.findStubUrl('loanIssuance') != null
+ stubFinder.findStubUrl('loanIssuance') == stubFinder.findStubUrl('org.springframework.cloud.contract.verifier.stubs', 'loanIssuance')
+ stubFinder.findStubUrl('org.springframework.cloud.contract.verifier.stubs:fraudDetectionServer') != null
+ and:
+ stubFinder.findAllRunningStubs().isPresent('loanIssuance')
+ stubFinder.findAllRunningStubs().isPresent('org.springframework.cloud.contract.verifier.stubs', 'fraudDetectionServer')
+ stubFinder.findAllRunningStubs().isPresent('org.springframework.cloud.contract.verifier.stubs:fraudDetectionServer')
+ and: 'Stubs were registered'
+ "${stubFinder.findStubUrl('loanIssuance').toString()}/name".toURL().text == 'loanIssuance'
+ "${stubFinder.findStubUrl('fraudDetectionServer').toString()}/name".toURL().text == 'fraudDetectionServer'
+ }
+
+ @Configuration
+ @EnableAutoConfiguration
+ static class Config {}
+}
+// end::test[]
\ No newline at end of file
diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/application.yml b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/application.yml
new file mode 100644
index 0000000000..4f618057e1
--- /dev/null
+++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/application.yml
@@ -0,0 +1,2 @@
+stubrunner.stubs.repository.root: classpath:m2repo/repository/
+stubrunner.stubs.ids: org.springframework.cloud.contract.verifier.stubs:loanIssuance,org.springframework.cloud.contract.verifier.stubs:fraudDetectionServer
\ No newline at end of file