Ошибки синтаксического анализа с openapi-генератором (недопустимый тип для типа, установите его в строку)

У меня есть следующая схема файла openapi

{
    "openapi": "3.0.3",
    "info": {
        "title": "Hyperledger Cactus Plugin - Connector Quorum",
        "description": "Can perform basic tasks on a Quorum ledger",
        "version": "0.0.1"
    },
    "servers": [
        {
            "url": "https://www.cactus.stream/{basePath}",
            "description": "Public test instance",
            "variables": {
                "basePath": {
                    "default": ""
                }
            }
        },
        {
            "url": "http://localhost:4000/{basePath}",
            "description": "Local test instance",
            "variables": {
                "basePath": {
                    "default": ""
                }
            }
        }
    ],
    "components": {
        "schemas": {
            "Web3SigningCredential": {
                "type": "object",
                "required": [
                    "type"
                ],
                "discriminator": {
                    "propertyName": "type"
                },
                "oneOf": [
                    {
                        "$ref": "#/components/schemas/Web3SigningCredentialGethKeychainPassword"
                    },
                    {
                        "$ref": "#/components/schemas/Web3SigningCredentialCactusKeychainRef"
                    },
                    {
                        "$ref": "#/components/schemas/Web3SigningCredentialPrivateKeyHex"
                    },
                    {
                        "$ref": "#/components/schemas/Web3SigningCredentialNone"
                    }
                ],
                "properties": {
                    "type": {
                        "$ref": "#/components/schemas/Web3SigningCredentialType"
                    }
                }
            },
            "Web3SigningCredentialGethKeychainPassword": {
                "type": "object",
                "required": [
                    "type",
                    "ethAccount",
                    "secret"
                ],
                "properties": {
                    "type": {
                        "$ref": "#/components/schemas/Web3SigningCredentialType"
                    },
                    "ethAccount": {
                        "type": "string",
                        "description": "The ethereum account (public key) that the credential  belongs to. Basically the username in the traditional terminology of authentication.",
                        "minLength": 64,
                        "maxLength": 64,
                        "nullable": false
                    },
                    "secret": {
                        "type": "string",
                        "description": "A geth keychain unlock password.",
                        "minLength": 0,
                        "maxLength": 65535
                    }
                }
            },
            "Web3SigningCredentialCactusKeychainRef": {
                "type": "object",
                "required": [
                    "type",
                    "ethAccount",
                    "keychainId",
                    "keychainEntryKey"
                ],
                "properties": {
                    "type": {
                        "$ref": "#/components/schemas/Web3SigningCredentialType"
                    },
                    "ethAccount": {
                        "type": "string",
                        "description": "The ethereum account (public key) that the credential  belongs to. Basically the username in the traditional  terminology of authentication.",
                        "minLength": 64,
                        "maxLength": 64,
                        "nullable": false
                    },
                    "keychainEntryKey": {
                        "type": "string",
                        "description": "The key to use when looking up the the keychain entry holding the secret pointed to by the  keychainEntryKey parameter.",
                        "minLength": 0,
                        "maxLength": 1024
                    },
                    "keychainId": {
                        "type": "string",
                        "description": "The keychain ID to use when looking up the the keychain plugin instance that will be used to retrieve the secret pointed to by the keychainEntryKey parameter.",
                        "minLength": 0,
                        "maxLength": 1024
                    }
                }
            },
            "Web3SigningCredentialPrivateKeyHex": {
                "type": "object",
                "required": [
                    "type",
                    "ethAccount",
                    "secret"
                ],
                "properties": {
                    "type": {
                        "$ref": "#/components/schemas/Web3SigningCredentialType"
                    },
                    "ethAccount": {
                        "type": "string",
                        "description": "The ethereum account (public key) that the credential belongs to. Basically the username in the traditional terminology of authentication.",
                        "minLength": 64,
                        "maxLength": 64,
                        "nullable": false
                    },
                    "secret": {
                        "type": "string",
                        "description": "The HEX encoded private key of an eth account.",
                        "minLength": 0,
                        "maxLength": 65535
                    }
                }
            },
            "Web3SigningCredentialNone": {
                "type": "object",
                "required": [
                    "type"
                ],
                "description": "Using this denotes that there is no signing required because the transaction is pre-signed.",
                "properties": {
                    "type": {
                        "$ref": "#/components/schemas/Web3SigningCredentialType"
                    }
                }
            },
            "Web3SigningCredentialType": {
                "type": "string",
                "enum": [
                    "CACTUS_KEYCHAIN_REF",
                    "GETH_KEYCHAIN_PASSWORD",
                    "PRIVATE_KEY_HEX",
                    "NONE"
                ]
            },
            "EthContractInvocationType": {
                "type": "string",
                "enum": [
                    "SEND",
                    "CALL"
                ]
            },
            "SolidityContractJsonArtifact": {
                "type": "object",
                "required": [
                    "contractName"
                ],
                "properties": {
                    "contractName": {
                        "type": "string",
                        "nullable": false
                    },
                    "metadata": {
                        "type": "string",
                        "nullable": false
                    },
                    "bytecode": {
                        "type": "string",
                        "nullable": false
                    },
                    "deployedBytecode": {
                        "type": "string",
                        "nullable": false
                    },
                    "sourceMap": {
                        "type": "string",
                        "nullable": false
                    },
                    "deployedSourceMap": {
                        "type": "string",
                        "nullable": false
                    },
                    "sourcePath": {
                        "type": "string"
                    },
                    "compiler": {
                        "type": "object",
                        "additionalProperties": true,
                        "properties": {
                            "name": {
                                "type": "string"
                            },
                            "version": {
                                "type": "string"
                            }
                        }
                    },
                    "functionHashes": {
                        "type": "object",
                        "additionalProperties": true
                    },
                    "gasEstimates": {
                        "properties": {
                            "creation": {
                                "type": "object",
                                "properties": {
                                    "codeDepositCost": {
                                        "type": "string"
                                    },
                                    "executionCost": {
                                        "type": "string"
                                    },
                                    "totalCost": {
                                        "type": "string"
                                    }
                                }
                            },
                            "external": {
                                "type": "object",
                                "additionalProperties": true
                            }
                        }
                    }
                }
            },
            "QuorumTransactionConfig": {
                "type": "object",
                "required": [],
                "additionalProperties": true,
                "properties": {
                    "rawTransaction": {
                        "type": "string",
                        "nullable": false
                    },
                    "from": {
                        "oneOf": [
                            {
                                "type": "string"
                            },
                            {
                                "type": "number"
                            }
                        ]
                    },
                    "to": {
                        "oneOf": [
                            {
                                "type": "string"
                            }
                        ]
                    },
                    "value": {
                        "oneOf": [
                            {
                                "type": "string"
                            },
                            {
                                "type": "number"
                            }
                        ]
                    },
                    "gas": {
                        "oneOf": [
                            {
                                "type": "string"
                            },
                            {
                                "type": "number"
                            }
                        ]
                    },
                    "gasPrice": {
                        "oneOf": [
                            {
                                "type": "string"
                            },
                            {
                                "type": "number"
                            }
                        ]
                    },
                    "data": {
                        "oneOf": [
                            {
                                "type": "string"
                            }
                        ]
                    }
                }
            },
            "Web3TransactionReceipt": {
                "type": "object",
                "required": [
                    "blockHash",
                    "blockNumber",
                    "transactionHash",
                    "transactionIndex",
                    "status",
                    "from",
                    "to",
                    "gasUsed"
                ],
                "additionalProperties": true,
                "properties": {
                    "status": {
                        "type": "boolean",
                        "nullable": false
                    },
                    "transactionHash": {
                        "type": "string",
                        "minLength": 64,
                        "maxLength": 64,
                        "pattern": "/^0x([A-Fa-f0-9]{64})$/"
                    },
                    "transactionIndex": {
                        "type": "number",
                        "nullable": false
                    },
                    "blockHash": {
                        "type": "string",
                        "minLength": 64,
                        "maxLength": 64,
                        "pattern": "/^0x([A-Fa-f0-9]{64})$/"
                    },
                    "blockNumber": {
                        "type": "number",
                        "nullable": false
                    },
                    "gasUsed": {
                        "type": "number",
                        "nullable": false
                    },
                    "contractAddress": {
                        "type": "string",
                        "nullable": true
                    },
                    "from": {
                        "type": "string",
                        "nullable": false
                    },
                    "to": {
                        "type": "string",
                        "nullable": false
                    }
                }
            },
            "RunTransactionRequest": {
                "type": "object",
                "required": [
                    "web3SigningCredential",
                    "transactionConfig"
                ],
                "properties": {
                    "web3SigningCredential": {
                        "$ref": "#/components/schemas/Web3SigningCredential",
                        "nullable": false
                    },
                    "transactionConfig": {
                        "$ref": "#/components/schemas/QuorumTransactionConfig",
                        "nullable": false
                    },
                    "timeoutMs": {
                        "type": "number",
                        "description": "The amount of milliseconds to wait for a transaction receipt with thehash of the transaction(which indicates successful execution) beforegiving up and crashing.",
                        "minimum": 0,
                        "default": 60000,
                        "nullable": false
                    }
                }
            },
            "RunTransactionResponse": {
                "type": "object",
                "required": [
                    "transactionReceipt"
                ],
                "properties": {
                    "transactionReceipt": {
                        "$ref": "#/components/schemas/Web3TransactionReceipt"
                    }
                }
            },
            "DeployContractSolidityBytecodeV1Request": {
                "type": "object",
                "required": [
                    "bytecode",
                    "web3SigningCredential"
                ],
                "properties": {
                    "web3SigningCredential": {
                        "$ref": "#/components/schemas/Web3SigningCredential",
                        "nullable": false
                    },
                    "bytecode": {
                        "type": "string",
                        "nullable": false,
                        "minLength": 1,
                        "maxLength": 24576,
                        "description": "See https://ethereum.stackexchange.com/a/47556 regarding the maximum length of the bytecode"
                    },
                    "gas": {
                        "type": "number",
                        "nullable": false
                    },
                    "gasPrice": {
                        "type": "string",
                        "nullable": false
                    },
                    "timeoutMs": {
                        "type": "number",
                        "description": "The amount of milliseconds to wait for a transaction receipt with theaddress of the contract(which indicates successful deployment) beforegiving up and crashing.",
                        "minimum": 0,
                        "default": 60000,
                        "nullable": false
                    }
                }
            },
            "DeployContractSolidityBytecodeV1Response": {
                "type": "object",
                "required": [
                    "transactionReceipt"
                ],
                "properties": {
                    "transactionReceipt": {
                        "$ref": "#/components/schemas/Web3TransactionReceipt"
                    }
                }
            },
            "InvokeContractV1Request": {
                "type": "object",
                "required": [
                    "contractAbi",
                    "web3SigningCredential",
                    "contractAddress",
                    "invocationType",
                    "methodName",
                    "params"
                ],
                "properties": {
                    "web3SigningCredential": {
                        "$ref": "#/components/schemas/Web3SigningCredential",
                        "nullable": false
                    },
                    "contractAbi": {
                        "description": "The application binary interface of the solidity contract",
                        "type": "array",
                        "items": {},
                        "nullable": false
                    },
                    "contractAddress": {
                        "type": "string",
                        "nullable": false
                    },
                    "invocationType": {
                        "$ref": "#/components/schemas/EthContractInvocationType",
                        "nullable": false,
                        "description": "Indicates wether it is a CALL or a SEND type of  invocation where only SEND ends up creating an actual transaction on the ledger."
                    },
                    "methodName": {
                        "description": "The name of the contract method to invoke.",
                        "type": "string",
                        "nullable": false,
                        "minLength": 1,
                        "maxLength": 2048
                    },
                    "params": {
                        "description": "The list of arguments to pass in to the contract method being invoked.",
                        "type": "array",
                        "default": [],
                        "items": {}
                    },
                    "gas": {
                        "oneOf": [
                            {
                                "type": "string"
                            },
                            {
                                "type": "number"
                            }
                        ]
                    },
                    "gasPrice": {
                        "oneOf": [
                            {
                                "type": "string"
                            },
                            {
                                "type": "number"
                            }
                        ]
                    },
                    "timeoutMs": {
                        "type": "number",
                        "description": "The amount of milliseconds to wait for a transaction receipt beforegiving up and crashing. Only has any effect if the invocation type is SEND",
                        "minimum": 0,
                        "default": 60000,
                        "nullable": false
                    }
                }
            },
            "InvokeContractV1Response": {
                "type": "object",
                "properties": {
                    "transactionReceipt": {
                        "$ref": "#/components/schemas/Web3TransactionReceipt"
                    },
                    "callOutput": {}
                }
            }
        }
    },
    "paths": {
        "/api/v1/plugins/@hyperledger/cactus-plugin-ledger-connector-quorum/deploy-contract-solidity-bytecode": {
            "post": {
                "operationId": "apiV1QuorumDeployContractSolidityBytecode",
                "summary": "Deploys the bytecode of a Solidity contract.",
                "parameters": [],
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/DeployContractSolidityBytecodeV1Request"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/DeployContractSolidityBytecodeV1Response"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/api/v1/plugins/@hyperledger/cactus-plugin-ledger-connector-quorum/run-transaction": {
            "post": {
                "operationId": "apiV1QuorumRunTransaction",
                "summary": "Executes a transaction on a quorum ledger",
                "parameters": [],
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/RunTransactionRequest"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/RunTransactionResponse"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/api/v1/plugins/@hyperledger/cactus-plugin-ledger-connector-quorum/invoke-contract": {
            "post": {
                "operationId": "apiV1QuorumInvokeContract",
                "summary": "Invokeds a contract on a quorum ledger",
                "parameters": [],
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/InvokeContractV1Request"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/InvokeContractV1Response"
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

Короче говоря, схема (в которой заключается проблема) похожа на
Web3SigningCredential - ›любой из {Web3SigningCredentialPrivateKeyHex, Web3SigningCredentialGethKeychainPassword , Web3SigningCredentialNone, Web3SigningCredentialCactusKeychainRef} - ›Web3SigningCredentialType

Когда я пытаюсь разобрать его, используя

openapi-generator generate --input-spec file_mentioned_above -g go -o some_path

Я получаю сообщение об ошибке

Exception in thread "main" java.lang.RuntimeException: Could not process model 'Web3SigningCredential'.Please make sure that your schema is correct!
        at org.openapitools.codegen.DefaultGenerator.generateModels(DefaultGenerator.java:477)
        at org.openapitools.codegen.DefaultGenerator.generate(DefaultGenerator.java:852)
        at org.openapitools.codegen.cmd.Generate.execute(Generate.java:432)
        at org.openapitools.codegen.cmd.OpenApiGeneratorCommand.run(OpenApiGeneratorCommand.java:32)
        at org.openapitools.codegen.OpenAPIGenerator.main(OpenAPIGenerator.java:66)
Caused by: java.lang.RuntimeException: 'Web3SigningCredential' defines discriminator 'type', but the referenced schema 'Web3SigningCredentialGethKeychainPassword' is incorrect. invalid type for type, set it to string
        at org.openapitools.codegen.DefaultCodegen.getOneOfAnyOfDescendants(DefaultCodegen.java:2792)
        at org.openapitools.codegen.DefaultCodegen.createDiscriminator(DefaultCodegen.java:2897)
        at org.openapitools.codegen.DefaultCodegen.fromModel(DefaultCodegen.java:2249)
        at org.openapitools.codegen.DefaultGenerator.processModels(DefaultGenerator.java:1162)
        at org.openapitools.codegen.DefaultGenerator.generateModels(DefaultGenerator.java:472)

Но то же самое работает, когда я использую язык typescript-axios в вышеупомянутой команде как

openapi-generator generate --input-spec file_mentioned_above -g typescript-axios -o some_path

Я что-то делаю не так с вышеупомянутым файлом спецификации или это как-то связано с Go для openapi-generator?


person Jagpreet Singh Sasan    schedule 08.01.2021    source источник


Ответы (1)


Попробуйте реорганизовать свои схемы, чтобы использовать allOf наследование вместо oneOf. Также не забудьте указать дискриминатор mapping в базовой схеме. Без mapping определение API предполагает, что дочерние схемы имеют то же имя, что и значения свойств дискриминатора, что не относится к вашему примеру.

Вот версия YAML, вы можете использовать https://www.json2yaml.com/, чтобы преобразовать ее в JSON.

components:
  schemas:
    Web3SigningCredential:
      type: object
      required:
        - type
      discriminator:
        propertyName: type
        mapping:
          CACTUS_KEYCHAIN_REF: Web3SigningCredentialCactusKeychainRef
          GETH_KEYCHAIN_PASSWORD: Web3SigningCredentialGethKeychainPassword
          PRIVATE_KEY_HEX: Web3SigningCredentialPrivateKeyHex
          NONE: Web3SigningCredentialNone
      properties:
        type:
          $ref: '#/components/schemas/Web3SigningCredentialType'

    Web3SigningCredentialGethKeychainPassword:
      allOf:
        - $ref: '#/components/schemas/Web3SigningCredential'
        - type: object
          required:
            - ethAccount
            - secret
          properties:
            ethAccount:
              type: string
              description: The ethereum account (public key) that the credential  belongs to. Basically the username in the traditional terminology of authentication.
              minLength: 64
              maxLength: 64
              nullable: false
            secret:
              type: string
              description: A geth keychain unlock password.
              minLength: 0
              maxLength: 65535

Обновите схемы Web3SigningCredentialCactusKeychainRef, Web3SigningCredentialPrivateKeyHex и Web3SigningCredentialNone соответственно.

person Helen    schedule 12.01.2021