diff --git a/docs/src/main/asciidoc/verifier/contract.adoc b/docs/src/main/asciidoc/verifier/contract.adoc index 24d60699c9..d7da5a6752 100644 --- a/docs/src/main/asciidoc/verifier/contract.adoc +++ b/docs/src/main/asciidoc/verifier/contract.adoc @@ -855,6 +855,9 @@ include::{converters_path}/src/main/resources/META-INF/spring.factories[indent=0 The default implementation is the WireMock stub generation. +TIP: You can provide multiple stub generator implementations. That way for example from a single +DSL as input you can e.g. produce WireMock stubs and Pact files too! + ==== Custom Stub Runner If you decide to have a custom stub generation you also need a custom way of running 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 index 677c9cd369..791839b976 100644 --- 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 @@ -69,7 +69,7 @@ class RecursiveFilesConverter { log.debug("Will create a stub for contract [${contract}]") } File sourceFile = contract.path.toFile() - StubGenerator stubGenerator = contract.convertedContract ? holder.firstOrDefault(new DslToWireMockClientConverter()) : + Collection stubGenerators = contract.convertedContract ? holder.allOrDefault(new DslToWireMockClientConverter()) : holder.converterForName(sourceFile.name) try { String path = sourceFile.path @@ -79,25 +79,27 @@ class RecursiveFilesConverter { } return } - if (!contract.convertedContract && !stubGenerator) { + if (!contract.convertedContract && !stubGenerators) { return } int contractsSize = contract.convertedContract.size() def entryKey = entry.key if (log.isDebugEnabled()) { - log.debug("Stub Generator [${stubGenerator}] will convert contents of [${entryKey}]") + log.debug("Stub Generators [${stubGenerators}] will convert contents of [${entryKey}]") } - 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 - Path absoluteTargetPath = createAndReturnTargetDirectory(sourceFile) - File newJsonFile = createTargetFileWithProperName(stubGenerator, absoluteTargetPath, - sourceFile, contractsSize, index, dsl) - newJsonFile.setText(converted, StandardCharsets.UTF_8.toString()) + 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 + 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) 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 index 5afade974b..0bc23eeef0 100644 --- 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 @@ -22,11 +22,11 @@ class StubGeneratorProvider { this.converters.addAll(converters) } - StubGenerator converterForName(String fileName) { - return this.converters.find { it.canHandleFileName(fileName) } + Collection converterForName(String fileName) { + return this.converters.findAll { it.canHandleFileName(fileName) } } - StubGenerator firstOrDefault(StubGenerator defaultStubGenerator) { - return this.converters.empty ? defaultStubGenerator : this.converters.first() + 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/RecursiveFilesConverter.groovy b/spring-cloud-contract-tools/spring-cloud-contract-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/RecursiveFilesConverter.groovy index b454781c82..1974030fa7 100644 --- a/spring-cloud-contract-tools/spring-cloud-contract-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/RecursiveFilesConverter.groovy +++ b/spring-cloud-contract-tools/spring-cloud-contract-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/RecursiveFilesConverter.groovy @@ -86,7 +86,7 @@ class RecursiveFilesConverter { contracts.asMap().entrySet().each { entry -> entry.value.each { ContractMetadata contract -> File sourceFile = contract.path.toFile() - StubGenerator stubGenerator = holder.converterForName(sourceFile.name); + StubGenerator stubGenerator = holder.converterForName(sourceFile.name).first() try { String path = sourceFile.path if (properties.isExcludeBuildFolders() && (matchesPath(path, "target") || matchesPath(path, "build"))) { diff --git a/spring-cloud-contract-tools/spring-cloud-contract-converters/src/test/groovy/org/springframework/cloud/contract/verifier/converter/RecursiveFilesConverterSpec.groovy b/spring-cloud-contract-tools/spring-cloud-contract-converters/src/test/groovy/org/springframework/cloud/contract/verifier/converter/RecursiveFilesConverterSpec.groovy index 32db60238d..d3628d8542 100755 --- a/spring-cloud-contract-tools/spring-cloud-contract-converters/src/test/groovy/org/springframework/cloud/contract/verifier/converter/RecursiveFilesConverterSpec.groovy +++ b/spring-cloud-contract-tools/spring-cloud-contract-converters/src/test/groovy/org/springframework/cloud/contract/verifier/converter/RecursiveFilesConverterSpec.groovy @@ -19,7 +19,9 @@ package org.springframework.cloud.contract.verifier.converter import groovy.io.FileType import org.junit.Rule import org.junit.rules.TemporaryFolder +import org.springframework.cloud.contract.spec.Contract import org.springframework.cloud.contract.verifier.config.ContractVerifierConfigProperties +import org.springframework.cloud.contract.verifier.file.ContractMetadata import org.springframework.util.FileSystemUtils import spock.lang.Specification @@ -98,12 +100,62 @@ class RecursiveFilesConverterSpec extends Specification { e.cause?.message == "Test conversion error" } - private - static Set getRelativePathsForFilesInDirectory(Collection createdFiles, File targetRootDirectory) { + def "should convert contract into stub using all possible converters"() { + given: + def sourceFile = tmpFolder.newFile("test.groovy") + sourceFile.text = """ + org.springframework.cloud.contract.spec.Contract.make { + request { + url "/baz" + method "GET" + } + response { + status 200 + } + } + """ + and: + StubGenerator stubGenerator1 = stubGenerator("foo") + and: + StubGenerator stubGenerator2 = stubGenerator("bar") + and: + ContractVerifierConfigProperties properties = new ContractVerifierConfigProperties() + properties.contractsDslDir = tmpFolder.root + properties.stubsOutputDir = tmpFolder.root + and: + RecursiveFilesConverter recursiveFilesConverter = new RecursiveFilesConverter(properties, new StubGeneratorProvider([stubGenerator1, stubGenerator2])) + when: + recursiveFilesConverter.processFiles() + then: + tmpFolder.root.list().toList().containsAll("foo", "bar") + } + + private static Set getRelativePathsForFilesInDirectory(Collection createdFiles, File targetRootDirectory) { Path rootSourcePath = Paths.get(targetRootDirectory.toURI()) Set relativizedCreatedFiles = createdFiles.collect { File file -> rootSourcePath.relativize(Paths.get(file.toURI())) } return relativizedCreatedFiles } + + private StubGenerator stubGenerator(String stub) { + return new StubGenerator() { + @Override + boolean canHandleFileName(String fileName) { + return true + } + + @Override + Map convertContents(String rootName, ContractMetadata content) { + return [ + (content.convertedContract.first()) : stub + ] + } + + @Override + String generateOutputFileNameForInput(String inputFileName) { + return stub + } + } + } }