From 37cee4ccda9e1f8ac94c547f2f6bec15d2ae3350 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Tue, 29 Mar 2016 22:40:20 +0200 Subject: [PATCH] Spring Cloud integration --- .../dsl/WireMockRequestStubStrategy.groovy | 2 +- build.gradle | 12 +++ settings.gradle | 1 + .../stubrunner/junit/AccurestRule.java | 2 +- .../stub-runner-spring-cloud/README.md | 13 +++ .../stub-runner-spring-cloud/build.gradle | 25 +++++ .../spring/cloud/StubMapperProperties.java | 55 ++++++++++ .../cloud/StubRunnerDiscoveryClient.java | 72 ++++++++++++++ .../cloud/StubRunnerServiceInstance.java | 57 +++++++++++ ...tubRunnerSpringCloudAutoConfiguration.java | 39 ++++++++ .../StubRunnerRibbonAutoConfiguration.java | 17 ++++ .../ribbon/StubRunnerRibbonConfiguration.java | 94 ++++++++++++++++++ .../main/resources/META-INF/spring.factories | 4 + ...nerSpringCloudAutoConfigurationSpec.groovy | 58 +++++++++++ .../src/test/resources/application.yml | 6 ++ .../src/test/resources/logback.xml | 14 +++ ...udDetectionServer-stubs-0.0.1-SNAPSHOT.jar | Bin 0 -> 1733 bytes ...udDetectionServer-stubs-0.0.1-SNAPSHOT.pom | 8 ++ .../0.0.1-SNAPSHOT/maven-metadata-local.xml | 12 +++ .../maven-metadata-local.xml | 11 ++ .../loanIssuance-stubs-0.0.1-SNAPSHOT.jar | Bin 0 -> 587 bytes .../loanIssuance-stubs-0.0.1-SNAPSHOT.pom | 8 ++ .../0.0.1-SNAPSHOT/maven-metadata-local.xml | 12 +++ .../maven-metadata-local.xml | 11 ++ stub-runner/stub-runner-spring/README.md | 2 +- stub-runner/stub-runner-spring/build.gradle | 4 +- .../spring/StubRunnerConfiguration.java | 2 +- .../src/test/resources/application.yml | 2 +- stub-runner/stub-runner/build.gradle | 1 - .../accurest/stubrunner/RunningStubs.groovy | 34 +++---- 30 files changed, 553 insertions(+), 25 deletions(-) create mode 100644 stub-runner/stub-runner-spring-cloud/README.md create mode 100644 stub-runner/stub-runner-spring-cloud/build.gradle create mode 100644 stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/StubMapperProperties.java create mode 100644 stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/StubRunnerDiscoveryClient.java create mode 100644 stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/StubRunnerServiceInstance.java create mode 100644 stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/StubRunnerSpringCloudAutoConfiguration.java create mode 100644 stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/ribbon/StubRunnerRibbonAutoConfiguration.java create mode 100644 stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/ribbon/StubRunnerRibbonConfiguration.java create mode 100644 stub-runner/stub-runner-spring-cloud/src/main/resources/META-INF/spring.factories create mode 100644 stub-runner/stub-runner-spring-cloud/src/test/groovy/io/codearte/accurest/stubrunner/spring/cloud/StubRunnerSpringCloudAutoConfigurationSpec.groovy create mode 100644 stub-runner/stub-runner-spring-cloud/src/test/resources/application.yml create mode 100644 stub-runner/stub-runner-spring-cloud/src/test/resources/logback.xml create mode 100644 stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/0.0.1-SNAPSHOT/fraudDetectionServer-stubs-0.0.1-SNAPSHOT.jar create mode 100644 stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/0.0.1-SNAPSHOT/fraudDetectionServer-stubs-0.0.1-SNAPSHOT.pom create mode 100644 stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/0.0.1-SNAPSHOT/maven-metadata-local.xml create mode 100644 stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/maven-metadata-local.xml create mode 100644 stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/0.0.1-SNAPSHOT/loanIssuance-stubs-0.0.1-SNAPSHOT.jar create mode 100644 stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/0.0.1-SNAPSHOT/loanIssuance-stubs-0.0.1-SNAPSHOT.pom create mode 100644 stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/0.0.1-SNAPSHOT/maven-metadata-local.xml create mode 100644 stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/maven-metadata-local.xml diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockRequestStubStrategy.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockRequestStubStrategy.groovy index 194a405237..1c3bbb6016 100755 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockRequestStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockRequestStubStrategy.groovy @@ -68,7 +68,7 @@ class WireMockRequestStubStrategy extends BaseWireMockStubStrategy { requestPattern.bodyPatterns = [new ValuePattern(jsonCompareMode: org.skyscreamer.jsonassert.JSONCompareMode.LENIENT, equalToJson: JsonOutput.toJson(getMatchingStrategy(request.body.clientValue).clientValue) ) ] } else { - requestPattern.bodyPatterns = values.collect { new ValuePattern(matchesJsonPath: it.jsonPath().replace("\\\\", "\\")) } ?: null + requestPattern.bodyPatterns = values.collect { new ValuePattern(matchesJsonPath: it.jsonPath().replace("\\\\", "\\")) } ?: null as List } } else if (contentType == ContentType.XML) { requestPattern.bodyPatterns = [new ValuePattern(equalToXml: getMatchingStrategy(request.body.clientValue).clientValue.toString())] diff --git a/build.gradle b/build.gradle index ba9586b76a..96908af878 100644 --- a/build.gradle +++ b/build.gradle @@ -61,6 +61,18 @@ subprojects { exclude(group: 'org.codehaus.groovy') } } + + // fixing the groovydoc issue http://stackoverflow.com/questions/20618857/gradle-task-groovydoc-failing-with-noclassdeffounderror + configurations { + jansi.extendsFrom(runtime) + } + groovydoc { + def title = "IPDS ${version}" + groovyClasspath = project.configurations.jansi + } + dependencies { + jansi 'org.fusesource.jansi:jansi:1.11' + } } project(':accurest-core') { diff --git a/settings.gradle b/settings.gradle index 762abc0c49..cbe81d5e33 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,6 +1,7 @@ include "accurest-core", "accurest-gradle-plugin", 'accurest-converters', 'accurest-testing-utils' include ':stub-runner:stub-runner' include ':stub-runner:stub-runner-spring' +include ':stub-runner:stub-runner-spring-cloud' include ':stub-runner:stub-runner-junit' rootProject.name = "accurest" diff --git a/stub-runner/stub-runner-junit/src/main/groovy/io/codearte/accurest/stubrunner/junit/AccurestRule.java b/stub-runner/stub-runner-junit/src/main/groovy/io/codearte/accurest/stubrunner/junit/AccurestRule.java index 6236e5d710..a47e4e9e8d 100644 --- a/stub-runner/stub-runner-junit/src/main/groovy/io/codearte/accurest/stubrunner/junit/AccurestRule.java +++ b/stub-runner/stub-runner-junit/src/main/groovy/io/codearte/accurest/stubrunner/junit/AccurestRule.java @@ -58,7 +58,7 @@ public class AccurestRule implements TestRule, StubFinder { String repoRoot = System.getProperty("stubrunner.stubs.repository.root", ""); String stubSuffix = System.getProperty("stubrunner.stubs.classifier", "stubs"); Boolean workOffline = Boolean.parseBoolean(System.getProperty("stubrunner.work-offline", "false")); - String stubsToDownload = System.getProperty("stubrunner.stubs", ""); + String stubsToDownload = System.getProperty("stubrunner.stubs.ids", ""); if (StringUtils.hasText(stubsToDownload)) { Collections.addAll(stubs, stubsToDownload.split(",")); } diff --git a/stub-runner/stub-runner-spring-cloud/README.md b/stub-runner/stub-runner-spring-cloud/README.md new file mode 100644 index 0000000000..06399b13a0 --- /dev/null +++ b/stub-runner/stub-runner-spring-cloud/README.md @@ -0,0 +1,13 @@ +stub-runner-spring-cloud +======================== + +Registers the stubs in the provided Service Discovery. It's enough to add the jar + +``` +io.codearte.accurest:stub-runner-spring-cloud +``` + +and the Stub Runner autoconfiguration should be picked up. + +In order to find the registered server via service discovery, you have to use the +`artifactId` as the name of the application \ No newline at end of file diff --git a/stub-runner/stub-runner-spring-cloud/build.gradle b/stub-runner/stub-runner-spring-cloud/build.gradle new file mode 100644 index 0000000000..96d86c8ac1 --- /dev/null +++ b/stub-runner/stub-runner-spring-cloud/build.gradle @@ -0,0 +1,25 @@ +description = 'Spring configuration for stub-runner' + +dependencies { + compile project(':stub-runner-root:stub-runner-spring') + + compile localGroovy() + compile 'org.springframework.cloud:spring-cloud-starter:[1.1.0.RC2,)' + // TODO: should be compile only + compile 'org.springframework.cloud:spring-cloud-starter-ribbon:[1.1.0.RC1,)' + + testCompile('org.spockframework:spock-core:1.0-groovy-2.3') { + exclude(group: 'org.codehaus.groovy') + } + testCompile 'cglib:cglib-nodep:2.2' + testCompile 'org.objenesis:objenesis:2.1' + testCompile 'org.springframework.cloud:spring-cloud-starter-zookeeper-discovery:1.0.0.RC1' + testCompile 'org.apache.curator:curator-test:2.9.1' + testCompile 'io.reactivex:rxjava:1.1.1' + testCompile 'org.springframework.boot:spring-boot-starter-test:1.3.3.RELEASE' + testCompile "org.springframework:spring-web:4.2.5.RELEASE" + testCompile('org.spockframework:spock-spring:1.0-groovy-2.3') { + exclude(group: 'org.codehaus.groovy') + } + testCompile 'ch.qos.logback:logback-classic:1.1.3' +} diff --git a/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/StubMapperProperties.java b/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/StubMapperProperties.java new file mode 100644 index 0000000000..c69ca674dc --- /dev/null +++ b/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/StubMapperProperties.java @@ -0,0 +1,55 @@ +package io.codearte.accurest.stubrunner.spring.cloud; + +import java.util.HashMap; +import java.util.Map; + +import org.springframework.boot.context.properties.ConfigurationProperties; + +/** + * Maps Ivy based ids to service Ids. You might want to name the service you're calling + * in another way than artifact id. If that's the case then this class should be used + * to change do the proper mapping. + * + * Just provide in your properties file for example: + * + * stubrunner.stubs.idsToServiceIds: + * ivyNotation: someValueInsideYourCode + * fraudDetectionServer: someNameThatShouldMapFraudDetectionServer + * + * @author Marcin Grzejszczak + */ +@ConfigurationProperties("stubrunner.stubs") +public class StubMapperProperties { + + /** + * Mapping of Ivy notation based ids to serviceIds + * inside your application + * + * Example + * + * "a:b" -> "myService" + * "artifactId" -> "myOtherService" + */ + private Map idsToServiceIds = new HashMap<>(); + + public Map getIdsToServiceIds() { + return this.idsToServiceIds; + } + + public void setIdsToServiceIds(Map idsToServiceIds) { + this.idsToServiceIds = idsToServiceIds; + } + + public String fromIvyNotationToId(String ivyNotation) { + return idsToServiceIds.get(ivyNotation); + } + + public String fromServiceIdToIvyNotation(String serviceId) { + for (Map.Entry entry : idsToServiceIds.entrySet()) { + if (entry.getValue().equals(serviceId)) { + return entry.getKey(); + } + } + return null; + } +} diff --git a/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/StubRunnerDiscoveryClient.java b/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/StubRunnerDiscoveryClient.java new file mode 100644 index 0000000000..66b7deb07e --- /dev/null +++ b/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/StubRunnerDiscoveryClient.java @@ -0,0 +1,72 @@ +package io.codearte.accurest.stubrunner.spring.cloud; + +import java.net.URI; +import java.net.URL; +import java.util.Collections; +import java.util.List; + +import org.springframework.cloud.client.ServiceInstance; +import org.springframework.cloud.client.discovery.DiscoveryClient; + +import io.codearte.accurest.stubrunner.RunningStubs; +import io.codearte.accurest.stubrunner.StubFinder; +import io.codearte.accurest.stubrunner.util.StringUtils; + +/** + * Custom version of {@link DiscoveryClient} that tries to find an instance + * in one of the started WireMock servers + * + * @author Marcin Grzejszczak + */ +public class StubRunnerDiscoveryClient implements DiscoveryClient { + + private final DiscoveryClient delegate; + private final StubFinder stubFinder; + private final StubMapperProperties stubMapperProperties; + + public StubRunnerDiscoveryClient(DiscoveryClient delegate, StubFinder stubFinder, + StubMapperProperties stubMapperProperties) { + this.delegate = delegate; + this.stubFinder = stubFinder; + this.stubMapperProperties = stubMapperProperties; + } + + @Override + public String description() { + return delegate.description(); + } + + @Override + public ServiceInstance getLocalServiceInstance() { + return delegate.getLocalServiceInstance(); + } + + @Override + public List getInstances(String serviceId) { + String ivyNotation = stubMapperProperties.fromServiceIdToIvyNotation(serviceId); + String serviceToFind = StringUtils.hasText(ivyNotation) ? ivyNotation : serviceId; + URL stubUrl = stubFinder.findStubUrl(serviceToFind); + if (stubUrl == null) { + return delegate.getInstances(serviceId); + } + return Collections.singletonList( + new StubRunnerServiceInstance(serviceId, stubUrl.getHost(), stubUrl.getPort(), toUri(stubUrl)) + ); + } + + private URI toUri(URL url) { + try { + return url.toURI(); + } catch (Exception e) { + return null; + } + } + + @Override + public List getServices() { + List services = delegate.getServices(); + RunningStubs runningStubs = stubFinder.findAllRunningStubs(); + services.addAll(runningStubs.getAllServicesNames()); + return services; + } +} diff --git a/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/StubRunnerServiceInstance.java b/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/StubRunnerServiceInstance.java new file mode 100644 index 0000000000..ba5ee8249f --- /dev/null +++ b/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/StubRunnerServiceInstance.java @@ -0,0 +1,57 @@ +package io.codearte.accurest.stubrunner.spring.cloud; + +import java.net.URI; +import java.util.HashMap; +import java.util.Map; + +import org.springframework.cloud.client.ServiceInstance; + +/** + * {@link ServiceInstance} with a helpful constructor + * + * @author Marcin Grzejszczak + */ +public class StubRunnerServiceInstance implements ServiceInstance { + + private final String serviceId; + private final String host; + private final int port; + private final URI uri; + + public StubRunnerServiceInstance(String serviceId, String host, int port, URI uri) { + this.serviceId = serviceId; + this.host = host; + this.port = port; + this.uri = uri; + } + + @Override + public String getServiceId() { + return serviceId; + } + + @Override + public String getHost() { + return host; + } + + @Override + public int getPort() { + return port; + } + + @Override + public boolean isSecure() { + return false; + } + + @Override + public URI getUri() { + return uri; + } + + @Override + public Map getMetadata() { + return new HashMap<>(); + } +} diff --git a/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/StubRunnerSpringCloudAutoConfiguration.java b/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/StubRunnerSpringCloudAutoConfiguration.java new file mode 100644 index 0000000000..b759304230 --- /dev/null +++ b/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/StubRunnerSpringCloudAutoConfiguration.java @@ -0,0 +1,39 @@ +package io.codearte.accurest.stubrunner.spring.cloud; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.cloud.client.discovery.DiscoveryClient; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.context.annotation.Primary; + +import io.codearte.accurest.stubrunner.StubFinder; +import io.codearte.accurest.stubrunner.spring.StubRunnerConfiguration; + +/** + * Wraps {@link DiscoveryClient} in a Stub Runner implementation that tries to find + * a corresponding WireMock server for a searched dependency + */ +@Configuration +@EnableConfigurationProperties +@ConditionalOnClass(DiscoveryClient.class) +@Import(StubRunnerConfiguration.class) +public class StubRunnerSpringCloudAutoConfiguration { + + @Bean + @ConditionalOnMissingBean + public StubMapperProperties stubMapperProperties() { + return new StubMapperProperties(); + } + + @Bean + @Primary + public DiscoveryClient stubRunnerDiscoveryClient(DiscoveryClient discoveryClient, + StubFinder stubFinder, + StubMapperProperties stubMapperProperties) { + return new StubRunnerDiscoveryClient(discoveryClient, stubFinder, stubMapperProperties); + } + +} diff --git a/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/ribbon/StubRunnerRibbonAutoConfiguration.java b/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/ribbon/StubRunnerRibbonAutoConfiguration.java new file mode 100644 index 0000000000..523f499076 --- /dev/null +++ b/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/ribbon/StubRunnerRibbonAutoConfiguration.java @@ -0,0 +1,17 @@ +package io.codearte.accurest.stubrunner.spring.cloud.ribbon; + +import org.springframework.boot.autoconfigure.AutoConfigureAfter; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration; +import org.springframework.cloud.netflix.ribbon.RibbonClients; +import org.springframework.context.annotation.Configuration; + +import com.netflix.loadbalancer.ServerList; + +@Configuration +@ConditionalOnClass(ServerList.class) +@AutoConfigureAfter(RibbonAutoConfiguration.class) +@RibbonClients(defaultConfiguration = StubRunnerRibbonConfiguration.class) +public class StubRunnerRibbonAutoConfiguration { + +} diff --git a/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/ribbon/StubRunnerRibbonConfiguration.java b/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/ribbon/StubRunnerRibbonConfiguration.java new file mode 100644 index 0000000000..c598caeaab --- /dev/null +++ b/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/ribbon/StubRunnerRibbonConfiguration.java @@ -0,0 +1,94 @@ +package io.codearte.accurest.stubrunner.spring.cloud.ribbon; + +import java.net.URI; +import java.net.URL; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; + +import com.netflix.client.config.IClientConfig; +import com.netflix.loadbalancer.Server; +import com.netflix.loadbalancer.ServerList; + +import io.codearte.accurest.stubrunner.RunningStubs; +import io.codearte.accurest.stubrunner.StubConfiguration; +import io.codearte.accurest.stubrunner.StubFinder; +import io.codearte.accurest.stubrunner.spring.cloud.StubMapperProperties; +import io.codearte.accurest.stubrunner.util.StringUtils; + +/** + * Ribbon AutoConfiguration that manipulates the service id to make the service + * be picked from the list of available WireMock instance if one is available. + * + * @author Marcin Grzejszczak + */ +@Configuration +public class StubRunnerRibbonConfiguration { + + @Bean + @Primary + @SuppressWarnings("unchecked") + public ServerList stubRunnerRibbonServerList(final ServerList serverList, + StubFinder stubFinder, + final StubMapperProperties stubMapperProperties, + IClientConfig clientConfig) { + String serviceName = clientConfig.getClientName(); + String mappedServiceName = StringUtils + .hasText(stubMapperProperties.fromServiceIdToIvyNotation(serviceName)) ? + stubMapperProperties.fromServiceIdToIvyNotation(serviceName) : serviceName; + RunningStubs runningStubs = stubFinder.findAllRunningStubs(); + final Map.Entry entry = runningStubs.getEntry(mappedServiceName); + final Collection servers = new ArrayList(); + if (entry != null) { + servers.add(new Server("localhost", entry.getValue()) { + @Override + public MetaInfo getMetaInfo() { + return new MetaInfo() { + @Override + public String getAppName() { + return stubMapperProperties.fromIvyNotationToId(entry.getKey().toColonSeparatedDependencyNotation()); + } + + @Override + public String getServerGroup() { + return null; + } + + @Override + public String getServiceIdForDiscovery() { + return stubMapperProperties.fromIvyNotationToId(entry.getKey().getArtifactId()); + } + + @Override + public String getInstanceId() { + return stubMapperProperties.fromIvyNotationToId(entry.getKey().getArtifactId()); + } + }; + } + }); + } + return new ServerList() { + @Override + public List getInitialListOfServers() { + List combinedList = new ArrayList<>(); + combinedList.addAll(servers); + combinedList.addAll(serverList.getInitialListOfServers()); + return combinedList; + } + + @Override + public List getUpdatedListOfServers() { + List combinedList = new ArrayList<>(); + combinedList.addAll(servers); + combinedList.addAll(serverList.getUpdatedListOfServers()); + return combinedList; + } + }; + } + +} diff --git a/stub-runner/stub-runner-spring-cloud/src/main/resources/META-INF/spring.factories b/stub-runner/stub-runner-spring-cloud/src/main/resources/META-INF/spring.factories new file mode 100644 index 0000000000..60fb0401e6 --- /dev/null +++ b/stub-runner/stub-runner-spring-cloud/src/main/resources/META-INF/spring.factories @@ -0,0 +1,4 @@ +# Auto Configuration +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ +io.codearte.accurest.stubrunner.spring.cloud.StubRunnerSpringCloudAutoConfiguration,\ +io.codearte.accurest.stubrunner.spring.cloud.ribbon.StubRunnerRibbonAutoConfiguration diff --git a/stub-runner/stub-runner-spring-cloud/src/test/groovy/io/codearte/accurest/stubrunner/spring/cloud/StubRunnerSpringCloudAutoConfigurationSpec.groovy b/stub-runner/stub-runner-spring-cloud/src/test/groovy/io/codearte/accurest/stubrunner/spring/cloud/StubRunnerSpringCloudAutoConfigurationSpec.groovy new file mode 100644 index 0000000000..741d7ccbe0 --- /dev/null +++ b/stub-runner/stub-runner-spring-cloud/src/test/groovy/io/codearte/accurest/stubrunner/spring/cloud/StubRunnerSpringCloudAutoConfigurationSpec.groovy @@ -0,0 +1,58 @@ +package io.codearte.accurest.stubrunner.spring.cloud + +import io.codearte.accurest.stubrunner.StubFinder +import org.apache.curator.test.TestingServer +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.boot.autoconfigure.EnableAutoConfiguration +import org.springframework.boot.test.SpringApplicationContextLoader +import org.springframework.boot.test.WebIntegrationTest +import org.springframework.cloud.client.discovery.EnableDiscoveryClient +import org.springframework.cloud.client.loadbalancer.LoadBalanced +import org.springframework.cloud.zookeeper.discovery.ZookeeperServiceDiscovery +import org.springframework.context.ConfigurableApplicationContext +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration +import org.springframework.test.context.ContextConfiguration +import org.springframework.web.client.RestTemplate +import spock.lang.AutoCleanup +import spock.lang.Shared +import spock.lang.Specification + +/** + * @author Marcin Grzejszczak + */ +@ContextConfiguration(classes = Config, loader = SpringApplicationContextLoader) +@WebIntegrationTest(randomPort = true) +class StubRunnerSpringCloudAutoConfigurationSpec extends Specification { + + @Autowired StubFinder stubFinder + @Autowired @LoadBalanced RestTemplate restTemplate + @Autowired ZookeeperServiceDiscovery zookeeperServiceDiscovery + @Autowired ConfigurableApplicationContext applicationContext + @Shared @AutoCleanup TestingServer testingServer = new TestingServer(2181) + + 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' + } + + def cleanup() { + zookeeperServiceDiscovery.serviceDiscovery.close() + applicationContext.close() + } + + @Configuration + @EnableAutoConfiguration + @EnableDiscoveryClient + static class Config { + @Bean + @LoadBalanced + RestTemplate restTemplate() { + return new RestTemplate() + } + } +} diff --git a/stub-runner/stub-runner-spring-cloud/src/test/resources/application.yml b/stub-runner/stub-runner-spring-cloud/src/test/resources/application.yml new file mode 100644 index 0000000000..686861b073 --- /dev/null +++ b/stub-runner/stub-runner-spring-cloud/src/test/resources/application.yml @@ -0,0 +1,6 @@ +stubrunner.stubs.repository.root: classpath:m2repo +stubrunner.stubs.ids: io.codearte.accurest.stubs:loanIssuance,io.codearte.accurest.stubs:fraudDetectionServer + +stubrunner.stubs.idsToServiceIds: + ivyNotation: someValueInsideYourCode + fraudDetectionServer: someNameThatShouldMapFraudDetectionServer \ No newline at end of file diff --git a/stub-runner/stub-runner-spring-cloud/src/test/resources/logback.xml b/stub-runner/stub-runner-spring-cloud/src/test/resources/logback.xml new file mode 100644 index 0000000000..0cfb35f4cd --- /dev/null +++ b/stub-runner/stub-runner-spring-cloud/src/test/resources/logback.xml @@ -0,0 +1,14 @@ + + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + \ No newline at end of file diff --git a/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/0.0.1-SNAPSHOT/fraudDetectionServer-stubs-0.0.1-SNAPSHOT.jar b/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/0.0.1-SNAPSHOT/fraudDetectionServer-stubs-0.0.1-SNAPSHOT.jar new file mode 100644 index 0000000000000000000000000000000000000000..a29a63180218c9e81bc924a09c14be4b4619b519 GIT binary patch literal 1733 zcmWIWW@h1HVBp|j&}pplU;qLp5CH_7KE;?7qUY=O+4sz8A8%c~i@e^tTIbH3-yCFc#rVO~M^BlM4AaJ9Yi?peL1tch zF@~)`i{Q?a1G3=?(~1&HQ(RI@Qj<$E^YemJi^@`qFm#)($XO`C$iN^4^r0<5-NhOC zr8z0SiACAYIhm<>C62{@`6X^3d-Sr3^Yf-oIO})VK%nJ)EmwAHh=8K+>H4Ky0r>?A zO$Aw11}7IS*-_T<)+=;M`TJYGipPsKsJ^e*KX-200f{R=k^`j^g0Eeet+h?;9qZ!t zvu@jH8~kod&|iB|MC*IjpNTT7=4;(Qc1L2((z08Nly|b_aV(g>b<&r`ALgoew_iSP zAgt;oyx8qvnz5OTzux+F`FZc(Eq-`YsHR?8hFPfV^zyBnE?Mv;I$7=K*!IRp>_qXJ zulMJL%+}64am01g+70>>TvirL)Ua<4pQ>S;=cVc{J+s|zdV#TB{6y&&Rksd4%xkV) zw<{><`;G;?=GUxexCH83+b{7vSo~b?effXm)=aMT`kE}755s0yvge=3)bhN zHtRJ0_w^Uvp~dWh_1B^lfI+SW400|{&L}2ObW6#xm4R{M5 zg!I1K@Ejd<- zKQ^=2ShZI*X6bIB-Az;1sQWBA<)56Y+0`@C>Eyq#XA{d+Z}I6}FH_H`p7r2|`NM;u zv05vwV=lDKyp?az^SH0L?!>&N=jZ0!&fhob(2PT;Yj#yE6A1E-Nq#nMhVtg-y|;d) zPf^ej!3mD%0Kx{~4xCbXzdZgy$SsX# z0a{+VI=;Gkfk7LBR*~db; zfeD6@NrV}95d?HS5C|~5bp+Ay0tsCkdVvH|3<66UHGw2t8&dIvYy!4Y2&^4w@n6R> zAQN8HAZtS}GC^e$1c0>72QuN>u$EBhW}%l*Fw?d)-X&-jf$|F3Dv)o{b0)&70AOCl p?`%w~5cw3{9`uxmu;&CbarU63%K&dyHjokQK&S_FXd?@V2LP^BMu-3a literal 0 HcmV?d00001 diff --git a/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/0.0.1-SNAPSHOT/fraudDetectionServer-stubs-0.0.1-SNAPSHOT.pom b/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/0.0.1-SNAPSHOT/fraudDetectionServer-stubs-0.0.1-SNAPSHOT.pom new file mode 100644 index 0000000000..2a8b40b197 --- /dev/null +++ b/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/0.0.1-SNAPSHOT/fraudDetectionServer-stubs-0.0.1-SNAPSHOT.pom @@ -0,0 +1,8 @@ + + + 4.0.0 + io.codearte.accurest.stubs + fraudDetectionServer-stubs + 0.0.1-SNAPSHOT + diff --git a/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/0.0.1-SNAPSHOT/maven-metadata-local.xml b/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/0.0.1-SNAPSHOT/maven-metadata-local.xml new file mode 100644 index 0000000000..5e2fc1d528 --- /dev/null +++ b/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/0.0.1-SNAPSHOT/maven-metadata-local.xml @@ -0,0 +1,12 @@ + + + io.codearte.accurest.stubs + fraudDetectionServer-stubs + 0.0.1-SNAPSHOT + + + true + + 20160326150924 + + diff --git a/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/maven-metadata-local.xml b/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/maven-metadata-local.xml new file mode 100644 index 0000000000..46fa17218f --- /dev/null +++ b/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/maven-metadata-local.xml @@ -0,0 +1,11 @@ + + + io.codearte.accurest.stubs + fraudDetectionServer-stubs + + + 0.0.1-SNAPSHOT + + 20160326150924 + + diff --git a/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/0.0.1-SNAPSHOT/loanIssuance-stubs-0.0.1-SNAPSHOT.jar b/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/0.0.1-SNAPSHOT/loanIssuance-stubs-0.0.1-SNAPSHOT.jar new file mode 100644 index 0000000000000000000000000000000000000000..12d6b10f29e2a1b6c25afea27910ef6af0c4f3ce GIT binary patch literal 587 zcmWIWW@h1HVBp|j&}pplU;qLp5CH_7KE;?7qUY=O+4sz8A8%c~i@e^tTIbH3-yCFc#rVO~M^Bm13@$;1F;Mc!xa{1tz+^=dFGg6cC{0rK{tss}~rw zA!r5Lr$(ivu9gb(Ce_6y<*k~;=VD;KRYlpJRp;G1sYNUzYpynC=c`K+U-=X=K6k9GE;P;Q_n7@0(vaR(mIfj}U@@YWGT z!-EoC8+uTJ6obH$Mol0I*M=0Z=q7+vBgYzu53=~LV;PW!2NJqA^w0$B0uoyq=Ob&w V61D-}tZX3FEI{}RNLw?4cmNRMhR*;1 literal 0 HcmV?d00001 diff --git a/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/0.0.1-SNAPSHOT/loanIssuance-stubs-0.0.1-SNAPSHOT.pom b/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/0.0.1-SNAPSHOT/loanIssuance-stubs-0.0.1-SNAPSHOT.pom new file mode 100644 index 0000000000..a296158345 --- /dev/null +++ b/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/0.0.1-SNAPSHOT/loanIssuance-stubs-0.0.1-SNAPSHOT.pom @@ -0,0 +1,8 @@ + + + 4.0.0 + io.codearte.accurest.stubs + loanIssuance-stubs + 0.0.1-SNAPSHOT + diff --git a/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/0.0.1-SNAPSHOT/maven-metadata-local.xml b/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/0.0.1-SNAPSHOT/maven-metadata-local.xml new file mode 100644 index 0000000000..f33521f12d --- /dev/null +++ b/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/0.0.1-SNAPSHOT/maven-metadata-local.xml @@ -0,0 +1,12 @@ + + + io.codearte.accurest.stubs + loanIssuance-stubs + 0.0.1-SNAPSHOT + + + true + + 20160326150924 + + diff --git a/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/maven-metadata-local.xml b/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/maven-metadata-local.xml new file mode 100644 index 0000000000..e990fad0bc --- /dev/null +++ b/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/maven-metadata-local.xml @@ -0,0 +1,11 @@ + + + io.codearte.accurest.stubs + loanIssuance-stubs + + + 0.0.1-SNAPSHOT + + 20160326150924 + + diff --git a/stub-runner/stub-runner-spring/README.md b/stub-runner/stub-runner-spring/README.md index c6d26a1386..5fbe827657 100644 --- a/stub-runner/stub-runner-spring/README.md +++ b/stub-runner/stub-runner-spring/README.md @@ -32,5 +32,5 @@ for the following configuration file: ``` stubrunner.stubs.repository.root: classpath:m2repo -stubrunner.stubs: io.codearte.accurest.stubs:loanIssuance,io.codearte.accurest.stubs:fraudDetectionServer +stubrunner.stubs.ids: io.codearte.accurest.stubs:loanIssuance,io.codearte.accurest.stubs:fraudDetectionServer ``` \ No newline at end of file diff --git a/stub-runner/stub-runner-spring/build.gradle b/stub-runner/stub-runner-spring/build.gradle index 3df19ddb06..cf735ddc98 100644 --- a/stub-runner/stub-runner-spring/build.gradle +++ b/stub-runner/stub-runner-spring/build.gradle @@ -13,6 +13,8 @@ dependencies { testCompile 'org.objenesis:objenesis:2.1' testCompile 'org.springframework.boot:spring-boot-starter:1.3.3.RELEASE' testCompile 'org.springframework.boot:spring-boot-starter-test:1.3.3.RELEASE' - testCompile 'org.spockframework:spock-spring:1.0-groovy-2.3' + testCompile('org.spockframework:spock-spring:1.0-groovy-2.3') { + exclude(group: 'org.codehaus.groovy') + } testCompile 'ch.qos.logback:logback-classic:1.1.3' } diff --git a/stub-runner/stub-runner-spring/src/main/groovy/io/codearte/accurest/stubrunner/spring/StubRunnerConfiguration.java b/stub-runner/stub-runner-spring/src/main/groovy/io/codearte/accurest/stubrunner/spring/StubRunnerConfiguration.java index ebc373b762..0e803b4284 100644 --- a/stub-runner/stub-runner-spring/src/main/groovy/io/codearte/accurest/stubrunner/spring/StubRunnerConfiguration.java +++ b/stub-runner/stub-runner-spring/src/main/groovy/io/codearte/accurest/stubrunner/spring/StubRunnerConfiguration.java @@ -41,7 +41,7 @@ public class StubRunnerConfiguration { @Value("${stubrunner.stubs.repository.root:}") Resource stubRepositoryRoot, @Value("${stubrunner.stubs.classifier:stubs}") String stubsSuffix, @Value("${stubrunner.work-offline:false}") boolean workOffline, - @Value("${stubrunner.stubs:}") String stubs) throws IOException { + @Value("${stubrunner.stubs.ids:}") String stubs) throws IOException { StubRunnerOptions stubRunnerOptions = new StubRunnerOptions(minPortValue, maxPortValue, uriStringOrEmpty(stubRepositoryRoot), stubRepositoryRoot == null || workOffline, stubsSuffix); Set dependencies = StubsParser.fromString(stubs, stubsSuffix); diff --git a/stub-runner/stub-runner-spring/src/test/resources/application.yml b/stub-runner/stub-runner-spring/src/test/resources/application.yml index 4b48d59b25..0cb44fd948 100644 --- a/stub-runner/stub-runner-spring/src/test/resources/application.yml +++ b/stub-runner/stub-runner-spring/src/test/resources/application.yml @@ -1,2 +1,2 @@ stubrunner.stubs.repository.root: classpath:m2repo -stubrunner.stubs: io.codearte.accurest.stubs:loanIssuance,io.codearte.accurest.stubs:fraudDetectionServer \ No newline at end of file +stubrunner.stubs.ids: io.codearte.accurest.stubs:loanIssuance,io.codearte.accurest.stubs:fraudDetectionServer \ No newline at end of file diff --git a/stub-runner/stub-runner/build.gradle b/stub-runner/stub-runner/build.gradle index 3fa0ed3b75..3ee78c7685 100644 --- a/stub-runner/stub-runner/build.gradle +++ b/stub-runner/stub-runner/build.gradle @@ -9,7 +9,6 @@ dependencies { compile "com.github.tomakehurst:wiremock:$wiremockVersion" compile 'javax.servlet:javax.servlet-api:3.1.0' compile 'args4j:args4j:2.32' - compile 'com.nurkiewicz.asyncretry:asyncretry-jdk7:0.0.6' if (rootProject.hasProperty("fatJar")) runtime 'ch.qos.logback:logback-classic:1.1.3' diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/RunningStubs.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/RunningStubs.groovy index c856dd9dd2..6c1d683fba 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/RunningStubs.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/RunningStubs.groovy @@ -23,21 +23,25 @@ class RunningStubs { } Integer getPort(String artifactId) { + return getEntry(artifactId)?.value + } + + Map.Entry getEntry(String artifactId) { def strings = artifactId.split(':') if (strings.length == 1) { return namesAndPorts.entrySet().find { it.key.artifactId == artifactId - }?.value + } } else if(strings.length == 2) { return namesAndPorts.entrySet().find { it.key.groupId == strings[0] && it.key.artifactId == strings[1] - }?.value + } } return namesAndPorts.entrySet().find { it.key.groupId == strings[0] && it.key.artifactId == strings[1] && it.key.classifier == strings[2] - }?.value + } } Integer getPort(String groupId, String artifactId) { @@ -47,21 +51,7 @@ class RunningStubs { } boolean isPresent(String artifactId) { - def strings = artifactId.split(':') - if (strings.length == 1) { - return namesAndPorts.entrySet().find { - it.key.artifactId == artifactId - } - } else if(strings.length == 2) { - return namesAndPorts.entrySet().find { - it.key.groupId == strings[0] && it.key.artifactId == strings[1] - } - } - return namesAndPorts.entrySet().find { - it.key.groupId == strings[0] && - it.key.artifactId == strings[1] && - it.key.classifier == strings[2] - } + return getEntry(artifactId) } boolean isPresent(String groupId, String artifactId) { @@ -70,6 +60,14 @@ class RunningStubs { } } + Set getAllServices() { + return namesAndPorts.keySet() + } + + Set getAllServicesNames() { + return namesAndPorts.keySet().collect { it.artifactId } as Set + } + @Override String toString() { return namesAndPorts.collect {