diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/OpenAPINormalizer.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/OpenAPINormalizer.java index 378cee272b1..789b9c9f95c 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/OpenAPINormalizer.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/OpenAPINormalizer.java @@ -221,10 +221,14 @@ public class OpenAPINormalizer { } } + // normalize PathItem common parameters + normalizeParameters(path.getParameters()); + for (Operation operation : operations) { + normalizeOperation(operation); normalizeRequestBody(operation); - normalizeParameters(operation); + normalizeParameters(operation.getParameters()); normalizeResponses(operation); } } @@ -294,10 +298,9 @@ public class OpenAPINormalizer { /** * Normalizes schemas in parameters * - * @param operation target operation + * @param parameters List parameters */ - private void normalizeParameters(Operation operation) { - List parameters = operation.getParameters(); + private void normalizeParameters(List parameters) { if (parameters == null) { return; } diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/OpenAPINormalizerTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/OpenAPINormalizerTest.java index 6bf5bdf1eee..051e961f093 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/OpenAPINormalizerTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/OpenAPINormalizerTest.java @@ -26,6 +26,7 @@ import io.swagger.v3.oas.models.Operation; import io.swagger.v3.oas.models.PathItem; import io.swagger.v3.oas.models.headers.Header; import io.swagger.v3.oas.models.media.*; +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; @@ -371,4 +372,46 @@ public class OpenAPINormalizerTest { assertEquals(((Schema) newSchema.getProperties().get("mum_or_dad")).getType(), "string"); assertEquals(newSchema.getRequired().get(0), "isParent"); } + + @Test + public void testNormalize31Schema() { + OpenAPI openAPI = TestUtils.parseSpec("src/test/resources/3_1/common-parameters.yaml"); + + Map inputRules = Map.of( + "NORMALIZE_31SPEC", "true" + ); + OpenAPINormalizer openAPINormalizer = new OpenAPINormalizer(openAPI, inputRules); + openAPINormalizer.normalize(); + + Schema pet = openAPI.getComponents().getSchemas().get("Pet"); + // verify schema for property id + Schema petSchema = (Schema)pet.getProperties().get("id"); + // both type and types are defined + assertNotNull(petSchema.getType()); + assertNotNull(petSchema.getTypes()); + } + + @Test + public void testNormalize31Parameters() { + OpenAPI openAPI = TestUtils.parseSpec("src/test/resources/3_1/common-parameters.yaml"); + + Map inputRules = Map.of( + "NORMALIZE_31SPEC", "true" + ); + OpenAPINormalizer openAPINormalizer = new OpenAPINormalizer(openAPI, inputRules); + openAPINormalizer.normalize(); + + PathItem pathItem = openAPI.getPaths().get("/pet/{petId}"); + assertNotNull(pathItem); + + // check common parameters + assertEquals(pathItem.getParameters().size(), 1); + assertNotNull(pathItem.getParameters().get(0).getSchema().getType()); + assertNotNull(pathItem.getParameters().get(0).getSchema().getTypes()); + + // check operation (delete) parameters + assertEquals(pathItem.getDelete().getParameters().size(), 1); + assertNotNull(pathItem.getDelete().getParameters().get(0).getSchema().getType()); + assertNotNull(pathItem.getDelete().getParameters().get(0).getSchema().getTypes()); + } } diff --git a/modules/openapi-generator/src/test/resources/3_1/common-parameters.yaml b/modules/openapi-generator/src/test/resources/3_1/common-parameters.yaml new file mode 100644 index 00000000000..6052f3d450f --- /dev/null +++ b/modules/openapi-generator/src/test/resources/3_1/common-parameters.yaml @@ -0,0 +1,227 @@ +openapi: 3.1.0 +servers: + - url: 'http://petstore.swagger.io/v2' +info: + description: >- + This is a sample server Petstore server. For this sample, you can use the api key + `special-key` to test the authorization filters. + version: 1.0.0 + title: OpenAPI Petstore + license: + name: Apache-2.0 + url: 'https://www.apache.org/licenses/LICENSE-2.0.html' +tags: + - name: pet + description: Everything about your Pets +paths: + '/pet/{petId}': + parameters: + - name: petId + in: path + description: ID of pet to return + required: true + schema: + type: integer + format: int64 + get: + tags: + - pet + summary: Find pet by ID + description: Returns a single pet + operationId: getPetById + responses: + '200': + description: successful operation + content: + application/xml: + schema: + $ref: '#/components/schemas/Pet' + application/json: + schema: + $ref: '#/components/schemas/Pet' + '400': + description: Invalid ID supplied + '404': + description: Pet not found + security: + - api_key: [] + delete: + tags: + - pet + summary: Deletes a pet + description: '' + operationId: deletePet + parameters: + - name: api_key + in: header + required: false + schema: + type: string + responses: + '400': + description: Invalid pet value + security: + - api_key: [] + patch: + tags: + - pet + summary: Updates a pet + description: '' + operationId: updatePet + responses: + '400': + description: Invalid pet value + requestBody: + $ref: '#/components/requestBodies/Pet' + security: + - api_key: [] +components: + requestBodies: + Pet: + content: + application/json: + schema: + $ref: '#/components/schemas/Pet' + application/xml: + schema: + $ref: '#/components/schemas/Pet' + description: Pet object that needs to be added to the store + required: true + securitySchemes: + api_key: + type: apiKey + name: api_key + in: header + schemas: + Order: + title: Pet Order + description: An order for a pets from the pet store + type: object + properties: + id: + type: integer + format: int64 + petId: + type: integer + format: int64 + quantity: + type: integer + format: int32 + shipDate: + type: string + format: date-time + status: + type: string + description: Order Status + enum: + - placed + - approved + - delivered + complete: + type: boolean + default: false + xml: + name: Order + Category: + title: Pet category + description: A category for a pet + type: object + properties: + id: + type: integer + format: int64 + name: + type: string + pattern: '^[a-zA-Z0-9]+[a-zA-Z0-9\.\-_]*[a-zA-Z0-9]+$' + xml: + name: Category + User: + title: a User + description: A User who is purchasing from the pet store + type: object + properties: + id: + type: integer + format: int64 + username: + type: string + firstName: + type: string + lastName: + type: string + email: + type: string + password: + type: string + phone: + type: string + userStatus: + type: integer + format: int32 + description: User Status + xml: + name: User + Tag: + title: Pet Tag + description: A tag for a pet + type: object + properties: + id: + type: integer + format: int64 + name: + type: string + xml: + name: Tag + Pet: + title: a Pet + description: A pet for sale in the pet store + type: object + required: + - name + - photoUrls + properties: + id: + type: integer + format: int64 + category: + $ref: '#/components/schemas/Category' + name: + type: string + example: doggie + photoUrls: + type: array + xml: + name: photoUrl + wrapped: true + items: + type: string + tags: + type: array + xml: + name: tag + wrapped: true + items: + $ref: '#/components/schemas/Tag' + status: + type: string + description: pet status in the store + deprecated: true + enum: + - available + - pending + - sold + xml: + name: Pet + ApiResponse: + title: An uploaded response + description: Describes the result of uploading an image resource + type: object + properties: + code: + type: integer + format: int32 + type: + type: string + message: + type: string