@@ -19,10 +19,17 @@ package org.springframework.cloud.contract.stubrunner;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.nio.file.FileVisitResult;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.SimpleFileVisitor;
|
||||
import java.nio.file.attribute.BasicFileAttributes;
|
||||
import java.util.AbstractMap;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
||||
import org.eclipse.aether.RepositorySystem;
|
||||
import org.eclipse.aether.RepositorySystemSession;
|
||||
@@ -52,6 +59,13 @@ import static org.springframework.cloud.contract.stubrunner.util.ZipCategory.unz
|
||||
*/
|
||||
public class AetherStubDownloader implements StubDownloader {
|
||||
|
||||
/**
|
||||
* There are problems with removal of stubs unpacked to a temporary folder.
|
||||
* That's why we're creating a bounded in-memory storage of unpacked files
|
||||
* and later we register a shutdown hook to remove all these files.
|
||||
*/
|
||||
private static final Queue<File> TEMP_FILES_LOG = new LinkedBlockingQueue<>(1000);
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(AetherStubDownloader.class);
|
||||
|
||||
private static final String TEMP_DIR_PREFIX = "contracts";
|
||||
@@ -84,6 +98,7 @@ public class AetherStubDownloader implements StubDownloader {
|
||||
this.repositorySystem = newRepositorySystem();
|
||||
this.session = newSession(this.repositorySystem, stubRunnerOptions.workOffline);
|
||||
this.workOffline = stubRunnerOptions.workOffline;
|
||||
registerShutdownHook();
|
||||
}
|
||||
|
||||
private boolean remoteReposMissing() {
|
||||
@@ -106,6 +121,7 @@ public class AetherStubDownloader implements StubDownloader {
|
||||
log.error("Remote repositories for stubs are not specified and work offline flag wasn't passed");
|
||||
}
|
||||
this.workOffline = false;
|
||||
registerShutdownHook();
|
||||
}
|
||||
|
||||
private List<RemoteRepository> remoteRepositories(StubRunnerOptions stubRunnerOptions) {
|
||||
@@ -249,7 +265,49 @@ public class AetherStubDownloader implements StubDownloader {
|
||||
tmpDirWhereStubsWillBeUnzipped.deleteOnExit();
|
||||
log.info("Unpacking stub from JAR [URI: " + stubJarUri + "]");
|
||||
unzipTo(new File(stubJarUri), tmpDirWhereStubsWillBeUnzipped);
|
||||
TEMP_FILES_LOG.add(tmpDirWhereStubsWillBeUnzipped);
|
||||
return tmpDirWhereStubsWillBeUnzipped;
|
||||
}
|
||||
|
||||
private void registerShutdownHook() {
|
||||
Runtime.getRuntime().addShutdownHook(new Thread() {
|
||||
public void run() {
|
||||
cleanup();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void cleanup() {
|
||||
try {
|
||||
for (File file : TEMP_FILES_LOG) {
|
||||
if (file.isDirectory()) {
|
||||
Files.walkFileTree(file.toPath(), new SimpleFileVisitor<Path>() {
|
||||
@Override
|
||||
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
|
||||
if (log.isTraceEnabled()) {
|
||||
log.trace("Removing unzipped file [" + file + "]");
|
||||
}
|
||||
Files.delete(file);
|
||||
return FileVisitResult.CONTINUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
|
||||
if (log.isTraceEnabled()) {
|
||||
log.trace("Removing unzipped dir [" + dir + "]");
|
||||
}
|
||||
Files.delete(dir);
|
||||
return FileVisitResult.CONTINUE;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
Files.delete(file.toPath());
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Failed to remove temporary file", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package org.springframework.cloud.contract.stubrunner;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
@@ -88,7 +89,9 @@ public class ClasspathStubProvider implements StubDownloaderBuilder {
|
||||
new File(tmp, relativePathWithoutFile).toPath());
|
||||
File newFile = new File(directory.toFile(), resource.getFilename());
|
||||
if (!newFile.exists() && !isDirectory(resource)) {
|
||||
Files.copy(resource.getInputStream(), newFile.toPath());
|
||||
try (InputStream stream = resource.getInputStream()) {
|
||||
Files.copy(stream, newFile.toPath());
|
||||
}
|
||||
}
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Stored file [" + newFile + "]");
|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-2017 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;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
import org.springframework.cloud.contract.verifier.dsl.wiremock.WireMockStubMapping;
|
||||
import org.springframework.util.StreamUtils;
|
||||
|
||||
import com.github.tomakehurst.wiremock.stubbing.StubMapping;
|
||||
|
||||
/**
|
||||
* Represents a single JSON file that was found in the folder with potential WireMock
|
||||
* stubs
|
||||
*/
|
||||
class WiremockMappingDescriptor {
|
||||
|
||||
final File descriptor;
|
||||
|
||||
public WiremockMappingDescriptor(File mappingDescriptor) {
|
||||
this.descriptor = mappingDescriptor;
|
||||
}
|
||||
|
||||
public StubMapping getMapping() {
|
||||
try {
|
||||
return WireMockStubMapping.buildFrom(StreamUtils.copyToString(
|
||||
new FileInputStream(this.descriptor), Charset.forName("UTF-8")));
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new IllegalStateException("Cannot read file", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "WiremockMappingDescriptor [descriptor=" + this.descriptor + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((this.descriptor == null) ? 0 : this.descriptor.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
WiremockMappingDescriptor other = (WiremockMappingDescriptor) obj;
|
||||
if (this.descriptor == null) {
|
||||
if (other.descriptor != null)
|
||||
return false;
|
||||
}
|
||||
else if (!this.descriptor.equals(other.descriptor))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1,20 +1,20 @@
|
||||
package org.springframework.cloud.contract.stubrunner.provider.wiremock;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.file.Files;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.github.jknack.handlebars.Helper;
|
||||
import com.github.tomakehurst.wiremock.WireMockServer;
|
||||
import com.github.tomakehurst.wiremock.client.WireMock;
|
||||
import com.github.tomakehurst.wiremock.core.WireMockConfiguration;
|
||||
import com.github.tomakehurst.wiremock.extension.responsetemplating.ResponseTemplateTransformer;
|
||||
import com.github.tomakehurst.wiremock.stubbing.StubMapping;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.cloud.contract.stubrunner.HttpServerStub;
|
||||
@@ -115,9 +115,9 @@ public class WireMockHttpServerStub implements HttpServerStub {
|
||||
}
|
||||
|
||||
StubMapping getMapping(File file) {
|
||||
try {
|
||||
return StubMapping.buildFrom(StreamUtils.copyToString(
|
||||
new FileInputStream(file), Charset.forName("UTF-8")));
|
||||
try (InputStream stream = Files.newInputStream(file.toPath())) {
|
||||
return StubMapping.buildFrom(
|
||||
StreamUtils.copyToString(stream, Charset.forName("UTF-8")));
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new IllegalStateException("Cannot read file", e);
|
||||
|
||||
@@ -17,9 +17,10 @@
|
||||
package org.springframework.cloud.contract.stubrunner.util;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
@@ -55,28 +56,28 @@ public class ZipCategory {
|
||||
if (destination == null)
|
||||
destination = new File(self.getParent());
|
||||
List<File> unzippedFiles = new ArrayList<>();
|
||||
try {
|
||||
ZipInputStream zipInput = new ZipInputStream(new FileInputStream(self));
|
||||
for (ZipEntry entry = zipInput.getNextEntry(); entry != null; entry = zipInput
|
||||
.getNextEntry()) {
|
||||
if (!entry.isDirectory()) {
|
||||
final File file = new File(destination, entry.getName());
|
||||
if (file.getParentFile() != null) {
|
||||
file.getParentFile().mkdirs();
|
||||
try (InputStream fileInputStream = Files.newInputStream(self.toPath())) {
|
||||
try (ZipInputStream zipInput = new ZipInputStream(fileInputStream)) {
|
||||
for (ZipEntry entry = zipInput.getNextEntry(); entry != null; entry = zipInput
|
||||
.getNextEntry()) {
|
||||
if (!entry.isDirectory()) {
|
||||
final File file = new File(destination, entry.getName());
|
||||
if (file.getParentFile() != null) {
|
||||
file.getParentFile().mkdirs();
|
||||
}
|
||||
try (OutputStream output = Files.newOutputStream(file.toPath())) {
|
||||
StreamUtils.copy(zipInput, output);
|
||||
}
|
||||
unzippedFiles.add(file);
|
||||
}
|
||||
try (FileOutputStream output = new FileOutputStream(file)) {
|
||||
StreamUtils.copy(zipInput, output);
|
||||
else {
|
||||
final File dir = new File(destination, entry.getName());
|
||||
dir.mkdirs();
|
||||
unzippedFiles.add(dir);
|
||||
}
|
||||
unzippedFiles.add(file);
|
||||
}
|
||||
else {
|
||||
final File dir = new File(destination, entry.getName());
|
||||
dir.mkdirs();
|
||||
unzippedFiles.add(dir);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException("Cannot unzip archive", e);
|
||||
}
|
||||
return unzippedFiles;
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package org.springframework.cloud.contract.verifier.converter
|
||||
|
||||
import java.nio.file.Files
|
||||
|
||||
import groovy.transform.CompileStatic
|
||||
import org.springframework.cloud.contract.spec.Contract
|
||||
import org.springframework.cloud.contract.spec.ContractConverter
|
||||
@@ -37,7 +39,8 @@ class YamlContractConverter implements ContractConverter<List<YamlContract>> {
|
||||
@Override
|
||||
public Collection<Contract> convertFrom(File file) {
|
||||
try {
|
||||
YamlContract yamlContract = new Yaml().loadAs(new FileInputStream(file), YamlContract.class)
|
||||
YamlContract yamlContract = new Yaml().loadAs(
|
||||
Files.newInputStream(file.toPath()), YamlContract.class)
|
||||
return [Contract.make {
|
||||
request {
|
||||
method(yamlContract?.request?.method)
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package org.springframework.cloud.contract.wiremock.restdocs;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.Writer;
|
||||
import java.net.URI;
|
||||
import java.nio.file.Files;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
@@ -136,7 +136,7 @@ public class ContractDslSnippet extends TemplatedSnippet {
|
||||
File output = new File(context.getOutputDirectory(),
|
||||
CONTRACTS_FOLDER + "/" + operation.getName() + ".groovy");
|
||||
output.getParentFile().mkdirs();
|
||||
try (Writer writer = new OutputStreamWriter(new FileOutputStream(output))) {
|
||||
try (Writer writer = new OutputStreamWriter(Files.newOutputStream(output.toPath()))) {
|
||||
writer.append(content);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user