diff --git a/spring-cloud-contract-wiremock/pom.xml b/spring-cloud-contract-wiremock/pom.xml
index b9b983d31b..32fcd19c98 100644
--- a/spring-cloud-contract-wiremock/pom.xml
+++ b/spring-cloud-contract-wiremock/pom.xml
@@ -84,5 +84,18 @@
spring-cloud-contract-verifier
test
+
+ io.spring.initializr
+ initializr-web
+ 0.4.0.BUILD-SNAPSHOT
+ stubs
+ test
+
+
+ *
+ *
+
+
+
diff --git a/spring-cloud-contract-wiremock/src/main/java/org/springframework/cloud/contract/wiremock/WireMockConfiguration.java b/spring-cloud-contract-wiremock/src/main/java/org/springframework/cloud/contract/wiremock/WireMockConfiguration.java
index a0fbb21622..92e3caef6f 100644
--- a/spring-cloud-contract-wiremock/src/main/java/org/springframework/cloud/contract/wiremock/WireMockConfiguration.java
+++ b/spring-cloud-contract-wiremock/src/main/java/org/springframework/cloud/contract/wiremock/WireMockConfiguration.java
@@ -16,13 +16,17 @@
package org.springframework.cloud.contract.wiremock;
+import com.github.tomakehurst.wiremock.WireMockServer;
+import com.github.tomakehurst.wiremock.client.WireMock;
+import com.github.tomakehurst.wiremock.common.Slf4jNotifier;
+import com.github.tomakehurst.wiremock.core.Options;
+
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
-import com.github.tomakehurst.wiremock.common.Slf4jNotifier;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.boot.context.properties.ConfigurationProperties;
@@ -36,10 +40,6 @@ import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.util.StreamUtils;
import org.springframework.util.StringUtils;
-import com.github.tomakehurst.wiremock.WireMockServer;
-import com.github.tomakehurst.wiremock.client.WireMock;
-import com.github.tomakehurst.wiremock.core.Options;
-
/**
* Configuration and lifecycle for a Spring Application context that wants to run a
* WireMock server. Can be used by adding
@@ -120,7 +120,7 @@ public class WireMockConfiguration implements SmartLifecycle {
private void registerFiles(com.github.tomakehurst.wiremock.core.WireMockConfiguration factory) throws IOException {
List resources = new ArrayList<>();
- for (String files : this.wireMock.getServer().getFiles()) {
+ for (String files : this.wireMock.getServer().getFiles()) {
if (StringUtils.hasText(files)) {
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(
this.resourceLoader);
diff --git a/spring-cloud-contract-wiremock/src/main/java/org/springframework/cloud/contract/wiremock/file/ResourcesFileSource.java b/spring-cloud-contract-wiremock/src/main/java/org/springframework/cloud/contract/wiremock/file/ResourcesFileSource.java
index b83f90ff74..64228f8d04 100644
--- a/spring-cloud-contract-wiremock/src/main/java/org/springframework/cloud/contract/wiremock/file/ResourcesFileSource.java
+++ b/spring-cloud-contract-wiremock/src/main/java/org/springframework/cloud/contract/wiremock/file/ResourcesFileSource.java
@@ -16,22 +16,25 @@
package org.springframework.cloud.contract.wiremock.file;
+import com.github.tomakehurst.wiremock.common.BinaryFile;
+import com.github.tomakehurst.wiremock.common.ClasspathFileSource;
+import com.github.tomakehurst.wiremock.common.FileSource;
+import com.github.tomakehurst.wiremock.common.SingleRootFileSource;
+import com.github.tomakehurst.wiremock.common.TextFile;
+
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
-import com.github.tomakehurst.wiremock.common.BinaryFile;
-import com.github.tomakehurst.wiremock.common.ClasspathFileSource;
-import com.github.tomakehurst.wiremock.common.FileSource;
-import com.github.tomakehurst.wiremock.common.SingleRootFileSource;
-import com.github.tomakehurst.wiremock.common.TextFile;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
+import static java.util.Arrays.asList;
+
/**
* @author Dave Syer
* @author Pei-Tang Huang
@@ -61,8 +64,7 @@ public class ResourcesFileSource implements FileSource {
sources[i] = new SingleRootFileSource(files.getFile());
}
else if (resource instanceof UrlResource) {
- UrlResource files = (UrlResource) resource;
- sources[i] = new SingleRootFileSource(getFile(files));
+ sources[i] = fileOrFallbackToClasspath(resource);
}
else {
throw new IllegalArgumentException("Unsupported resource type for file source: " + resource.getClass());
@@ -71,9 +73,31 @@ public class ResourcesFileSource implements FileSource {
return sources;
}
- private static File getFile(UrlResource files) {
+ private static FileSource fileOrFallbackToClasspath(Resource resource) {
+ UrlResource file = (UrlResource) resource;
try {
- return files.getFile();
+ URI uri = file.getURI();
+ if (compressedResource(uri)) {
+ return new ClasspathFileSource(pathFromCompressed(uri));
+ }
+ return new SingleRootFileSource(getFile(file));
+ } catch (IOException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ private static String pathFromCompressed(URI pathUri) {
+ String path = pathUri.getSchemeSpecificPart().split("!")[1];
+ return path.startsWith("/") ? path.substring(1) : path;
+ }
+
+ private static boolean compressedResource(URI pathUri) {
+ return asList("jar", "war", "ear", "zip").contains(pathUri.getScheme());
+ }
+
+ private static File getFile(UrlResource file) {
+ try {
+ return file.getFile();
}
catch (IOException e) {
throw new IllegalStateException(e);
@@ -199,4 +223,4 @@ public class ResourcesFileSource implements FileSource {
}
-}
+}
\ No newline at end of file
diff --git a/spring-cloud-contract-wiremock/src/test/java/org/springframework/cloud/contract/wiremock/AutoConfigureWireMockFilesApplicationWithUrlResourceTests.java b/spring-cloud-contract-wiremock/src/test/java/org/springframework/cloud/contract/wiremock/AutoConfigureWireMockFilesApplicationWithUrlResourceTests.java
index 25bbb9626f..59dd320804 100644
--- a/spring-cloud-contract-wiremock/src/test/java/org/springframework/cloud/contract/wiremock/AutoConfigureWireMockFilesApplicationWithUrlResourceTests.java
+++ b/spring-cloud-contract-wiremock/src/test/java/org/springframework/cloud/contract/wiremock/AutoConfigureWireMockFilesApplicationWithUrlResourceTests.java
@@ -13,7 +13,8 @@ import static org.assertj.core.api.Assertions.assertThat;
@RunWith(SpringRunner.class)
@SpringBootTest(classes=WiremockTestsApplication.class, properties="app.baseUrl=http://localhost:${wiremock.server.port}", webEnvironment=WebEnvironment.NONE)
@DirtiesContext
-@AutoConfigureWireMock(port=0, files="classpath*:root")
+// resource from a Initilizr stubs jar
+@AutoConfigureWireMock(port=0, files="classpath*:META-INF/io.spring.initializr/initializr-web/0.4.0.BUILD-SNAPSHOT")
public class AutoConfigureWireMockFilesApplicationWithUrlResourceTests {
@Autowired
@@ -21,7 +22,7 @@ public class AutoConfigureWireMockFilesApplicationWithUrlResourceTests {
@Test
public void contextLoads() throws Exception {
- assertThat(this.service.go()).isEqualTo("{\"message\":\"Hello Root\"}");
+ assertThat(this.service.pom()).contains("spring-boot-starter-parent");
}
}
diff --git a/spring-cloud-contract-wiremock/src/test/java/org/springframework/cloud/contract/wiremock/WiremockTestsApplication.java b/spring-cloud-contract-wiremock/src/test/java/org/springframework/cloud/contract/wiremock/WiremockTestsApplication.java
index df1a184074..2b22fe1708 100644
--- a/spring-cloud-contract-wiremock/src/test/java/org/springframework/cloud/contract/wiremock/WiremockTestsApplication.java
+++ b/spring-cloud-contract-wiremock/src/test/java/org/springframework/cloud/contract/wiremock/WiremockTestsApplication.java
@@ -1,11 +1,16 @@
package org.springframework.cloud.contract.wiremock;
+import java.net.URI;
+import java.util.stream.Stream;
+
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
+import org.springframework.http.MediaType;
+import org.springframework.http.RequestEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@@ -58,6 +63,19 @@ class Service {
return this.restTemplate.getForEntity(this.base + "/test", String.class).getBody();
}
+ public String pom() {
+ return this.restTemplate.exchange(
+ RequestEntity.get(URI.create(this.base + "/pom.xml"))
+ .accept(mediaTypes()).build(), String.class).getBody();
+ }
+
+ private MediaType[] mediaTypes() {
+ return Stream
+ .of("text/plain", "text/plain", "application/json", "application/json",
+ "application/*+json", "application/*+json", "*/*", "*/*")
+ .map(MediaType::valueOf).toArray(MediaType[]::new);
+ }
+
public void setBase(String base) {
this.base = base;
}