From af3f0a06c6ec55ad04f4f489e905b372a490f61e Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Tue, 24 Sep 2019 12:32:25 +0200 Subject: [PATCH] Refactored more to java --- .../converter/RecursiveFilesConverter.groovy | 175 ------------ .../converter/StubGeneratorProvider.groovy | 49 ---- .../DslToWireMockClientConverter.groovy | 58 ---- .../ConversionContractVerifierException.java} | 16 +- .../converter/RecursiveFilesConverter.java | 261 ++++++++++++++++++ .../verifier/converter/StubGenerator.java | 0 .../converter/StubGeneratorProvider.java | 57 ++++ .../DslToWireMockClientConverter.java | 87 ++++++ .../wiremock/DslToWireMockConverter.java} | 22 +- 9 files changed, 422 insertions(+), 303 deletions(-) delete mode 100644 spring-cloud-contract-tools/spring-cloud-contract-converters/src/main/groovy/org/springframework/cloud/contract/verifier/converter/RecursiveFilesConverter.groovy delete mode 100644 spring-cloud-contract-tools/spring-cloud-contract-converters/src/main/groovy/org/springframework/cloud/contract/verifier/converter/StubGeneratorProvider.groovy delete mode 100644 spring-cloud-contract-tools/spring-cloud-contract-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/DslToWireMockClientConverter.groovy rename spring-cloud-contract-tools/spring-cloud-contract-converters/src/main/{groovy/org/springframework/cloud/contract/verifier/converter/ConversionContractVerifierException.groovy => java/org/springframework/cloud/contract/verifier/converter/ConversionContractVerifierException.java} (67%) create mode 100644 spring-cloud-contract-tools/spring-cloud-contract-converters/src/main/java/org/springframework/cloud/contract/verifier/converter/RecursiveFilesConverter.java rename spring-cloud-contract-tools/spring-cloud-contract-converters/src/main/{groovy => java}/org/springframework/cloud/contract/verifier/converter/StubGenerator.java (100%) create mode 100644 spring-cloud-contract-tools/spring-cloud-contract-converters/src/main/java/org/springframework/cloud/contract/verifier/converter/StubGeneratorProvider.java create mode 100644 spring-cloud-contract-tools/spring-cloud-contract-converters/src/main/java/org/springframework/cloud/contract/verifier/wiremock/DslToWireMockClientConverter.java rename spring-cloud-contract-tools/spring-cloud-contract-converters/src/main/{groovy/org/springframework/cloud/contract/verifier/wiremock/DslToWireMockConverter.groovy => java/org/springframework/cloud/contract/verifier/wiremock/DslToWireMockConverter.java} (63%) diff --git a/spring-cloud-contract-tools/spring-cloud-contract-converters/src/main/groovy/org/springframework/cloud/contract/verifier/converter/RecursiveFilesConverter.groovy b/spring-cloud-contract-tools/spring-cloud-contract-converters/src/main/groovy/org/springframework/cloud/contract/verifier/converter/RecursiveFilesConverter.groovy deleted file mode 100644 index 8088c4b1f9..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-converters/src/main/groovy/org/springframework/cloud/contract/verifier/converter/RecursiveFilesConverter.groovy +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.verifier.converter - -import java.nio.charset.StandardCharsets -import java.nio.file.Files -import java.nio.file.Path -import java.nio.file.Paths - -import groovy.transform.CompileStatic -import groovy.util.logging.Commons -import wiremock.com.google.common.collect.ListMultimap - -import org.springframework.cloud.contract.spec.Contract -import org.springframework.cloud.contract.verifier.config.ContractVerifierConfigProperties -import org.springframework.cloud.contract.verifier.file.ContractFileScanner -import org.springframework.cloud.contract.verifier.file.ContractFileScannerBuilder -import org.springframework.cloud.contract.verifier.file.ContractMetadata -import org.springframework.cloud.contract.verifier.util.NamesUtil -import org.springframework.cloud.contract.verifier.wiremock.DslToWireMockClientConverter - -/** - * Recursively converts contracts into their stub representations - * - * @since 1.1.0 - */ -@Commons -@CompileStatic -class RecursiveFilesConverter { - - private final StubGeneratorProvider holder - private final File outMappingsDir - private final File contractsDslDir - private final List excludedFiles - private final String includedContracts - private final boolean excludeBuildFolders - - // Use constructor without ContractVerifierConfigProperties - @Deprecated - RecursiveFilesConverter(ContractVerifierConfigProperties props, StubGeneratorProvider holder = null) { - this(props.stubsOutputDir, props.contractsDslDir, props.excludedFiles, props.includedContracts, props.excludeBuildFolders, holder) - } - - // Use constructor without ContractVerifierConfigProperties - @Deprecated - RecursiveFilesConverter(ContractVerifierConfigProperties props, File stubsOutputDir, StubGeneratorProvider holder = null) { - this(stubsOutputDir, props.contractsDslDir, props.excludedFiles, props.includedContracts, props.excludeBuildFolders, holder) - } - - RecursiveFilesConverter(File stubsOutputDir, File contractsDslDir, List excludedFiles, - String includedContracts, boolean excludeBuildFolders, StubGeneratorProvider holder = null) { - this.outMappingsDir = stubsOutputDir - this.contractsDslDir = contractsDslDir - this.excludedFiles = excludedFiles - this.includedContracts = includedContracts - this.excludeBuildFolders = excludeBuildFolders - this.holder = holder ?: new StubGeneratorProvider() - } - - void processFiles() { - ContractFileScanner scanner = new ContractFileScannerBuilder() - .baseDir(contractsDslDir) - .excluded(excludedFiles as Set) - .ignored([] as Set) - .included([] as Set) - .includeMatcher(includedContracts) - .build() - ListMultimap contracts = scanner.findContracts() - if (log.isDebugEnabled()) { - log.debug("Found the following contracts $contracts") - } - contracts.asMap().entrySet().each { entry -> - entry.value.each { ContractMetadata contract -> - if (log.isDebugEnabled()) { - log.debug("Will create a stub for contract [${contract}]") - } - File sourceFile = contract.path.toFile() - Collection stubGenerators = contract.convertedContract ? holder. - allOrDefault(new DslToWireMockClientConverter()) : - holder.converterForName(sourceFile.name) - try { - String path = sourceFile.path - if (excludeBuildFolders - && ( - matchesPath(path, "target") || matchesPath(path, "build"))) { - if (log.isDebugEnabled()) { - log.debug("Exclude build folder is set. Path [${path}] contains [target] or [build] in its path") - } - return - } - if (!contract.convertedContract && !stubGenerators) { - return - } - int contractsSize = contract.convertedContract.size() - def entryKey = entry.key - if (log.isDebugEnabled()) { - log.debug("Stub Generators [${stubGenerators}] will convert contents of [${entryKey}]") - } - stubGenerators.each { StubGenerator stubGenerator -> - Map convertedContent = stubGenerator. - convertContents(entryKey.last().toString(), contract) - if (!convertedContent) { - return - } - convertedContent.entrySet(). - eachWithIndex { Map.Entry content, int index -> - Contract dsl = content.key - String converted = content.value - if (converted) { - Path absoluteTargetPath = - createAndReturnTargetDirectory(sourceFile) - File newJsonFile = - createTargetFileWithProperName(stubGenerator, absoluteTargetPath, - sourceFile, contractsSize, index, dsl) - newJsonFile.setText(converted, StandardCharsets.UTF_8. - toString()) - } - } - } - } - catch (Exception e) { - throw new ConversionContractVerifierException("Unable to make conversion of ${sourceFile.name}", e) - } - } - } - } - - private boolean matchesPath(String path, String folder) { - return path.matches("^.*${File.separator}${folder}${File.separator}.*\$") - } - - private Path createAndReturnTargetDirectory(File sourceFile) { - Path relativePath = Paths.get(contractsDslDir.toURI()). - relativize(sourceFile.parentFile.toPath()) - Path absoluteTargetPath = outMappingsDir.toPath().resolve(relativePath) - Files.createDirectories(absoluteTargetPath) - return absoluteTargetPath - } - - private File createTargetFileWithProperName(StubGenerator stubGenerator, Path absoluteTargetPath, - File sourceFile, int contractsSize, int index, Contract dsl) { - String name = generateName(dsl, contractsSize, stubGenerator, sourceFile, index) - File newJsonFile = new File(absoluteTargetPath.toFile(), name) - log.info("Creating new stub [$newJsonFile.path]") - return newJsonFile - } - - private String generateName(Contract dsl, int contractsSize, StubGenerator converter, - File sourceFile, int index) { - String generatedName = converter.generateOutputFileNameForInput(sourceFile.name) - boolean hasDot = NamesUtil.hasDot(generatedName) - String extension = hasDot ? NamesUtil.afterLastDot(generatedName) : "" - if (dsl.name && extension) { - return "${dsl.name}.${extension}" - } - else if (contractsSize == 1) { - return generatedName - } - return "${index}_${generatedName}" - } -} diff --git a/spring-cloud-contract-tools/spring-cloud-contract-converters/src/main/groovy/org/springframework/cloud/contract/verifier/converter/StubGeneratorProvider.groovy b/spring-cloud-contract-tools/spring-cloud-contract-converters/src/main/groovy/org/springframework/cloud/contract/verifier/converter/StubGeneratorProvider.groovy deleted file mode 100644 index 627bccaa94..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-converters/src/main/groovy/org/springframework/cloud/contract/verifier/converter/StubGeneratorProvider.groovy +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.verifier.converter - -import groovy.transform.CompileStatic - -import org.springframework.core.io.support.SpringFactoriesLoader - -/** - * Retrieves file converters from the class path and operates on them. - * - * @author Marcin Grzejszczak - * @since 1.1.0 - */ -@CompileStatic -class StubGeneratorProvider { - - private final List converters = [] - - StubGeneratorProvider() { - this.converters.addAll(SpringFactoriesLoader.loadFactories(StubGenerator, null)) - } - - StubGeneratorProvider(List converters) { - this.converters.addAll(converters) - } - - Collection converterForName(String fileName) { - return this.converters.findAll { it.canHandleFileName(fileName) } - } - - Collection allOrDefault(StubGenerator defaultStubGenerator) { - return this.converters.empty ? [defaultStubGenerator] : this.converters - } -} diff --git a/spring-cloud-contract-tools/spring-cloud-contract-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/DslToWireMockClientConverter.groovy b/spring-cloud-contract-tools/spring-cloud-contract-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/DslToWireMockClientConverter.groovy deleted file mode 100644 index cba897eb4c..0000000000 --- a/spring-cloud-contract-tools/spring-cloud-contract-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/DslToWireMockClientConverter.groovy +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2013-2019 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 - * - * https://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.verifier.wiremock - -import groovy.transform.CompileStatic - -import org.springframework.cloud.contract.spec.Contract -import org.springframework.cloud.contract.verifier.dsl.wiremock.WireMockStubStrategy -import org.springframework.cloud.contract.verifier.file.ContractMetadata -import org.springframework.cloud.contract.verifier.util.NamesUtil - -/** - * Converts DSLs to WireMock stubs - * - * @since 1.0.0 - */ -@CompileStatic -class DslToWireMockClientConverter extends DslToWireMockConverter { - - private String convertASingleContract(String rootName, ContractMetadata contract, Contract dsl) { - return new WireMockStubStrategy(rootName, contract, dsl).toWireMockClientStub() - } - - @Override - Map convertContents(String rootName, ContractMetadata contract) { - if (!(contract.convertedContract.any { it.request })) { - return [:] - } - if (contract.convertedContract.size() == 1) { - return [(contract.convertedContract.first()): - convertASingleContract(rootName, contract, contract.convertedContract. - first())] - } - Map convertedContracts = [:] - contract.convertedContract.findAll { it.request }. - eachWithIndex { Contract dsl, int index -> - String name = dsl.name ? NamesUtil. - convertIllegalPackageChars(dsl.name) : "${rootName}_${index}" - convertedContracts << [(dsl): convertASingleContract(name, contract, dsl)] - } - return convertedContracts - } - -} diff --git a/spring-cloud-contract-tools/spring-cloud-contract-converters/src/main/groovy/org/springframework/cloud/contract/verifier/converter/ConversionContractVerifierException.groovy b/spring-cloud-contract-tools/spring-cloud-contract-converters/src/main/java/org/springframework/cloud/contract/verifier/converter/ConversionContractVerifierException.java similarity index 67% rename from spring-cloud-contract-tools/spring-cloud-contract-converters/src/main/groovy/org/springframework/cloud/contract/verifier/converter/ConversionContractVerifierException.groovy rename to spring-cloud-contract-tools/spring-cloud-contract-converters/src/main/java/org/springframework/cloud/contract/verifier/converter/ConversionContractVerifierException.java index 85b0ca642b..50fe9c7148 100644 --- a/spring-cloud-contract-tools/spring-cloud-contract-converters/src/main/groovy/org/springframework/cloud/contract/verifier/converter/ConversionContractVerifierException.groovy +++ b/spring-cloud-contract-tools/spring-cloud-contract-converters/src/main/java/org/springframework/cloud/contract/verifier/converter/ConversionContractVerifierException.java @@ -14,21 +14,19 @@ * limitations under the License. */ -package org.springframework.cloud.contract.verifier.converter +package org.springframework.cloud.contract.verifier.converter; -import groovy.transform.CompileStatic - -import org.springframework.cloud.contract.spec.ContractVerifierException +import org.springframework.cloud.contract.spec.ContractVerifierException; /** - * Thrown when a a DSL can't be properly converted + * Thrown when a a DSL can't be properly converted. * * @since 1.0.0 */ -@CompileStatic -class ConversionContractVerifierException extends ContractVerifierException { +public class ConversionContractVerifierException extends ContractVerifierException { - ConversionContractVerifierException(String message, Throwable cause) { - super(message, cause) + public ConversionContractVerifierException(String message, Throwable cause) { + super(message, cause); } + } diff --git a/spring-cloud-contract-tools/spring-cloud-contract-converters/src/main/java/org/springframework/cloud/contract/verifier/converter/RecursiveFilesConverter.java b/spring-cloud-contract-tools/spring-cloud-contract-converters/src/main/java/org/springframework/cloud/contract/verifier/converter/RecursiveFilesConverter.java new file mode 100644 index 0000000000..e240d54b92 --- /dev/null +++ b/spring-cloud-contract-tools/spring-cloud-contract-converters/src/main/java/org/springframework/cloud/contract/verifier/converter/RecursiveFilesConverter.java @@ -0,0 +1,261 @@ +/* + * Copyright 2013-2019 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 + * + * https://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.verifier.converter; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.Set; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import wiremock.com.google.common.collect.ListMultimap; + +import org.springframework.cloud.contract.spec.Contract; +import org.springframework.cloud.contract.verifier.config.ContractVerifierConfigProperties; +import org.springframework.cloud.contract.verifier.file.ContractFileScanner; +import org.springframework.cloud.contract.verifier.file.ContractFileScannerBuilder; +import org.springframework.cloud.contract.verifier.file.ContractMetadata; +import org.springframework.cloud.contract.verifier.util.NamesUtil; +import org.springframework.cloud.contract.verifier.wiremock.DslToWireMockClientConverter; +import org.springframework.util.StringUtils; + +/** + * Recursively converts contracts into their stub representations. + * + * @since 1.1.0 + */ +public class RecursiveFilesConverter { + + private static final Log log = LogFactory.getLog(RecursiveFilesConverter.class); + + private final StubGeneratorProvider holder; + + private final File outMappingsDir; + + private final File contractsDslDir; + + private final List excludedFiles; + + private final String includedContracts; + + private final boolean excludeBuildFolders; + + @Deprecated + public RecursiveFilesConverter(ContractVerifierConfigProperties props, + StubGeneratorProvider holder) { + this(props.getStubsOutputDir(), props.getContractsDslDir(), + props.getExcludedFiles(), props.getIncludedContracts(), + props.getExcludeBuildFolders(), holder); + } + + @Deprecated + public RecursiveFilesConverter(ContractVerifierConfigProperties props) { + this(props.getStubsOutputDir(), props.getContractsDslDir(), + props.getExcludedFiles(), props.getIncludedContracts(), + props.getExcludeBuildFolders(), null); + } + + @Deprecated + public RecursiveFilesConverter(ContractVerifierConfigProperties props, + File stubsOutputDir) { + this(stubsOutputDir, props.getContractsDslDir(), props.getExcludedFiles(), + props.getIncludedContracts(), props.getExcludeBuildFolders(), null); + } + + @Deprecated + public RecursiveFilesConverter(ContractVerifierConfigProperties props, + File stubsOutputDir, StubGeneratorProvider holder) { + this(stubsOutputDir, props.getContractsDslDir(), props.getExcludedFiles(), + props.getIncludedContracts(), props.getExcludeBuildFolders(), holder); + } + + public RecursiveFilesConverter(File stubsOutputDir, File contractsDslDir, + List excludedFiles, String includedContracts, + boolean excludeBuildFolders, StubGeneratorProvider holder) { + this.outMappingsDir = stubsOutputDir; + this.contractsDslDir = contractsDslDir; + this.excludedFiles = excludedFiles; + this.includedContracts = includedContracts; + this.excludeBuildFolders = excludeBuildFolders; + this.holder = holder == null ? new StubGeneratorProvider() : holder; + } + + public RecursiveFilesConverter(File stubsOutputDir, File contractsDslDir, + List excludedFiles, String includedContracts, + boolean excludeBuildFolders) { + this(stubsOutputDir, contractsDslDir, excludedFiles, includedContracts, + excludeBuildFolders, null); + } + + public void processFiles() { + ContractFileScanner scanner = new ContractFileScannerBuilder() + .baseDir(contractsDslDir).excluded(new HashSet<>(excludedFiles)) + .ignored(new HashSet<>()).included(new HashSet<>()) + .includeMatcher(includedContracts).build(); + ListMultimap contracts = scanner.findContracts(); + if (log.isDebugEnabled()) { + log.debug("Found the following contracts " + contracts); + } + for (Map.Entry> entry : contracts.asMap() + .entrySet()) { + for (ContractMetadata contract : entry.getValue()) { + if (log.isDebugEnabled()) { + log.debug("Will create a stub for contract [" + contract + "]"); + } + File sourceFile = contract.getPath().toFile(); + Collection stubGenerators = contract + .getConvertedContract() != null + ? holder.allOrDefault(new DslToWireMockClientConverter()) + : holder.converterForName(sourceFile.getName()); + try { + String path = sourceFile.getPath(); + if (excludeBuildFolders && (matchesPath(path, "target") + || matchesPath(path, "build"))) { + if (log.isDebugEnabled()) { + log.debug("Exclude build folder is set. Path [" + path + + "] contains [target] or [build] in its path"); + } + + continue; + } + if (nullOrEmpty(contract) && nullOrEmpty(stubGenerators)) { + continue; + } + int contractsSize = contract.getConvertedContract().size(); + Path entryKey = entry.getKey(); + if (log.isDebugEnabled()) { + log.debug("Stub Generators [" + stubGenerators + + "] will convert contents of [" + entryKey + "]"); + } + + for (StubGenerator stubGenerator : stubGenerators) { + Map convertedContent = stubGenerator + .convertContents(last(entryKey).toString(), contract); + if (convertedContent == null || convertedContent.isEmpty()) { + continue; + } + Set> entrySet = convertedContent + .entrySet(); + Iterator> iterator = entrySet + .iterator(); + int index = 0; + while (iterator.hasNext()) { + Map.Entry content = iterator.next(); + Contract dsl = content.getKey(); + String converted = content.getValue(); + if (StringUtils.hasText(converted)) { + Path absoluteTargetPath = createAndReturnTargetDirectory( + sourceFile); + File newJsonFile = createTargetFileWithProperName( + stubGenerator, absoluteTargetPath, sourceFile, + contractsSize, index, dsl); + Files.write(newJsonFile.toPath(), + Collections.singletonList(converted), + StandardCharsets.UTF_8); + } + index = index + 1; + } + + } + + } + catch (Exception e) { + throw new ConversionContractVerifierException( + "Unable to make conversion of " + sourceFile.getName(), e); + } + + } + + } + + } + + private static T last(Iterable self) { + Iterator iterator = self.iterator(); + if (!iterator.hasNext()) { + throw new NoSuchElementException( + "Cannot access last() element from an empty Iterable"); + } + T result = null; + while (iterator.hasNext()) { + result = iterator.next(); + } + return result; + } + + private boolean nullOrEmpty(ContractMetadata contract) { + return contract.getConvertedContract() == null + || nullOrEmpty(contract.getConvertedContract()); + } + + private boolean nullOrEmpty(Collection collection) { + return collection == null || collection.isEmpty(); + } + + private boolean matchesPath(String path, String folder) { + return path.matches("^.*" + File.separator + folder + File.separator + ".*$"); + } + + private Path createAndReturnTargetDirectory(File sourceFile) { + Path relativePath = Paths.get(contractsDslDir.toURI()) + .relativize(sourceFile.getParentFile().toPath()); + Path absoluteTargetPath = outMappingsDir.toPath().resolve(relativePath); + try { + Files.createDirectories(absoluteTargetPath); + } + catch (IOException ex) { + throw new IllegalStateException(ex); + } + return absoluteTargetPath; + } + + private File createTargetFileWithProperName(StubGenerator stubGenerator, + Path absoluteTargetPath, File sourceFile, int contractsSize, int index, + Contract dsl) { + String name = generateName(dsl, contractsSize, stubGenerator, sourceFile, index); + File newJsonFile = new File(absoluteTargetPath.toFile(), name); + log.info("Creating new stub [" + newJsonFile.getPath() + "]"); + return newJsonFile; + } + + private String generateName(Contract dsl, int contractsSize, StubGenerator converter, + File sourceFile, int index) { + String generatedName = converter + .generateOutputFileNameForInput(sourceFile.getName()); + boolean hasDot = NamesUtil.hasDot(generatedName); + String extension = hasDot ? NamesUtil.afterLastDot(generatedName) : ""; + if (StringUtils.hasText(dsl.getName()) && StringUtils.hasText(extension)) { + return dsl.getName() + "." + extension; + } + else if (contractsSize == 1) { + return generatedName; + } + return index + "_" + generatedName; + } + +} diff --git a/spring-cloud-contract-tools/spring-cloud-contract-converters/src/main/groovy/org/springframework/cloud/contract/verifier/converter/StubGenerator.java b/spring-cloud-contract-tools/spring-cloud-contract-converters/src/main/java/org/springframework/cloud/contract/verifier/converter/StubGenerator.java similarity index 100% rename from spring-cloud-contract-tools/spring-cloud-contract-converters/src/main/groovy/org/springframework/cloud/contract/verifier/converter/StubGenerator.java rename to spring-cloud-contract-tools/spring-cloud-contract-converters/src/main/java/org/springframework/cloud/contract/verifier/converter/StubGenerator.java diff --git a/spring-cloud-contract-tools/spring-cloud-contract-converters/src/main/java/org/springframework/cloud/contract/verifier/converter/StubGeneratorProvider.java b/spring-cloud-contract-tools/spring-cloud-contract-converters/src/main/java/org/springframework/cloud/contract/verifier/converter/StubGeneratorProvider.java new file mode 100644 index 0000000000..2f06c594ce --- /dev/null +++ b/spring-cloud-contract-tools/spring-cloud-contract-converters/src/main/java/org/springframework/cloud/contract/verifier/converter/StubGeneratorProvider.java @@ -0,0 +1,57 @@ +/* + * Copyright 2013-2019 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 + * + * https://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.verifier.converter; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +import org.springframework.core.io.support.SpringFactoriesLoader; + +/** + * Retrieves file converters from the class path and operates on them. + * + * @author Marcin Grzejszczak + * @since 1.1.0 + */ +public class StubGeneratorProvider { + + public StubGeneratorProvider() { + this.converters + .addAll(SpringFactoriesLoader.loadFactories(StubGenerator.class, null)); + } + + public StubGeneratorProvider(List converters) { + this.converters.addAll(converters); + } + + public Collection converterForName(final String fileName) { + return this.converters.stream() + .filter(stubGenerator -> stubGenerator.canHandleFileName(fileName)) + .collect(Collectors.toList()); + } + + public Collection allOrDefault(StubGenerator defaultStubGenerator) { + return this.converters.isEmpty() ? Collections.singletonList(defaultStubGenerator) + : this.converters; + } + + private final List converters = new ArrayList(); + +} diff --git a/spring-cloud-contract-tools/spring-cloud-contract-converters/src/main/java/org/springframework/cloud/contract/verifier/wiremock/DslToWireMockClientConverter.java b/spring-cloud-contract-tools/spring-cloud-contract-converters/src/main/java/org/springframework/cloud/contract/verifier/wiremock/DslToWireMockClientConverter.java new file mode 100644 index 0000000000..9c9690cb3b --- /dev/null +++ b/spring-cloud-contract-tools/spring-cloud-contract-converters/src/main/java/org/springframework/cloud/contract/verifier/wiremock/DslToWireMockClientConverter.java @@ -0,0 +1,87 @@ +/* + * Copyright 2013-2019 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 + * + * https://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.verifier.wiremock; + +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.stream.Collectors; + +import org.springframework.cloud.contract.spec.Contract; +import org.springframework.cloud.contract.verifier.dsl.wiremock.WireMockStubStrategy; +import org.springframework.cloud.contract.verifier.file.ContractMetadata; +import org.springframework.cloud.contract.verifier.util.NamesUtil; +import org.springframework.util.StringUtils; + +/** + * Converts DSLs to WireMock stubs. + * + * @since 1.0.0 + */ +public class DslToWireMockClientConverter extends DslToWireMockConverter { + + private String convertASingleContract(String rootName, ContractMetadata contract, + Contract dsl) { + return new WireMockStubStrategy(rootName, contract, dsl).toWireMockClientStub(); + } + + @Override + public Map convertContents(String rootName, + ContractMetadata contract) { + List httpContracts = httpContracts(contract); + if (httpContracts.isEmpty()) { + return new HashMap<>(); + } + if (contract.getConvertedContract().size() == 1) { + return Collections.singletonMap( + first((List) contract.getConvertedContract()), + convertASingleContract(rootName, contract, + first((List) contract.getConvertedContract()))); + } + return convertContracts(rootName, contract, httpContracts); + } + + private List httpContracts(ContractMetadata contract) { + return contract.getConvertedContract().stream() + .filter(c -> c.getRequest() != null).collect(Collectors.toList()); + } + + private Map convertContracts(String rootName, + ContractMetadata contract, List contractsWithRequest) { + Map convertedContracts = new LinkedHashMap<>(); + for (int i = 0; i < contractsWithRequest.size(); i++) { + Contract dsl = contractsWithRequest.get(i); + String name = StringUtils.hasText(dsl.getName()) + ? NamesUtil.convertIllegalPackageChars(dsl.getName()) + : rootName + "_" + i; + convertedContracts.put(dsl, convertASingleContract(name, contract, dsl)); + } + return convertedContracts; + } + + private static T first(List self) { + if (self.isEmpty()) { + throw new NoSuchElementException( + "Cannot access first() element from an empty List"); + } + return self.get(0); + } + +} diff --git a/spring-cloud-contract-tools/spring-cloud-contract-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/DslToWireMockConverter.groovy b/spring-cloud-contract-tools/spring-cloud-contract-converters/src/main/java/org/springframework/cloud/contract/verifier/wiremock/DslToWireMockConverter.java similarity index 63% rename from spring-cloud-contract-tools/spring-cloud-contract-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/DslToWireMockConverter.groovy rename to spring-cloud-contract-tools/spring-cloud-contract-converters/src/main/java/org/springframework/cloud/contract/verifier/wiremock/DslToWireMockConverter.java index 85fc32e44e..273cb61b8a 100644 --- a/spring-cloud-contract-tools/spring-cloud-contract-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/DslToWireMockConverter.groovy +++ b/spring-cloud-contract-tools/spring-cloud-contract-converters/src/main/java/org/springframework/cloud/contract/verifier/wiremock/DslToWireMockConverter.java @@ -14,30 +14,28 @@ * limitations under the License. */ -package org.springframework.cloud.contract.verifier.wiremock +package org.springframework.cloud.contract.verifier.wiremock; -import groovy.transform.CompileStatic - -import org.springframework.cloud.contract.verifier.converter.StubGenerator +import org.springframework.cloud.contract.verifier.converter.StubGenerator; /** - * WireMock implementation of the {@link StubGenerator} + * WireMock implementation of the {@link StubGenerator}. * * @since 1.0.0 */ -@CompileStatic -abstract class DslToWireMockConverter implements StubGenerator { +public abstract class DslToWireMockConverter implements StubGenerator { @Override - String generateOutputFileNameForInput(String inputFileName) { - return inputFileName.replaceAll(extension(inputFileName), 'json') + public String generateOutputFileNameForInput(String inputFileName) { + return inputFileName.replaceAll(extension(inputFileName), "json"); } private String extension(String inputFileName) { - int i = inputFileName.lastIndexOf('.') + int i = inputFileName.lastIndexOf("."); if (i > 0) { - return inputFileName.substring(i + 1) + return inputFileName.substring(i + 1); } - return "" + return ""; } + }