OpenAPITools / openapi-generator

OpenAPI Generator allows generation of API client libraries (SDK generation), server stubs, documentation and configuration automatically given an OpenAPI Spec (v2, v3)
https://openapi-generator.tech
Apache License 2.0
21.28k stars 6.44k forks source link

[BUG] [Java] Cross-path references are not properly considered for Parameters #19306

Open en-milie opened 1 month ago

en-milie commented 1 month ago
Description

When parsing the Parameters section from an operation, cross-path reference parameters are ignored. This is not consistent with other elements which are properly included in the final OpenAPI object.

openapi-generator version

Version 7.7.0

OpenAPI declaration file content or url
"/attribute/{namespace}":
    delete:
      description: |
        Delete an attribute namespace and all attributes below.

        This operation is the same as the one defined with [DELETE /attribute/{namespace}/_meta](#/Attributes/delete_attribute__namespace___meta).
      parameters:
        - $ref: "#/paths/~1attribute~1%7Bnamespace%7D/get/parameters/0"

Full spec file is here: https://github.com/APIs-guru/openapi-directory/blob/main/APIs/opensuse.org/obs/2.10.50/openapi.yaml

Generation Details

Use the following code:

        OpenAPIParser openAPIV3Parser = new OpenAPIParser();
        ParseOptions options = new ParseOptions();
        options.setResolve(true);
        options.setFlatten(true);

        OpenAPI openAPI = openAPIV3Parser.readContents(Files.readString(Paths.get("openapi.yaml")), null, options).getOpenAPI();
        PathItem pathItem = openAPI.getPaths().get("/attribute/{namespace}");

You can then check the Parameters list of the DELETE operation is empty instead of having one parameter.

Steps to reproduce

See above

Suggest a fix

The issue seems to be this code from the io.swagger.v3.parser.processors.ParameterProcessor class:

    if (parameter.get$ref().startsWith("#") && parameter.get$ref().indexOf("#/components/parameters") <= -1) {
                    //TODO: Not possible to add warning during resolve doesn't accept result as an input. Hence commented below line.
                    //result.warning(location, "The parameter should use Reference Object to link to parameters that are defined at the OpenAPI Object's components/parameters.");
                    continue;
                }

Which only includes refs that are from the components section. One possible fix is that it should just include parameters that are referencing other paths 'as is' rather than trying to solve it.

0x0-pavel-0x0 commented 1 month ago

could you reduce your yaml-file for reproducing the bug to min size that is needed?

en-milie commented 1 month ago

Yes. This is it:

openapi: "3.0.0"
info:
  version: 1.0.0
  title: Swagger Petstore
  description: A sample API that uses a petstore as an example to demonstrate features in the OpenAPI 3.0 specification
  termsOfService: http://swagger.io/terms/
  contact:
    name: Swagger API Team
    email: apiteam@swagger.io
    url: http://swagger.io
  license:
    name: Apache 2.0
    url: https://www.apache.org/licenses/LICENSE-2.0.html
servers:
  - url: http://petstore.swagger.io/api
paths:
  "/attribute/{namespace}":
    delete:
      description: |
        Delete an attribute namespace and all attributes below.

        This operation is the same as the one defined with [DELETE /attribute/{namespace}/_meta](#/Attributes/delete_attribute__namespace___meta).
      parameters:
        - $ref: "#/paths/~1attribute~1%7Bnamespace%7D/get/parameters/0"
      responses:
        "200":
          content:
            application/xml; charset=utf-8:
              example:
                code: ok
                summary: Ok
              schema:
                $ref: "#/paths/~1architectures/get/responses/401/content/application~1xml;%20charset=utf-8/schema"
          description: |
            OK. The request has succeeded.

            XML Schema used for body validation: [status.xsd](../schema/status.xsd)
        "401":
          $ref: "#/paths/~1architectures/get/responses/401"
      security:
        - basic_authentication: [ ]
      summary: Delete an attribute namespace and all attributes below.
      tags:
        - Attribute Namespaces
    get:
      description: List all attributes under a given attribute namespace.
      parameters:
        - description: The namespace
          example: OBS_TEST
          in: path
          name: namespace
          required: true
          schema:
            type: string
      responses:
        "200":
          content:
            application/xml; charset=utf-8:
              example:
                count: "2"
                entry:
                  - name: AutoCleanup
                  - name: OwnerRootProject
              schema:
                $ref: "#/paths/~1architectures/get/responses/200/content/application~1xml;%20charset=utf-8/schema"
          description: |
            OK. The request has succeeded.

            XML Schema used for body validation: [directory.xsd](../schema/directory.xsd)
        "401":
          $ref: "#/paths/~1architectures/get/responses/401"
        "404":
          content:
            application/xml; charset=utf-8:
              example:
                code: not_found
                summary: Couldn't find AttribNamespace
              schema:
                $ref: "#/paths/~1architectures/get/responses/401/content/application~1xml;%20charset=utf-8/schema"
          description: Not Found.
      security:
        - basic_authentication: [ ]
      summary: List all attributes below a namespace.
      tags:
        - Attribute Namespaces
  /architectures:
    get:
      description: |
        Get a list of all known architectures known to OBS in general. This is not the list of architectures provided by this instance. Check the schedulers element from the `/configuration` route for this.
      responses:
        "200":
          content:
            application/xml; charset=utf-8:
              example:
                count: "4"
                entry:
                  - name: aarch64
                  - name: armv7l
                  - name: s390x
                  - name: x86_64
              schema:
                properties:
                  count:
                    type: integer
                    xml:
                      attribute: true
                  entry:
                    items:
                      properties:
                        name:
                          type: string
                          xml:
                            attribute: true
                      type: object
                    type: array
                type: object
                xml:
                  name: directory
          description: OK. The request has succeeded.
        "401":
          content:
            application/xml; charset=utf-8:
              examples:
                anonymous_user:
                  summary: Anonymous User
                  value:
                    code: anonymous_user
                    summary: Anonymous user is not allowed here - please login
                authentication_required:
                  summary: Authentication Required
                  value:
                    code: authentication_required
                    summary: Unknown user 'Admin' or invalid password
              schema:
                properties:
                  code:
                    type: string
                    xml:
                      attribute: true
                  data:
                    items:
                      type: string
                    type: array
                  details:
                    type: string
                  summary:
                    type: string
                type: object
                xml:
                  name: status
          description: |
            Unauthorized.

            XML Schema used for body validation: [status.xsd](../schema/status.xsd)
      security:
        - basic_authentication: [ ]
      summary: List all known architectures.
      tags:
        - General Information
en-milie commented 1 month ago

As it can be seen in the below image during debug, Paramaters are not solved at all:

Screenshot 2024-08-09 at 14 44 07

while ApiResponse, which uses a similar syntax is properly solved:

Screenshot 2024-08-09 at 14 44 18