diff --git a/README.adoc b/README.adoc
index 36e6bb57a8..8bab5e7f92 100644
--- a/README.adoc
+++ b/README.adoc
@@ -1311,7 +1311,7 @@ Example of a `pom.xml` inside the `server` folder.
UTF-8
1.8
- 1.0.2.BUILD-SNAPSHOT
+ 1.0.3.BUILD-SNAPSHOT
Camden.BUILD-SNAPSHOT
diff --git a/docs/src/main/asciidoc/verifier/stubrunner.adoc b/docs/src/main/asciidoc/verifier/stubrunner.adoc
index 80cae8436e..0b60564416 100644
--- a/docs/src/main/asciidoc/verifier/stubrunner.adoc
+++ b/docs/src/main/asciidoc/verifier/stubrunner.adoc
@@ -66,6 +66,8 @@ Some of the properties that are repetitive can be set using system properties or
|stubrunner.classifier|stubs| Default classifier for the stub artifacts
|stubrunner.workOffline|false| If true then will not contact any remote repositories to download stubs
|stubrunner.ids|| Array of Ivy notation stubs to download
+|stubrunner.username|| Optional username to access the tool that stores the JARs with stubs
+|stubrunner.password|| Optional password to access the tool that stores the JARs with stubs
|======================
===== Stub runner stubs ids
@@ -80,7 +82,7 @@ groupId:artifactId:version:classifier:port
`version`, `classifier` and `port` are optional.
* If you don't provide the `port` then a random one will be picked
-* If you don't provide the `classifier` then the default one will be taken.
+* If you don't provide the `classifier` then the default one will be taken. (NOTE that you can pass an empty classifier like this `groupId:artifactId:version:`)
* If you don't provide the `version` then the `+` will be passed and the latest one will be downloaded
Where `port` means the port of the WireMock server.
\ No newline at end of file
diff --git a/spring-cloud-contract-stub-runner/README.adoc b/spring-cloud-contract-stub-runner/README.adoc
index 23d117147d..611a3c2290 100644
--- a/spring-cloud-contract-stub-runner/README.adoc
+++ b/spring-cloud-contract-stub-runner/README.adoc
@@ -14,24 +14,35 @@ You can set the following options to the main class:
[source,groovy,indent=0]
----
- -maxp (--maxPort) N : Maximum port value to be assigned to the
- Wiremock instance. Defaults to 15000
- (default: 15000)
- -minp (--minPort) N : Minimal port value to be assigned to the
- Wiremock instance. Defaults to 10000
- (default: 10000)
- -s (--stubs) VAL : Comma separated list of Ivy representation of
- jars with stubs. Eg. groupid:artifactid1,group
- id2:artifactid2:version:classifier
- -sr (--stubRepositoryRoot) VAL : Location of a Jar containing server where you
- keep your stubs (e.g. http://nexus.net/content
- /repositories/repository)
- -ss (--stubsSuffix) VAL : Suffix for the jar containing stubs (e.g.
- 'stubs' if the stub jar would have a 'stubs'
- classifier for stubs: foobar-stubs ).
- Defaults to 'stubs' (default: stubs)
- -wo (--workOffline) : Switch to work offline. Defaults to 'false'
- (default: false)
+-c, --classifier Suffix for the jar containing stubs (e.
+ g. 'stubs' if the stub jar would
+ have a 'stubs' classifier for stubs:
+ foobar-stubs ). Defaults to 'stubs'
+ (default: stubs)
+--maxPort, --maxp Maximum port value to be assigned to
+ the WireMock instance. Defaults to
+ 15000 (default: 15000)
+--minPort, --minp Minimum port value to be assigned to
+ the WireMock instance. Defaults to
+ 10000 (default: 10000)
+-p, --password Password to user when connecting to
+ repository
+--phost, --proxyHost Proxy host to use for repository
+ requests
+--pport, --proxyPort [Integer] Proxy port to use for repository
+ requests
+-r, --root Location of a Jar containing server
+ where you keep your stubs (e.g. http:
+ //nexus.
+ net/content/repositories/repository)
+-s, --stubs Comma separated list of Ivy
+ representation of jars with stubs.
+ Eg. groupid:artifactid1,groupid2:
+ artifactid2:classifier
+-u, --username Username to user when connecting to
+ repository
+--wo, --workOffline Switch to work offline. Defaults to
+ 'false'
----
===== HTTP Stubs
diff --git a/spring-cloud-contract-stub-runner/pom.xml b/spring-cloud-contract-stub-runner/pom.xml
index cd02deaa41..420a36c6dd 100644
--- a/spring-cloud-contract-stub-runner/pom.xml
+++ b/spring-cloud-contract-stub-runner/pom.xml
@@ -94,6 +94,12 @@
junit
junit
+
+ io.specto
+ hoverfly-junit
+ 0.1.8
+ test
+
com.sun.jersey
jersey-client
diff --git a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/AetherFactories.java b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/AetherFactories.java
index 709ed9db7e..d45fd40861 100644
--- a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/AetherFactories.java
+++ b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/AetherFactories.java
@@ -16,9 +16,6 @@
package org.springframework.cloud.contract.stubrunner;
-import java.util.ArrayList;
-import java.util.List;
-
import org.apache.maven.repository.internal.MavenRepositorySystemUtils;
import org.eclipse.aether.DefaultRepositorySystemSession;
import org.eclipse.aether.RepositorySystem;
@@ -26,13 +23,11 @@ import org.eclipse.aether.RepositorySystemSession;
import org.eclipse.aether.connector.basic.BasicRepositoryConnectorFactory;
import org.eclipse.aether.impl.DefaultServiceLocator;
import org.eclipse.aether.repository.LocalRepository;
-import org.eclipse.aether.repository.RemoteRepository;
import org.eclipse.aether.repository.RepositoryPolicy;
import org.eclipse.aether.spi.connector.RepositoryConnectorFactory;
import org.eclipse.aether.spi.connector.transport.TransporterFactory;
import org.eclipse.aether.transport.file.FileTransporterFactory;
import org.eclipse.aether.transport.http.HttpTransporterFactory;
-import org.springframework.util.StringUtils;
class AetherFactories {
@@ -52,22 +47,12 @@ class AetherFactories {
if (!workOffline) {
session.setUpdatePolicy(RepositoryPolicy.UPDATE_POLICY_ALWAYS);
}
+ session.setChecksumPolicy(RepositoryPolicy.CHECKSUM_POLICY_WARN);
LocalRepository localRepo = new LocalRepository(localRepositoryDirectory());
session.setLocalRepositoryManager(system.newLocalRepositoryManager(session, localRepo));
return session;
}
- public static List newRepositories(List repositories) {
- List result = new ArrayList<>();
- for (int index = 0; index < repositories.size(); index++) {
- String repo = repositories.get(index);
- if (StringUtils.hasText(repo)) {
- result.add(new RemoteRepository.Builder("remote" + index, "default", repo).build());
- }
- }
- return result;
- }
-
private static String localRepositoryDirectory() {
return System.getProperty(MAVEN_LOCAL_REPOSITORY_LOCATION, System.getProperty("user.home") + "/.m2/repository");
}
diff --git a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/AetherStubDownloader.java b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/AetherStubDownloader.java
index c62b6bc035..51045307ed 100644
--- a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/AetherStubDownloader.java
+++ b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/AetherStubDownloader.java
@@ -21,7 +21,6 @@ import java.io.IOException;
import java.net.URI;
import java.util.AbstractMap;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.List;
import java.util.Map;
@@ -29,6 +28,7 @@ import org.eclipse.aether.RepositorySystem;
import org.eclipse.aether.RepositorySystemSession;
import org.eclipse.aether.artifact.Artifact;
import org.eclipse.aether.artifact.DefaultArtifact;
+import org.eclipse.aether.repository.Proxy;
import org.eclipse.aether.repository.RemoteRepository;
import org.eclipse.aether.resolution.ArtifactRequest;
import org.eclipse.aether.resolution.ArtifactResult;
@@ -38,12 +38,13 @@ import org.eclipse.aether.resolution.VersionRangeResult;
import org.eclipse.aether.resolution.VersionRequest;
import org.eclipse.aether.resolution.VersionResolutionException;
import org.eclipse.aether.resolution.VersionResult;
+import org.eclipse.aether.util.repository.AuthenticationBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.springframework.cloud.contract.stubrunner.StubRunnerOptions.StubRunnerProxyOptions;
import org.springframework.util.StringUtils;
import static java.nio.file.Files.createTempDirectory;
-import static org.springframework.cloud.contract.stubrunner.AetherFactories.newRepositories;
import static org.springframework.cloud.contract.stubrunner.AetherFactories.newRepositorySystem;
import static org.springframework.cloud.contract.stubrunner.AetherFactories.newSession;
import static org.springframework.cloud.contract.stubrunner.util.ZipCategory.unzipTo;
@@ -106,13 +107,27 @@ public class AetherStubDownloader implements StubDownloader {
}
}
- private List remoteRepositories(
- StubRunnerOptions stubRunnerOptions) {
+ private List remoteRepositories(StubRunnerOptions stubRunnerOptions) {
if (stubRunnerOptions.stubRepositoryRoot == null) {
return new ArrayList<>();
}
- List remoteRepos = newRepositories(
- Arrays.asList(stubRunnerOptions.stubRepositoryRoot.split(",")));
+ final String[] repos = stubRunnerOptions.stubRepositoryRoot.split(",");
+ final List remoteRepos = new ArrayList<>();
+ for (int i = 0; i < repos.length; i++) {
+ if(StringUtils.hasText(repos[i])) {
+ final RemoteRepository.Builder builder = new RemoteRepository.Builder("remote" + i, "default", repos[i])
+ .setAuthentication(new AuthenticationBuilder()
+ .addUsername(stubRunnerOptions.username)
+ .addPassword(stubRunnerOptions.password)
+ .build());
+ if(stubRunnerOptions.getProxyOptions() != null) {
+ final StubRunnerProxyOptions p = stubRunnerOptions.getProxyOptions();
+ builder.setProxy(new Proxy(null, p.getProxyHost(), p.getProxyPort()));
+ }
+
+ remoteRepos.add(builder.build());
+ }
+ }
if (log.isDebugEnabled()) {
log.debug("Using the following remote repos " + remoteRepos);
}
@@ -165,8 +180,7 @@ public class AetherStubDownloader implements StubDownloader {
}
@Override
- public Map.Entry downloadAndUnpackStubJar(
- StubRunnerOptions options, StubConfiguration stubConfiguration) {
+ public Map.Entry downloadAndUnpackStubJar(StubConfiguration stubConfiguration) {
String version = getVersion(stubConfiguration.groupId,
stubConfiguration.artifactId, stubConfiguration.version,
stubConfiguration.classifier);
diff --git a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/Arguments.java b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/Arguments.java
index 4f61887b46..8878053ee0 100644
--- a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/Arguments.java
+++ b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/Arguments.java
@@ -48,4 +48,9 @@ class Arguments {
public StubConfiguration getStub() {
return this.stub;
}
+
+ @Override public String toString() {
+ return "Arguments{" + "stubRunnerOptions=" + this.stubRunnerOptions
+ + ", repositoryPath='" + this.repositoryPath + '\'' + ", stub=" + this.stub + '}';
+ }
}
\ No newline at end of file
diff --git a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/ContractDownloader.java b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/ContractDownloader.java
index c2fda66ba9..2001b75d1f 100644
--- a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/ContractDownloader.java
+++ b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/ContractDownloader.java
@@ -91,7 +91,7 @@ public class ContractDownloader {
private File unpackAndDownloadContracts() {
log.info("Will download contracts for [" + this.contractsJarStubConfiguration + "]");
Map.Entry unpackedContractStubs = this.stubDownloader
- .downloadAndUnpackStubJar(null, this.contractsJarStubConfiguration);
+ .downloadAndUnpackStubJar(this.contractsJarStubConfiguration);
if (unpackedContractStubs == null) {
throw new IllegalStateException("The contracts failed to be downloaded!");
}
diff --git a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubDownloader.java b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubDownloader.java
index 725a1827a8..00ea82a126 100644
--- a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubDownloader.java
+++ b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubDownloader.java
@@ -25,5 +25,5 @@ public interface StubDownloader {
* Returns a mapping of updated StubConfiguration (it will contain the resolved version) and the location of the downloaded JAR.
* If there was no artifact this method will return {@code null}.
*/
- Map.Entry downloadAndUnpackStubJar(StubRunnerOptions options, StubConfiguration stubConfiguration);
+ Map.Entry downloadAndUnpackStubJar(StubConfiguration stubConfiguration);
}
\ No newline at end of file
diff --git a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubRunnerFactory.java b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubRunnerFactory.java
index 1a2c5187ac..972d4ece2b 100644
--- a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubRunnerFactory.java
+++ b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubRunnerFactory.java
@@ -57,7 +57,7 @@ class StubRunnerFactory {
Collection result = new ArrayList<>();
for (StubConfiguration stubsConfiguration : this.stubRunnerOptions.getDependencies()) {
Map.Entry entry = this.stubDownloader
- .downloadAndUnpackStubJar(this.stubRunnerOptions, stubsConfiguration);
+ .downloadAndUnpackStubJar(stubsConfiguration);
if (log.isDebugEnabled()) {
log.debug("For stub configuration [" + stubsConfiguration + "] the downloaded entry is [" + entry + "]");
}
diff --git a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubRunnerMain.java b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubRunnerMain.java
index 77a01b90e9..e55b915950 100644
--- a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubRunnerMain.java
+++ b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubRunnerMain.java
@@ -38,11 +38,11 @@ public class StubRunnerMain {
ArgumentAcceptingOptionSpec minPortValueOpt = parser
.acceptsAll(Arrays.asList("minp", "minPort"),
"Minimum port value to be assigned to the WireMock instance. Defaults to 10000")
- .withRequiredArg().ofType(Integer.class);
+ .withRequiredArg().ofType(Integer.class).defaultsTo(10000);
ArgumentAcceptingOptionSpec maxPortValueOpt = parser
.acceptsAll(Arrays.asList("maxp", "maxPort"),
"Maximum port value to be assigned to the WireMock instance. Defaults to 15000")
- .withRequiredArg().ofType(Integer.class);
+ .withRequiredArg().ofType(Integer.class).defaultsTo(15000);
ArgumentAcceptingOptionSpec stubsOpt = parser
.acceptsAll(Arrays.asList("s", "stubs"),
"Comma separated list of Ivy representation of jars with stubs. Eg. groupid:artifactid1,groupid2:artifactid2:classifier")
@@ -54,7 +54,19 @@ public class StubRunnerMain {
ArgumentAcceptingOptionSpec rootOpt = parser
.acceptsAll(Arrays.asList("r", "root"),"Location of a Jar containing server where you keep your stubs (e.g. http://nexus.net/content/repositories/repository)")
.withRequiredArg();
-
+ ArgumentAcceptingOptionSpec usernameOpt = parser
+ .acceptsAll(Arrays.asList("u", "username"),"Username to user when connecting to repository")
+ .withOptionalArg();
+ ArgumentAcceptingOptionSpec passwordOpt = parser
+ .acceptsAll(Arrays.asList("p", "password"),"Password to user when connecting to repository")
+ .withOptionalArg();
+ ArgumentAcceptingOptionSpec proxyHostOpt = parser
+ .acceptsAll(Arrays.asList("phost", "proxyHost"),"Proxy host to use for repository requests")
+ .withOptionalArg();
+ ArgumentAcceptingOptionSpec proxyPortOpt = parser
+ .acceptsAll(Arrays.asList("pport", "proxyPort"),"Proxy port to use for repository requests")
+ .withOptionalArg()
+ .ofType(Integer.class);
parser.acceptsAll(Arrays.asList("wo", "workOffline"),
"Switch to work offline. Defaults to 'false'");
OptionSet options = parser.parse(args);
@@ -64,11 +76,21 @@ public class StubRunnerMain {
Integer maxPortValue = options.valueOf(maxPortValueOpt);
String stubRepositoryRoot= options.valueOf(rootOpt);
String stubsSuffix = options.valueOf(classifierOpt);
- StubRunnerOptions stubRunnerOptions = new StubRunnerOptionsBuilder()
+ final String username = options.valueOf(usernameOpt);
+ final String password = options.valueOf(passwordOpt);
+ final String proxyHost = options.valueOf(proxyHostOpt);
+ final Integer proxyPort = options.valueOf(proxyPortOpt);
+ final StubRunnerOptionsBuilder builder = new StubRunnerOptionsBuilder()
.withMinMaxPort(minPortValue, maxPortValue)
.withStubRepositoryRoot(stubRepositoryRoot)
.withWorkOffline(workOffline).withStubsClassifier(stubsSuffix)
- .withStubs(stubs).build();
+ .withUsername(username)
+ .withPassword(password)
+ .withStubs(stubs);
+ if (proxyHost != null) {
+ builder.withProxy(proxyHost, proxyPort);
+ }
+ StubRunnerOptions stubRunnerOptions = builder.build();
this.arguments = new Arguments(stubRunnerOptions);
}
catch (Exception e) {
diff --git a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubRunnerOptions.java b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubRunnerOptions.java
index 4f1e740112..957880d31f 100644
--- a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubRunnerOptions.java
+++ b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/StubRunnerOptions.java
@@ -60,9 +60,26 @@ public class StubRunnerOptions {
*/
final Map stubIdsToPortMapping;
- public StubRunnerOptions(Integer minPortValue, Integer maxPortValue, String stubRepositoryRoot, boolean workOffline,
- String stubsClassifier, Collection dependencies,
- Map stubIdsToPortMapping) {
+ /**
+ * Optional username for authorization header
+ */
+ final String username;
+
+ /**
+ * Optional password for authorization header
+ */
+ final String password;
+
+ /**
+ * Optional proxy settings
+ */
+ private final StubRunnerProxyOptions stubRunnerProxyOptions;
+
+ StubRunnerOptions(Integer minPortValue, Integer maxPortValue,
+ String stubRepositoryRoot, boolean workOffline, String stubsClassifier,
+ Collection dependencies,
+ Map stubIdsToPortMapping,
+ String username, String password, final StubRunnerProxyOptions stubRunnerProxyOptions) {
this.minPortValue = minPortValue;
this.maxPortValue = maxPortValue;
this.stubRepositoryRoot = stubRepositoryRoot;
@@ -70,17 +87,9 @@ public class StubRunnerOptions {
this.stubsClassifier = stubsClassifier;
this.dependencies = dependencies;
this.stubIdsToPortMapping = stubIdsToPortMapping;
- }
-
- /**
- * @deprecated there is no context path any longer
- */
- @Deprecated
- public StubRunnerOptions(Integer minPortValue, Integer maxPortValue, String stubRepositoryRoot, boolean workOffline,
- String stubsClassifier, Collection dependencies,
- Map stubIdsToPortMapping, String contextPath) {
- this(minPortValue, maxPortValue, stubRepositoryRoot, workOffline, stubsClassifier, dependencies,
- stubIdsToPortMapping);
+ this.username = username;
+ this.password = password;
+ this.stubRunnerProxyOptions = stubRunnerProxyOptions;
}
public Integer port(StubConfiguration stubConfiguration) {
@@ -108,12 +117,41 @@ public class StubRunnerOptions {
return this.stubIdsToPortMapping;
}
- @Override
- public String toString() {
- return "StubRunnerOptions [minPortValue=" + this.minPortValue + ", maxPortValue=" + this.maxPortValue
- + ", stubRepositoryRoot=" + this.stubRepositoryRoot + ", workOffline=" + this.workOffline
- + ", stubsClassifier=" + this.stubsClassifier + ", dependencies=" + this.dependencies
- + ", stubIdsToPortMapping=" + this.stubIdsToPortMapping + "]";
+ public StubRunnerProxyOptions getProxyOptions() {
+ return this.stubRunnerProxyOptions;
}
+ public static class StubRunnerProxyOptions {
+
+ private final String proxyHost;
+ private final int proxyPort;
+
+ public StubRunnerProxyOptions(final String proxyHost, final int proxyPort) {
+ this.proxyHost = proxyHost;
+ this.proxyPort = proxyPort;
+ }
+
+ public String getProxyHost() {
+ return this.proxyHost;
+ }
+
+ public int getProxyPort() {
+ return this.proxyPort;
+ }
+
+ @Override public String toString() {
+ return "StubRunnerProxyOptions{" + "proxyHost='" + this.proxyHost + '\''
+ + ", proxyPort=" + this.proxyPort + '}';
+ }
+ }
+
+ @Override public String toString() {
+ return "StubRunnerOptions{" + "minPortValue=" + this.minPortValue + ", maxPortValue="
+ + this.maxPortValue + ", stubRepositoryRoot='" + this.stubRepositoryRoot + '\''
+ + ", workOffline=" + this.workOffline + ", stubsClassifier='" + this.stubsClassifier
+ + '\'' + ", dependencies=" + this.dependencies + ", stubIdsToPortMapping="
+ + this.stubIdsToPortMapping + ", username='" + this.username + '\'' + ", password='"
+ + this.password + '\'' + ", stubRunnerProxyOptions=" + this.stubRunnerProxyOptions
+ + '}';
+ }
}
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 39e67e8f5a..b08b26ad1f 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
@@ -16,6 +16,9 @@
package org.springframework.cloud.contract.stubrunner;
+import org.springframework.cloud.contract.stubrunner.util.StubsParser;
+import org.springframework.util.StringUtils;
+
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
@@ -23,9 +26,6 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Map;
-import org.springframework.cloud.contract.stubrunner.util.StubsParser;
-import org.springframework.util.StringUtils;
-
public class StubRunnerOptionsBuilder {
private static final String DELIMITER = ":";
@@ -37,6 +37,9 @@ public class StubRunnerOptionsBuilder {
private String stubRepositoryRoot;
private boolean workOffline = false;
private String stubsClassifier = "stubs";
+ private String username;
+ private String password;
+ private StubRunnerOptions.StubRunnerProxyOptions stubRunnerProxyOptions;
public StubRunnerOptionsBuilder() {
}
@@ -57,8 +60,7 @@ public class StubRunnerOptionsBuilder {
return this;
}
- public StubRunnerOptionsBuilder withMinMaxPort(Integer minPortValue,
- Integer maxPortValue) {
+ public StubRunnerOptionsBuilder withMinMaxPort(Integer minPortValue, Integer maxPortValue) {
this.minPortValue = minPortValue;
this.maxPortValue = maxPortValue;
return this;
@@ -114,7 +116,8 @@ public class StubRunnerOptionsBuilder {
public StubRunnerOptions build() {
return new StubRunnerOptions(this.minPortValue, this.maxPortValue, this.stubRepositoryRoot,
- this.workOffline, this.stubsClassifier, buildDependencies(), this.stubIdsToPortMapping);
+ this.workOffline, this.stubsClassifier, buildDependencies(), this.stubIdsToPortMapping,
+ this.username, this.password, this.stubRunnerProxyOptions);
}
private Collection buildDependencies() {
@@ -139,8 +142,7 @@ public class StubRunnerOptionsBuilder {
if (StubsParser.hasPort(notation)) {
addPort(notation);
this.stubs.add(StubsParser.ivyFromStringWithPort(notation));
- }
- else {
+ } else {
this.stubs.add(notation);
}
}
@@ -154,4 +156,18 @@ public class StubRunnerOptionsBuilder {
this.stubIdsToPortMapping.putAll(stubIdsToPortMapping);
}
+ public StubRunnerOptionsBuilder withUsername(final String username) {
+ this.username = username;
+ return this;
+ }
+
+ public StubRunnerOptionsBuilder withPassword(final String password) {
+ this.password = password;
+ return this;
+ }
+
+ public StubRunnerOptionsBuilder withProxy(final String proxyHost, final int proxyPort) {
+ this.stubRunnerProxyOptions = new StubRunnerOptions.StubRunnerProxyOptions(proxyHost, proxyPort);
+ return this;
+ }
}
diff --git a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/junit/StubRunnerRule.java b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/junit/StubRunnerRule.java
index f4665a93b5..229b221edf 100644
--- a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/junit/StubRunnerRule.java
+++ b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/junit/StubRunnerRule.java
@@ -65,14 +65,20 @@ public class StubRunnerRule implements TestRule, StubFinder {
}
private StubRunnerOptions defaultStubRunnerOptions() {
- return new StubRunnerOptionsBuilder()
+ StubRunnerOptionsBuilder builder = new StubRunnerOptionsBuilder()
.withMinPort(Integer.valueOf(System.getProperty("stubrunner.port.range.min", "10000")))
.withMaxPort(Integer.valueOf(System.getProperty("stubrunner.port.range.max", "15000")))
.withStubRepositoryRoot(System.getProperty("stubrunner.repository.root", ""))
.withWorkOffline(Boolean.parseBoolean(System.getProperty("stubrunner.work-offline", "false")))
.withStubsClassifier(System.getProperty("stubrunner.classifier", "stubs"))
.withStubs(System.getProperty("stubrunner.ids", ""))
- .build();
+ .withUsername(System.getProperty("stubrunner.username"))
+ .withPassword(System.getProperty("stubrunner.password"));
+ String proxyHost = System.getProperty("stubrunner.proxy.host");
+ if (proxyHost != null) {
+ builder.withProxy(proxyHost, Integer.parseInt(System.getProperty("stubrunner.proxy.port")));
+ }
+ return builder.build();
}
/**
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 2eb4b1cd3a..0f240e4c21 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
@@ -67,14 +67,11 @@ public class StubRunnerConfiguration {
*/
@Bean
public BatchStubRunner batchStubRunner() throws IOException {
- StubRunnerOptions stubRunnerOptions = new StubRunnerOptionsBuilder()
- .withMinMaxPort(this.props.getMinPort(), this.props.getMaxPort())
- .withStubRepositoryRoot(
- uriStringOrEmpty(this.props.getRepositoryRoot()))
- .withWorkOffline(this.props.isWorkOffline())
- .withStubsClassifier(this.props.getClassifier())
- .withStubs(this.props.getIds())
- .build();
+ StubRunnerOptionsBuilder builder = builder();
+ if (this.props.getProxyHost() != null) {
+ builder.withProxy(this.props.getProxyHost(), this.props.getProxyPort());
+ }
+ StubRunnerOptions stubRunnerOptions = builder.build();
BatchStubRunner batchStubRunner = new BatchStubRunnerFactory(stubRunnerOptions,
this.stubDownloader != null ? this.stubDownloader
: new AetherStubDownloader(stubRunnerOptions),
@@ -86,6 +83,18 @@ public class StubRunnerConfiguration {
return batchStubRunner;
}
+ private StubRunnerOptionsBuilder builder() throws IOException {
+ return new StubRunnerOptionsBuilder()
+ .withMinMaxPort(this.props.getMinPort(), this.props.getMaxPort())
+ .withStubRepositoryRoot(
+ uriStringOrEmpty(this.props.getRepositoryRoot()))
+ .withWorkOffline(this.props.isWorkOffline())
+ .withStubsClassifier(this.props.getClassifier())
+ .withStubs(this.props.getIds())
+ .withUsername(this.props.getUsername())
+ .withPassword(this.props.getPassword());
+ }
+
private String uriStringOrEmpty(Resource stubRepositoryRoot) throws IOException {
return stubRepositoryRoot != null ? stubRepositoryRoot.getURI().toString() : "";
}
diff --git a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/spring/StubRunnerProperties.java b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/spring/StubRunnerProperties.java
index 27ab22716f..651bdf6680 100644
--- a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/spring/StubRunnerProperties.java
+++ b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/spring/StubRunnerProperties.java
@@ -65,6 +65,26 @@ public class StubRunnerProperties {
*/
private String contextPath = "";
+ /**
+ * Repository username
+ */
+ private String username;
+
+ /**
+ * Repository password
+ */
+ private String password;
+
+ /**
+ * Repository proxy port
+ */
+ private Integer proxyPort;
+
+ /**
+ * Repository proxy host
+ */
+ private String proxyHost;
+
public int getMinPort() {
return this.minPort;
}
@@ -97,6 +117,38 @@ public class StubRunnerProperties {
this.repositoryRoot = new DefaultResourceLoader().getResource(repositoryRoot);
}
+ public String getUsername() {
+ return this.username;
+ }
+
+ public void setUsername(final String username) {
+ this.username = username;
+ }
+
+ public String getPassword() {
+ return this.password;
+ }
+
+ public void setPassword(final String password) {
+ this.password = password;
+ }
+
+ public Integer getProxyPort() {
+ return this.proxyPort;
+ }
+
+ public void setProxyPort(final Integer proxyPort) {
+ this.proxyPort = proxyPort;
+ }
+
+ public String getProxyHost() {
+ return this.proxyHost;
+ }
+
+ public void setProxyHost(final String proxyHost) {
+ this.proxyHost = proxyHost;
+ }
+
public String[] getIds() {
return this.ids;
}
diff --git a/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/AetherStubDownloaderSpec.groovy b/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/AetherStubDownloaderSpec.groovy
new file mode 100644
index 0000000000..5001a9f792
--- /dev/null
+++ b/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/AetherStubDownloaderSpec.groovy
@@ -0,0 +1,30 @@
+package org.springframework.cloud.contract.stubrunner
+
+import io.specto.hoverfly.junit.HoverflyRule
+import org.junit.Rule
+
+import spock.lang.Specification
+
+class AetherStubDownloaderSpec extends Specification {
+
+ @Rule
+ HoverflyRule hoverflyRule = HoverflyRule.buildFromClassPathResource("simulation.json").build()
+
+ def 'Should be able to download from a repository using username and password authentication'() {
+ given:
+ final StubRunnerOptions stubRunnerOptions = new StubRunnerOptionsBuilder()
+ .withUsername("andrew.morgan")
+ .withPassword("k+hbZp8rpolRucXB09dGE/CxPXxidQryQUYSGbeo6JE=")
+ .withProxy("localhost", hoverflyRule.proxyPort)
+ .withStubRepositoryRoot("https://test.jfrog.io/test/libs-snapshot-local")
+ .build()
+
+ final AetherStubDownloader aetherStubDownloader = new AetherStubDownloader(stubRunnerOptions)
+
+ when:
+ final def jar = aetherStubDownloader.downloadAndUnpackStubJar(new StubConfiguration("io.test", "test-simulations-svc", "1.0-SNAPSHOT"))
+
+ then:
+ jar != null
+ }
+}
diff --git a/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/ContractDownloaderSpec.groovy b/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/ContractDownloaderSpec.groovy
index b715e5062b..e88b7df793 100644
--- a/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/ContractDownloaderSpec.groovy
+++ b/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/ContractDownloaderSpec.groovy
@@ -19,7 +19,7 @@ class ContractDownloaderSpec extends Specification {
stubConfiguration, contractPath, '', '')
ContractVerifierConfigProperties properties = new ContractVerifierConfigProperties()
and:
- stubDownloader.downloadAndUnpackStubJar(_, _) >> new AbstractMap.SimpleEntry(stubConfiguration, file)
+ stubDownloader.downloadAndUnpackStubJar(_) >> new AbstractMap.SimpleEntry(stubConfiguration, file)
when:
contractDownloader.unpackedDownloadedContracts(properties)
then:
@@ -35,7 +35,7 @@ class ContractDownloaderSpec extends Specification {
stubConfiguration, contractPath, '', '')
ContractVerifierConfigProperties properties = new ContractVerifierConfigProperties()
and:
- stubDownloader.downloadAndUnpackStubJar(_, _) >> new AbstractMap.SimpleEntry(stubConfiguration, file)
+ stubDownloader.downloadAndUnpackStubJar(_) >> new AbstractMap.SimpleEntry(stubConfiguration, file)
when:
contractDownloader.unpackedDownloadedContracts(properties)
then:
diff --git a/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerFactorySpec.groovy b/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerFactorySpec.groovy
index 24776bcf00..cec3e255e9 100644
--- a/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerFactorySpec.groovy
+++ b/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerFactorySpec.groovy
@@ -42,8 +42,8 @@ class StubRunnerFactorySpec extends Specification {
def "Should download stub definitions many times"() {
given:
folder.newFolder("mappings")
- 1 * downloader.downloadAndUnpackStubJar(_, _) >> new AbstractMap.SimpleEntry(new StubConfiguration('a:b'), folder.root)
- 1 * downloader.downloadAndUnpackStubJar(_, _) >> new AbstractMap.SimpleEntry(new StubConfiguration('c:d'), folder.root)
+ 1 * downloader.downloadAndUnpackStubJar(_) >> new AbstractMap.SimpleEntry(new StubConfiguration('a:b'), folder.root)
+ 1 * downloader.downloadAndUnpackStubJar(_) >> new AbstractMap.SimpleEntry(new StubConfiguration('c:d'), folder.root)
when:
Collection stubRunners = collectOnlyPresentValues(factory.createStubsFromServiceConfiguration())
then:
diff --git a/spring-cloud-contract-stub-runner/src/test/resources/simulation.json b/spring-cloud-contract-stub-runner/src/test/resources/simulation.json
new file mode 100644
index 0000000000..20d8c8239c
--- /dev/null
+++ b/spring-cloud-contract-stub-runner/src/test/resources/simulation.json
@@ -0,0 +1,313 @@
+{
+ "data": [
+ {
+ "response": {
+ "status": 200,
+ "body": "\u003c?xml version=\"1.0\" encoding=\"UTF-8\"?\u003e\n\u003cmetadata\u003e\n \u003cgroupId\u003eio.test\u003c/groupId\u003e\n \u003cartifactId\u003etest-simulations-svc\u003c/artifactId\u003e\n \u003cversion\u003e1.0-SNAPSHOT\u003c/version\u003e\n \u003cversioning\u003e\n \u003csnapshot\u003e\n \u003cbuildNumber\u003e1\u003c/buildNumber\u003e\n \u003c/snapshot\u003e\n \u003clastUpdated\u003e20161102142105\u003c/lastUpdated\u003e\n \u003c/versioning\u003e\n\u003c/metadata\u003e\n",
+ "encodedBody": false,
+ "headers": {
+ "Accept-Ranges": [
+ "bytes"
+ ],
+ "Cache-Control": [
+ "no-store"
+ ],
+ "Connection": [
+ "keep-alive"
+ ],
+ "Content-Disposition": [
+ "attachment; filename=\"maven-metadata.xml\"; filename*=UTF-8''maven-metadata.xml"
+ ],
+ "Content-Length": [
+ "320"
+ ],
+ "Content-Type": [
+ "application/xml"
+ ],
+ "Date": [
+ "Tue, 08 Nov 2016 15:22:26 GMT"
+ ],
+ "Etag": [
+ "9a318b6f330aaf4b7088c3018e31dd4bb11b18f1"
+ ],
+ "Hoverfly": [
+ "Was-Here"
+ ],
+ "Last-Modified": [
+ "Wed, 02 Nov 2016 14:21:05 GMT"
+ ],
+ "Server": [
+ "Artifactory/4.14.0"
+ ],
+ "X-Artifactory-Filename": [
+ "maven-metadata.xml"
+ ],
+ "X-Artifactory-Id": [
+ "aolprod1b-test"
+ ],
+ "X-Checksum-Md5": [
+ "baa7a56ac80111c29099f9076e6a136f"
+ ],
+ "X-Checksum-Sha1": [
+ "9a318b6f330aaf4b7088c3018e31dd4bb11b18f1"
+ ],
+ "X-Node": [
+ "nginx-shared2b"
+ ]
+ }
+ },
+ "request": {
+ "requestType": "template",
+ "path": "/test/libs-snapshot-local/io/test/test-simulations-svc/1.0-SNAPSHOT/maven-metadata.xml",
+ "method": "GET",
+ "destination": "test.jfrog.io",
+ "scheme": "https",
+ "query": "",
+ "body": "",
+ "headers": {
+ "Authorization": [
+ "Basic dXNlcm5hbWU6cGFzc3dvcmQK=="
+ ]
+ }
+ }
+ },
+ {
+ "response": {
+ "status": 401
+ },
+ "request": {
+ "requestType": "template",
+ "path": "/test/libs-snapshot-local/io/test/test-simulations-svc/1.0-SNAPSHOT/maven-metadata.xml",
+ "method": "GET",
+ "destination": "test.jfrog.io",
+ "scheme": "https",
+ "query": "",
+ "body": ""
+ }
+ },
+ {
+ "response": {
+ "status": 401
+ },
+ "request": {
+ "requestType": "template",
+ "path": "/test/libs-snapshot-local/io/test/test-simulations-svc/1.0-SNAPSHOT/test-simulations-svc-1.0-SNAPSHOT-stubs.jar.sha1",
+ "method": "GET",
+ "destination": "test.jfrog.io",
+ "scheme": "https",
+ "query": "",
+ "body": ""
+ }
+ },
+ {
+ "response": {
+ "status": 401
+ },
+ "request": {
+ "requestType": "template",
+ "path": "/test/libs-snapshot-local/io/test/test-simulations-svc/1.0-SNAPSHOT/test-simulations-svc-1.0-SNAPSHOT-stubs.jar.md5",
+ "method": "GET",
+ "destination": "test.jfrog.io",
+ "scheme": "https",
+ "query": "",
+ "body": ""
+ }
+ },
+ {
+ "response": {
+ "status": 200,
+ "body": "9a318b6f330aaf4b7088c3018e31dd4bb11b18f1",
+ "encodedBody": false,
+ "headers": {
+ "Connection": [
+ "keep-alive"
+ ],
+ "Content-Length": [
+ "40"
+ ],
+ "Content-Type": [
+ "application/x-checksum"
+ ],
+ "Date": [
+ "Tue, 08 Nov 2016 15:22:26 GMT"
+ ],
+ "Hoverfly": [
+ "Was-Here"
+ ],
+ "Last-Modified": [
+ "Tue, 08 Nov 2016 15:22:26 GMT"
+ ],
+ "Server": [
+ "Artifactory/4.14.0"
+ ],
+ "X-Artifactory-Id": [
+ "aolprod1b-test"
+ ],
+ "X-Node": [
+ "nginx-shared2b"
+ ]
+ }
+ },
+ "request": {
+ "requestType": "template",
+ "path": "/test/libs-snapshot-local/io/test/test-simulations-svc/1.0-SNAPSHOT/maven-metadata.xml.sha1",
+ "method": "GET",
+ "destination": "test.jfrog.io",
+ "scheme": "https",
+ "query": "",
+ "body": "",
+ "headers": {
+ "Accept-Encoding": [
+ "gzip,deflate"
+ ],
+ "Authorization": [
+ "Basic dXNlcm5hbWU6cGFzc3dvcmQK=="
+ ],
+ "Cache-Control": [
+ "no-cache, no-store"
+ ],
+ "Connection": [
+ "Keep-Alive"
+ ],
+ "Pragma": [
+ "no-cache"
+ ],
+ "User-Agent": [
+ "Aether"
+ ]
+ }
+ }
+ },
+ {
+ "response": {
+ "status": 200,
+ "body": "UEsDBAoAAAgIAJxyYkkAAAAAAgAAAAAAAAAJAAAATUVUQS1JTkYvAwBQSwMECgAACAgAnHJiSbJ/Au4bAAAAGQAAABQAAABNRVRBLUlORi9NQU5JRkVTVC5NRvNNzMtMSy0u0Q1LLSrOzM+zUjDUM+Dl4uUCAFBLAwQKAAAICACccmJJAAAAAAIAAAAAAAAACgAAAGNvbnRyYWN0cy8DAFBLAwQKAAAICACccmJJkcxXfpgAAADnAAAALwAAAGNvbnRyYWN0cy9zaG91bGRCZUFibGVUb0NyZWF0ZVNpbXVsYXRpb24uZ3Jvb3Z5VY1BDsIgFET3nIIdbUxo9QpewIUe4Id+kRQE/4dqYnp30bRGZzdvJjMJzAgWpYnXTGAyCxHJak7krvZMEPAeadTGxzLotVRjNHq/ugAjyqeQVYS3gpwX91bAfImDVIfTUX1hIS8n8AWbOsklIDWEFh+N6tiF4iG7yjtIrpu2f0hvVNu2n6F5eeRUA/y55Ay5sNz1/dKbxQtQSwMECgAACAgAnHJiSQAAAAACAAAAAAAAAAkAAABtYXBwaW5ncy8DAFBLAwQKAAAICACccmJJT/HGJIsAAADBAAAALAAAAG1hcHBpbmdzL3Nob3VsZEJlQWJsZVRvQ3JlYXRlU2ltdWxhdGlvbi5qc29uVY07DsIwEET7nMJyC8ZOlI/gFCngAGtlIyzl613TRLk7dqCAcp7mzWyZEDIE10lxExLLyti+QdUAWFX2plC2rq3CCK9VZ9DmvTwnxeMakDhZW8xpxA8tMKOfjilNbgwDsJsn0rA4/cr/0OV0DEVxRH7On//2cZcR7t8LWmITfz6IgQMlUBiTitn+BlBLAQIUAwoAAAgIAJxyYkkAAAAAAgAAAAAAAAAJAAAAAAAAAAAAEADtQQAAAABNRVRBLUlORi9QSwECFAMKAAAICACccmJJsn8C7hsAAAAZAAAAFAAAAAAAAAAAAAAApIEpAAAATUVUQS1JTkYvTUFOSUZFU1QuTUZQSwECFAMKAAAICACccmJJAAAAAAIAAAAAAAAACgAAAAAAAAAAABAA/UF2AAAAY29udHJhY3RzL1BLAQIUAwoAAAgIAJxyYkmRzFd+mAAAAOcAAAAvAAAAAAAAAAAAAAC0gaAAAABjb250cmFjdHMvc2hvdWxkQmVBYmxlVG9DcmVhdGVTaW11bGF0aW9uLmdyb292eVBLAQIUAwoAAAgIAJxyYkkAAAAAAgAAAAAAAAAJAAAAAAAAAAAAEAD9QYUBAABtYXBwaW5ncy9QSwECFAMKAAAICACccmJJT/HGJIsAAADBAAAALAAAAAAAAAAAAAAAtIGuAQAAbWFwcGluZ3Mvc2hvdWxkQmVBYmxlVG9DcmVhdGVTaW11bGF0aW9uLmpzb25QSwUGAAAAAAYABgCfAQAAgwIAAAAA",
+ "encodedBody": true,
+ "headers": {
+ "Accept-Ranges": [
+ "bytes"
+ ],
+ "Cache-Control": [
+ "no-store"
+ ],
+ "Connection": [
+ "keep-alive"
+ ],
+ "Content-Disposition": [
+ "attachment; filename=\"test-simulations-svc-1.0-SNAPSHOT-stubs.jar\"; filename*=UTF-8''test-simulations-svc-1.0-SNAPSHOT-stubs.jar"
+ ],
+ "Content-Length": [
+ "1080"
+ ],
+ "Content-Type": [
+ "application/java-archive"
+ ],
+ "Date": [
+ "Tue, 08 Nov 2016 15:22:26 GMT"
+ ],
+ "Etag": [
+ "6c40475c58db6745b860e7b3f0ffa1c87faa83ce"
+ ],
+ "Hoverfly": [
+ "Was-Here"
+ ],
+ "Last-Modified": [
+ "Wed, 02 Nov 2016 14:21:06 GMT"
+ ],
+ "Server": [
+ "Artifactory/4.14.0"
+ ],
+ "X-Artifactory-Filename": [
+ "test-simulations-svc-1.0-SNAPSHOT-stubs.jar"
+ ],
+ "X-Artifactory-Id": [
+ "aolprod1b-test"
+ ],
+ "X-Checksum-Md5": [
+ "0b8c9e9880654871beaf1cf40cd07aaf"
+ ],
+ "X-Checksum-Sha1": [
+ "6c40475c58db6745b860e7b3f0ffa1c87faa83ce"
+ ],
+ "X-Node": [
+ "nginx-shared2b"
+ ]
+ }
+ },
+ "request": {
+ "requestType": "template",
+ "path": "/test/libs-snapshot-local/io/test/test-simulations-svc/1.0-SNAPSHOT/test-simulations-svc-1.0-SNAPSHOT-stubs.jar",
+ "method": "GET",
+ "destination": "test.jfrog.io",
+ "scheme": "https",
+ "query": "",
+ "body": ""
+ }
+ },
+ {
+ "response": {
+ "status": 200,
+ "body": "6c40475c58db6745b860e7b3f0ffa1c87faa83ce",
+ "encodedBody": false,
+ "headers": {
+ "Connection": [
+ "keep-alive"
+ ],
+ "Content-Length": [
+ "40"
+ ],
+ "Content-Type": [
+ "application/x-checksum"
+ ],
+ "Date": [
+ "Tue, 08 Nov 2016 15:22:26 GMT"
+ ],
+ "Hoverfly": [
+ "Was-Here"
+ ],
+ "Last-Modified": [
+ "Tue, 08 Nov 2016 15:22:26 GMT"
+ ],
+ "Server": [
+ "Artifactory/4.14.0"
+ ],
+ "X-Artifactory-Id": [
+ "aolprod1b-test"
+ ],
+ "X-Node": [
+ "nginx-shared2b"
+ ]
+ }
+ },
+ "request": {
+ "requestType": "recording",
+ "path": "/test/libs-snapshot-local/io/test/test-simulations-svc/1.0-SNAPSHOT/test-simulations-svc-1.0-SNAPSHOT-stubs.jar.sha1",
+ "method": "GET",
+ "destination": "test.jfrog.io",
+ "scheme": "https",
+ "query": "",
+ "body": "",
+ "headers": {
+ "Accept-Encoding": [
+ "gzip,deflate"
+ ],
+ "Authorization": [
+ "Basic dXNlcm5hbWU6cGFzc3dvcmQK=="
+ ],
+ "Cache-Control": [
+ "no-cache, no-store"
+ ],
+ "Connection": [
+ "Keep-Alive"
+ ],
+ "Pragma": [
+ "no-cache"
+ ],
+ "User-Agent": [
+ "Aether"
+ ]
+ }
+ }
+ }
+ ]
+}
\ No newline at end of file