diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/ClientOptInput.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/ClientOptInput.java index 71716ba25c2..2a6f32028ad 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/ClientOptInput.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/ClientOptInput.java @@ -30,12 +30,12 @@ public class ClientOptInput { private List auths; public ClientOptInput openAPI(OpenAPI openAPI) { - this.openAPI = openAPI; + this.setOpenAPI(openAPI); return this; } public ClientOptInput config(CodegenConfig codegenConfig) { - this.config = codegenConfig; + this.setConfig(codegenConfig); return this; } @@ -72,6 +72,10 @@ public class ClientOptInput { @Deprecated public void setConfig(CodegenConfig config) { this.config = config; + // TODO: ClientOptInputs needs to be retired + if (this.openAPI != null) { + this.config.setOpenAPI(this.openAPI); + } } @Deprecated @@ -86,5 +90,9 @@ public class ClientOptInput { @Deprecated public void setOpenAPI(OpenAPI openAPI) { this.openAPI = openAPI; + // TODO: ClientOptInputs needs to be retired + if (this.config != null) { + this.config.setOpenAPI(this.openAPI); + } } } diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenResponse.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenResponse.java index 42120f9ea5d..511c0fc7b60 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenResponse.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenResponse.java @@ -24,7 +24,7 @@ public class CodegenResponse { public String code, message; public boolean hasMore; public List> examples; - public String dataType, baseType, containerType; + public String dataType, baseType, containerType, pattern; public boolean hasHeaders; public boolean isString, isNumeric, isInteger, isLong, isNumber, isFloat, isDouble, isByteArray, isBoolean, isDate, isDateTime, isUuid, isEmail, isModel, isFreeFormObject; @@ -46,7 +46,7 @@ public class CodegenResponse { @Override public boolean equals(Object o) { if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (!(o instanceof CodegenResponse)) return false; CodegenResponse that = (CodegenResponse) o; return hasMore == that.hasMore && hasHeaders == that.hasHeaders && @@ -79,6 +79,7 @@ public class CodegenResponse { Objects.equals(dataType, that.dataType) && Objects.equals(baseType, that.baseType) && Objects.equals(containerType, that.containerType) && + Objects.equals(pattern, that.pattern) && Objects.equals(schema, that.schema) && Objects.equals(jsonSchema, that.jsonSchema) && Objects.equals(vendorExtensions, that.vendorExtensions); @@ -86,8 +87,7 @@ public class CodegenResponse { @Override public int hashCode() { - - return Objects.hash(headers, code, message, hasMore, examples, dataType, baseType, containerType, + return Objects.hash(headers, code, message, hasMore, examples, dataType, baseType, containerType, pattern, hasHeaders, isString, isNumeric, isInteger, isLong, isNumber, isFloat, isDouble, isByteArray, isBoolean, isDate, isDateTime, isUuid, isEmail, isModel, isFreeFormObject, isDefault, simpleType, primitiveType, isMapContainer, isListContainer, isBinary, isFile, schema, jsonSchema, vendorExtensions); @@ -102,6 +102,7 @@ public class CodegenResponse { sb.append(", hasMore=").append(hasMore); sb.append(", examples=").append(examples); sb.append(", dataType='").append(dataType).append('\''); + sb.append(", pattern='").append(pattern).append('\''); sb.append(", baseType='").append(baseType).append('\''); sb.append(", containerType='").append(containerType).append('\''); sb.append(", hasHeaders=").append(hasHeaders); diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java index 7c2c4565b36..1099af7cd49 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java @@ -2887,6 +2887,10 @@ public class DefaultCodegen implements CodegenConfig { responseSchema = ModelUtils.getSchemaFromResponse(response); } r.schema = responseSchema; + if (responseSchema != null && responseSchema.getPattern() != null) { + r.pattern = toRegularExpression(responseSchema.getPattern()); + } + r.message = escapeText(response.getDescription()); // TODO need to revise and test examples in responses // ApiResponse does not support examples at the moment diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/utils/ModelUtils.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/utils/ModelUtils.java index 8a17b0f7305..780857f606c 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/utils/ModelUtils.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/utils/ModelUtils.java @@ -55,7 +55,6 @@ public class ModelUtils { return Boolean.parseBoolean(GlobalSettings.getProperty(generateAliasAsModelKey, "false")); } - /** * Searches for the model by name in the map of models and returns it * diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/DefaultGeneratorTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/DefaultGeneratorTest.java index e8097915a0f..46449c74a3a 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/DefaultGeneratorTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/DefaultGeneratorTest.java @@ -1,19 +1,25 @@ package org.openapitools.codegen; +import io.swagger.models.Response; import io.swagger.v3.oas.models.OpenAPI; import io.swagger.v3.oas.models.Operation; import io.swagger.v3.oas.models.PathItem; import io.swagger.v3.oas.models.Paths; import io.swagger.v3.oas.models.media.IntegerSchema; +import io.swagger.v3.oas.models.media.Schema; import io.swagger.v3.oas.models.media.StringSchema; +import io.swagger.v3.oas.models.parameters.Parameter; import io.swagger.v3.oas.models.parameters.QueryParameter; +import io.swagger.v3.oas.models.parameters.RequestBody; import io.swagger.v3.oas.models.responses.ApiResponse; import io.swagger.v3.oas.models.responses.ApiResponses; +import org.openapitools.codegen.utils.ModelUtils; import org.testng.Assert; import org.testng.annotations.Test; import java.io.File; import java.io.IOException; +import java.util.HashSet; import java.util.List; import java.util.Map; @@ -74,6 +80,48 @@ public class DefaultGeneratorTest { Assert.assertEquals(defaultList.get(1).allParams.size(), 1); } + @Test + public void testRefModelValidationProperties(){ + OpenAPI openAPI = TestUtils.parseSpec("src/test/resources/2_0/refAliasedPrimitiveWithValidation.yml"); + ClientOptInput opts = new ClientOptInput(); + opts.setOpenAPI(openAPI); + DefaultCodegen config = new DefaultCodegen(); + config.setStrictSpecBehavior(false); + opts.setConfig(config); + + DefaultGenerator generator = new DefaultGenerator(); + generator.opts(opts); + + String expectedPattern = "^\\d{3}-\\d{2}-\\d{4}$"; + // NOTE: double-escaped regex for when the value is intended to be dumped in template into a String location. + String escapedPattern = config.toRegularExpression(expectedPattern); + + Schema stringRegex = openAPI.getComponents().getSchemas().get("StringRegex"); + // Sanity check. + Assert.assertEquals(stringRegex.getPattern(), expectedPattern); + + // Validate when we alias/unalias + Schema unaliasedStringRegex = ModelUtils.unaliasSchema(openAPI, stringRegex); + Assert.assertEquals(unaliasedStringRegex.getPattern(), expectedPattern); + + // Validate when converting to property + CodegenProperty stringRegexProperty = config.fromProperty("stringRegex", stringRegex); + Assert.assertEquals(stringRegexProperty.pattern, escapedPattern); + + // Validate when converting to parameter + Operation operation = openAPI.getPaths().get("/fake/StringRegex").getPost(); + RequestBody body = operation.getRequestBody(); + CodegenParameter codegenParameter = config.fromRequestBody(body, new HashSet<>(), "body"); + + Assert.assertEquals(codegenParameter.pattern, escapedPattern); + + // Validate when converting to response + ApiResponse response = operation.getResponses().get("200"); + CodegenResponse codegenResponse = config.fromResponse("200", response); + + Assert.assertEquals(((Schema)codegenResponse.schema).getPattern(), expectedPattern); + Assert.assertEquals(codegenResponse.pattern, escapedPattern); + } @Test public void minimalUpdateTest() throws IOException { diff --git a/modules/openapi-generator/src/test/resources/2_0/refAliasedPrimitiveWithValidation.yml b/modules/openapi-generator/src/test/resources/2_0/refAliasedPrimitiveWithValidation.yml new file mode 100644 index 00000000000..372fd0dc677 --- /dev/null +++ b/modules/openapi-generator/src/test/resources/2_0/refAliasedPrimitiveWithValidation.yml @@ -0,0 +1,78 @@ +swagger: '2.0' +info: + description: "Tests models which trigger aliased primitives but contain JSON Schema Validation Properties" + version: 1.0.0 + title: OpenAPI Petstore + license: + name: Apache-2.0 + url: 'http://www.apache.org/licenses/LICENSE-2.0.html' +host: petstore.swagger.io:80 +basePath: /v2 +tags: + - name: fake + description: A fake api +schemes: + - http +paths: + /fake/StringEnum: + post: + tags: + - fake + description: Test serialization of StringEnum + operationId: StringEnum + parameters: + - name: body + in: body + description: Input string as post body + schema: + $ref: '#/definitions/StringEnum' + responses: + '200': + description: Returned string + schema: + $ref: '#/definitions/StringEnum' + /fake/StringRegex: + post: + tags: + - fake + description: Test serialization of StringRegex + operationId: StringRegex + parameters: + - name: body + in: body + description: Input string as post body + schema: + $ref: '#/definitions/StringRegex' + responses: + '200': + description: Returned string + schema: + $ref: '#/definitions/StringRegex' + /fake/ObjectModelWithRefs: + post: + tags: + - fake + description: Test serialization of ObjectModelWithRefs + operationId: ObjectModelWithRefs + parameters: + - name: body + in: body + description: Input object as post body + schema: + $ref: '#/definitions/ObjectModelWithRefs' + responses: + '200': + description: Returned object + schema: + $ref: '#/definitions/ObjectModelWithRefs' +definitions: + ObjectModelWithRefs: + type: object + required: + - stringRegex + properties: + stringRegex: + $ref: '#/definitions/StringRegex' + StringRegex: + type: string + pattern: '^\d{3}-\d{2}-\d{4}$' \ No newline at end of file