DiscoveryClient is optional

without this change if you want to use Spring Cloud Contract Stub Runner Cloud you need to have an implementation of Service Discovery on your classpath. That's not always what you want to have - actually the tests should be possible to be run without any backing service disvoery technology.

    This change provides the default NoOp Discovery Client in case where there is no bean of DiscoveryClient type.

    fixes #56
This commit is contained in:
Marcin Grzejszczak
2016-08-22 16:29:09 +02:00
parent 125b16edf6
commit 48aa8f763d
5 changed files with 103 additions and 10 deletions

View File

@@ -26,7 +26,7 @@
<activemq.version>5.12.1</activemq.version>
<camel.version>2.17.0</camel.version>
<spring-cloud-stream.version>1.0.2.RELEASE</spring-cloud-stream.version>
<spring-boot.version>1.4.0.RC1</spring-boot.version>
<spring-boot.version>1.4.0.RELEASE</spring-boot.version>
</properties>
<modules>

View File

@@ -46,12 +46,19 @@ class StubRunnerDiscoveryClient implements DiscoveryClient {
public StubRunnerDiscoveryClient(DiscoveryClient delegate, StubFinder stubFinder,
StubMapperProperties stubMapperProperties, String springAppName) {
this.delegate = delegate instanceof StubRunnerDiscoveryClient ?
this.delegate = delegate instanceof StubRunnerDiscoveryClient ?
noOpDiscoveryClient(springAppName) : delegate;
this.stubFinder = stubFinder;
this.stubMapperProperties = stubMapperProperties;
}
public StubRunnerDiscoveryClient(StubFinder stubFinder,
StubMapperProperties stubMapperProperties, String springAppName) {
this.delegate = noOpDiscoveryClient(springAppName);
this.stubFinder = stubFinder;
this.stubMapperProperties = stubMapperProperties;
}
private NoopDiscoveryClient noOpDiscoveryClient(String springAppName) {
return new NoopDiscoveryClient(new DefaultServiceInstance(springAppName, "localhost", 0, false));
}

View File

@@ -17,6 +17,7 @@
package org.springframework.cloud.contract.stubrunner.spring.cloud;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
@@ -46,12 +47,21 @@ public class StubRunnerSpringCloudAutoConfiguration {
}
@Bean
@ConditionalOnBean(DiscoveryClient.class)
@Primary
public DiscoveryClient stubRunnerDiscoveryClient(DiscoveryClient discoveryClient,
public DiscoveryClient stubRunnerDiscoveryClientWrapper(DiscoveryClient discoveryClient,
StubFinder stubFinder,
StubMapperProperties stubMapperProperties,
@Value("${spring.application.name:unknown}") String springAppName) {
return new StubRunnerDiscoveryClient(discoveryClient, stubFinder, stubMapperProperties, springAppName);
}
@Bean
@ConditionalOnMissingBean(DiscoveryClient.class)
public DiscoveryClient stubRunnerDiscoveryClient(StubFinder stubFinder,
StubMapperProperties stubMapperProperties,
@Value("${spring.application.name:unknown}") String springAppName) {
return new StubRunnerDiscoveryClient(stubFinder, stubMapperProperties, springAppName);
}
}

View File

@@ -21,9 +21,8 @@ import org.junit.AfterClass
import org.junit.BeforeClass
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.autoconfigure.EnableAutoConfiguration
import org.springframework.boot.test.IntegrationTest
import org.springframework.boot.test.WebIntegrationTest
import org.springframework.boot.test.context.SpringBootContextLoader
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.cloud.client.discovery.EnableDiscoveryClient
import org.springframework.cloud.client.loadbalancer.LoadBalanced
import org.springframework.cloud.contract.stubrunner.StubFinder
@@ -37,22 +36,19 @@ import org.springframework.test.annotation.DirtiesContext
import org.springframework.test.context.ContextConfiguration
import org.springframework.util.SocketUtils
import org.springframework.web.client.RestTemplate
import spock.lang.Specification
/**
* @author Marcin Grzejszczak
*/
@ContextConfiguration(classes = Config, loader = SpringBootContextLoader)
@WebIntegrationTest(randomPort = true)
@IntegrationTest("stubrunner.camel.enabled=false")
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
properties = ["stubrunner.camel.enabled=false"])
@AutoConfigureStubRunner
@DirtiesContext
class StubRunnerSpringCloudAutoConfigurationSpec extends Specification {
@Autowired StubFinder stubFinder
@Autowired @LoadBalanced RestTemplate restTemplate
// TODO: this shouldn't be needed?
@Autowired ZookeeperServiceDiscovery zookeeperServiceDiscovery
@Autowired ConfigurableApplicationContext applicationContext

View File

@@ -0,0 +1,80 @@
/*
* 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.cloud
import org.junit.AfterClass
import org.junit.BeforeClass
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.autoconfigure.EnableAutoConfiguration
import org.springframework.boot.test.context.SpringBootContextLoader
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.cloud.client.discovery.EnableDiscoveryClient
import org.springframework.cloud.client.loadbalancer.LoadBalanced
import org.springframework.cloud.contract.stubrunner.StubFinder
import org.springframework.cloud.contract.stubrunner.spring.AutoConfigureStubRunner
import org.springframework.cloud.zookeeper.discovery.RibbonZookeeperAutoConfiguration
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.test.annotation.DirtiesContext
import org.springframework.test.context.ContextConfiguration
import org.springframework.web.client.RestTemplate
import spock.lang.Specification
/**
* @author Marcin Grzejszczak
*/
@ContextConfiguration(classes = Config, loader = SpringBootContextLoader)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
properties = ["stubrunner.camel.enabled=false",
"spring.cloud.zookeeper.enabled=false",
"spring.cloud.zookeeper.discovery.enabled=false"])
@AutoConfigureStubRunner
@DirtiesContext
class StubRunnerSpringCloudAutoConfigurationWithoutDiscoverySpec extends Specification {
@Autowired StubFinder stubFinder
@Autowired @LoadBalanced RestTemplate restTemplate
@BeforeClass
@AfterClass
static void setupProps() {
System.clearProperty("stubrunner.stubs.repository.root");
System.clearProperty("stubrunner.stubs.classifier");
}
// tag::test[]
def 'should make service discovery work'() {
expect: 'WireMocks are running'
"${stubFinder.findStubUrl('loanIssuance').toString()}/name".toURL().text == 'loanIssuance'
"${stubFinder.findStubUrl('fraudDetectionServer').toString()}/name".toURL().text == 'fraudDetectionServer'
and: 'Stubs can be reached via load service discovery'
restTemplate.getForObject('http://loanIssuance/name', String) == 'loanIssuance'
restTemplate.getForObject('http://someNameThatShouldMapFraudDetectionServer/name', String) == 'fraudDetectionServer'
}
// end::test[]
@Configuration
@EnableAutoConfiguration(exclude = [RibbonZookeeperAutoConfiguration])
@EnableDiscoveryClient
static class Config {
@Bean
@LoadBalanced
RestTemplate restTemplate() {
return new RestTemplate()
}
}
}