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.64k stars 6.53k forks source link

[BUG] Generator tried to load relative ref from a non-existing path. #16443

Open windless0530 opened 1 year ago

windless0530 commented 1 year ago
Description

I have created some yaml files, structured like:

Both common.yml and amp.yml refer to auth.yml, which refers to components.yml. See the following for details.

components.yml (Meta refers to ErrorCode):

ErrorCode:
  type: integer
  format: int64
  description: 0 for NoError, 100 for AuthenticationFailed

Meta:
  title: Meta
  type: object
  properties:
    error_code:
      $ref: ./component.yml#/ErrorCode
    redirect:
      title: Redirect
      type: object
      properties:
        url:
          type: string

auth.yml (oauth2_code2token response refers to Meta in components.yml):

oauth2_code2token:
  get:
    responses:
      200:
        description: OK
        content:
          application/json:
            schema:
              type: object
              title: Code2TokenResponse
              properties:
                meta:
                  $ref: ../data/component.yml#/Meta
                data:

common.yml (code2token refers to oauth2_code2token in auth.yml)

paths:
  /oauth2/code2token:
    $ref: ./operation/auth.yml#/oauth2_code2token

amp.yml (code2token refers to oauth2_code2token in auth.yml)

paths:
  /oauth2/code2token:
    $ref: ../common/operation/auth.yml#/oauth2_code2token

As above the only difference between amp.yml and common.yml is the relative reference path according to their different parent directories.

However, only common.yml can be successfully parsed and generated, while the amp.yml would generate the following error:

java.lang.RuntimeException: Unable to load RELATIVE ref: ../common/common/data/component.yml path: /autra/./api/amp at io.swagger.v3.parser.util.RefUtils.readExternalRef(RefUtils.java:220) at io.swagger.v3.parser.ResolverCache.loadRef(ResolverCache.java:150) at io.swagger.v3.parser.processors.ExternalRefProcessor.processRefToExternalSchema(ExternalRefProcessor.java:88) at io.swagger.v3.parser.processors.SchemaProcessor.processReferenceSchema(SchemaProcessor.java:236) at io.swagger.v3.parser.processors.SchemaProcessor.processPropertySchema(SchemaProcessor.java:138) at io.swagger.v3.parser.processors.SchemaProcessor.processSchemaType(SchemaProcessor.java:77) at io.swagger.v3.parser.processors.SchemaProcessor.processSchema(SchemaProcessor.java:62) at io.swagger.v3.parser.processors.ComponentsProcessor.processSchemas(ComponentsProcessor.java:231) at io.swagger.v3.parser.processors.ComponentsProcessor.processComponents(ComponentsProcessor.java:145) at io.swagger.v3.parser.OpenAPIResolver.resolve(OpenAPIResolver.java:73) at io.swagger.v3.parser.OpenAPIResolver.resolve(OpenAPIResolver.java:59) at io.swagger.v3.parser.OpenAPIV3Parser.resolve(OpenAPIV3Parser.java:238) at io.swagger.v3.parser.OpenAPIV3Parser.readContents(OpenAPIV3Parser.java:181) at io.swagger.v3.parser.OpenAPIV3Parser.readLocation(OpenAPIV3Parser.java:97) at io.swagger.parser.OpenAPIParser.readLocation(OpenAPIParser.java:16) at org.openapitools.codegen.config.CodegenConfigurator.toContext(CodegenConfigurator.java:637) at org.openapitools.codegen.config.CodegenConfigurator.toClientOptInput(CodegenConfigurator.java:695) at org.openapitools.codegen.cmd.Generate.execute(Generate.java:503) at org.openapitools.codegen.cmd.OpenApiGeneratorCommand.run(OpenApiGeneratorCommand.java:32) at org.openapitools.codegen.OpenAPIGenerator.main(OpenAPIGenerator.java:66) Caused by: java.lang.RuntimeException: Could not find ../common/common/data/component.yml on the classpath at io.swagger.v3.parser.util.ClasspathHelper.loadFileFromClasspath(ClasspathHelper.java:33) at io.swagger.v3.parser.util.RefUtils.readExternalRef(RefUtils.java:214) ... 19 common frames omitted [main] WARN o.o.codegen.utils.ModelUtils - Failed to get the schema name: ../common/common/data/component.yml#/ErrorCode [main] WARN o.o.codegen.utils.ModelUtils - Failed to get the schema name: ../common/common/data/component.yml#/ErrorCode Exception in thread "main" org.openapitools.codegen.SpecValidationException: There were issues with the specification. The option can be disabled via validateSpec (Maven/Gradle) or --skip-validate-spec (CLI). | Error count: 1, Warning count: 0 Errors: -Unable to load RELATIVE ref: ../common/common/data/component.yml path: /autra/./api/amp at org.openapitools.codegen.config.CodegenConfigurator.toContext(CodegenConfigurator.java:668) at org.openapitools.codegen.config.CodegenConfigurator.toClientOptInput(CodegenConfigurator.java:695) at org.openapitools.codegen.cmd.Generate.execute(Generate.java:503) at org.openapitools.codegen.cmd.OpenApiGeneratorCommand.run(OpenApiGeneratorCommand.java:32) at org.openapitools.codegen.OpenAPIGenerator.main(OpenAPIGenerator.java:66)

This really confused me, for the string "common/common/data" does not even exist in my workspace.

I haved tried the followings:

  1. Run ag "common/comon/data" . in my workspace, with no output at all.
  2. Find string "common/common/data" in my Visual Studio Code, with no result.
  3. Run docker system prune -a to remove all the cache, and force update the generator, tried to generate again, ending in the same error.
  4. Run the generator image with sh as the substitution for the default entry point, and manually run /usr/local/bin/docker-entrypoint.sh generate in the container, ending in the same error.

Now I have no idea about what happened... Could anyone help me about that?

Thanks.

openapi-generator version

7.0.1-SNAPSHOT (Using the docker image)

windless0530 commented 1 year ago

OK, now the problem is solved by simply modifying the reference of ErrorCode to local $ref: "#/ErrorCode", as following:

ErrorCode:
  type: integer
  format: int64
  description: 0 for NoError, 100 for AuthenticationFailed

Meta:
  title: Meta
  type: object
  properties:
    error_code:
      $ref: "#/ErrorCode"
    redirect:
      title: Redirect
      type: object
      properties:
        url:
          type: string

However, another 2 questions occured.

Firstly, as Meta is refered in 2 ways:

                  $ref: ../../common/data/component.yml#/Meta
                  $ref: ../data/component.yml#/Meta

Changing ErrorCode to local reference will cause 2 'Meta's be generated, Meta and Meta_1, both in the combined openapi.yaml file and the generated codes, eg, meta.go and meta_1.go.

Secondly, another schema Error can only be refered remotely, as following:

Error:
  title: Error
  type: object
  properties:
    code:
      type: integer
      format: int64
    message:
      type: string

StatusBadRequest:
  description: Bad Request
  content:
    application/json:
      schema:
        $ref: ./component.yml#/Error

If I modify the above reference to local $ref: "#/Error", error would occur.

All the above types, Error, ErrorCode, Meta, StatusBadRequest are all defined in the same yaml file. No component schema is declared in the entry yaml file, amp.yml or common.yml.

So could any one tell the difference between Error and ErrorCode that caused the above reference restriction?