From 366b77c3a18f3acf9c3355930e78dd9fb7e1147a Mon Sep 17 00:00:00 2001 From: John Thompson Date: Tue, 16 Apr 2019 02:30:53 -0400 Subject: [PATCH] Updating YamlContractConverter to during isAccepted method, to (#1037) parse file and return false is parse fails. Closes #1036 --- .../converter/YamlContractConverter.groovy | 16 +- .../YamlContractConverterSpec.groovy | 24 ++- .../resources/yml/oa3/openapi_petstore.yml | 157 ++++++++++++++++++ 3 files changed, 193 insertions(+), 4 deletions(-) create mode 100644 spring-cloud-contract-verifier/src/test/resources/yml/oa3/openapi_petstore.yml diff --git a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/converter/YamlContractConverter.groovy b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/converter/YamlContractConverter.groovy index 9362ed127f..3824f5a0c6 100644 --- a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/converter/YamlContractConverter.groovy +++ b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/converter/YamlContractConverter.groovy @@ -18,7 +18,7 @@ package org.springframework.cloud.contract.verifier.converter import com.fasterxml.jackson.dataformat.yaml.YAMLMapper import groovy.transform.CompileStatic - +import groovy.util.logging.Slf4j import org.springframework.cloud.contract.spec.Contract import org.springframework.cloud.contract.spec.ContractConverter @@ -28,6 +28,7 @@ import org.springframework.cloud.contract.spec.ContractConverter * @since 1.2.1* @author Marcin Grzejszczak * @author Tim Ysewyn */ +@Slf4j @CompileStatic class YamlContractConverter implements ContractConverter> { @@ -39,7 +40,18 @@ class YamlContractConverter implements ContractConverter> { @Override boolean isAccepted(File file) { String name = file.getName() - return name.endsWith(".yml") || name.endsWith(".yaml") + boolean acceptFile = name.endsWith(".yml") || name.endsWith(".yaml") + + if (acceptFile){ + try { + yamlToContracts.convertFrom(file) + } catch (e) { + log.warn("Error Processing yaml file. Skipping Contract Generation ", e) + acceptFile = false + } + } + + return acceptFile } @Override diff --git a/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/converter/YamlContractConverterSpec.groovy b/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/converter/YamlContractConverterSpec.groovy index 66d2e16002..b2f1e22227 100644 --- a/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/converter/YamlContractConverterSpec.groovy +++ b/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/converter/YamlContractConverterSpec.groovy @@ -89,6 +89,10 @@ class YamlContractConverterSpec extends Specification { URL ymlRestXmlFile = YamlContractConverterSpec. getResource("/yml/contract_rest_xml.yml") File ymlRestXml = new File(ymlRestXmlFile.toURI()) + + URL oa3SpecUrl = YamlContractConverterSpec.getResource('/yml/oa3/openapi_petstore.yml') + File oa3File = new File(oa3SpecUrl.toURI()) + YamlContractConverter converter = new YamlContractConverter() String xmlContractBody = ''' @@ -638,7 +642,7 @@ class YamlContractConverterSpec extends Specification { given: File yml = new File(YamlContractConverterSpec.getResource("/yml/contract_broken_request_headers.yml").toURI()) and: - assert converter.isAccepted(yml) + assert !converter.isAccepted(yml) //expecting to fail when: converter.convertFrom(yml) then: @@ -650,7 +654,7 @@ class YamlContractConverterSpec extends Specification { given: File yml = new File(YamlContractConverterSpec.getResource("/yml/contract_broken_response_headers.yml").toURI()) and: - assert converter.isAccepted(yml) + assert !converter.isAccepted(yml) //expecting to fail when: converter.convertFrom(yml) then: @@ -1321,4 +1325,20 @@ ignored: false .replaceAll(' ', '') == xmlContractBody .replaceAll("\n", "").replaceAll(' ', '') } + + def "Should accept file"(){ + when: + def accepted = converter.isAccepted(ymlWithRest3) + + then: + accepted + } + + def "Should NOT accept file"(){ + when: + def accepted = converter.isAccepted(oa3File) + + then: + !accepted + } } diff --git a/spring-cloud-contract-verifier/src/test/resources/yml/oa3/openapi_petstore.yml b/spring-cloud-contract-verifier/src/test/resources/yml/oa3/openapi_petstore.yml new file mode 100644 index 0000000000..ede29d2fe9 --- /dev/null +++ b/spring-cloud-contract-verifier/src/test/resources/yml/oa3/openapi_petstore.yml @@ -0,0 +1,157 @@ +openapi: "3.0.0" +info: + version: 1.0.0 + title: Swagger Petstore + license: + name: MIT +servers: + - url: http://petstore.swagger.io/v1 +paths: + /pets: + get: + summary: List all pets + operationId: listPets + tags: + - pets + # Define Contracts + x-contracts: + - contractId: 1 + name: Test List All Pets, No Limit + requestHeaders: + - Content-type: application/json + serviceName: serviceA + - contractId: 2 + name: Test List All Pets, Limit 5 + requestHeaders: + - Content-type: application/json + serviceName: serviceB + parameters: + - name: limit + in: query + description: How many items to return at one time (max 100) + required: false + schema: + type: integer + format: int32 + # Define Parameters for Contracts + x-contracts: + - contractId: 1 + value: null + - contractId: 2 + value: 5 + responses: + '200': + description: An paged array of pets + headers: + x-next: + description: A link to the next page of responses + schema: + type: string + content: + application/json: + schema: + $ref: "#/components/schemas/Pets" + #Define Expectations for Contracts (expecting 200, application/json response and below conditions) + x-contracts: + - contractId: 1 + matchers: + path: $.* + maxOccurance: 25 + - contractId: 2 + matchers: + path: $.* + maxOccurance: 25 + default: + description: unexpected error + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + post: + description: Creates a new pet in the store. Duplicates are allowed + operationId: addPet + # Define Contracts + x-contracts: + - contractId: 1 + name: Test Create Pet + serviceName: serviceC + requestHeaders: + - Content-type: application/json + requestBody: + description: Pet to add to the store + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/NewPet' + x-contracts: + - contractId: 1 + body: + name: Jake + responses: + '200': + description: pet response + content: + application/json: + schema: + $ref: '#/components/schemas/Pet' + default: + description: unexpected error + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + /pets/{petId}: + get: + summary: Info for a specific pet + operationId: showPetById + tags: + - pets + parameters: + - name: petId + in: path + required: true + description: The id of the pet to retrieve + schema: + type: string + responses: + '200': + description: Expected response to a valid request + content: + application/json: + schema: + $ref: "#/components/schemas/Pets" + default: + description: unexpected error + content: + application/json: + schema: + $ref: "#/components/schemas/Error" +components: + schemas: + Pet: + required: + - id + - name + properties: + id: + type: integer + format: int64 + name: + type: string + tag: + type: string + Pets: + type: array + items: + $ref: "#/components/schemas/Pet" + Error: + required: + - code + - message + properties: + code: + type: integer + format: int32 + message: + type: string \ No newline at end of file