Open csmorley opened 4 years ago
Having same issue when providing a specification rather than providing an URL
I think the "definitions" do not only contain schemas but also responses, but at deserialization we assume "definitions" are schemas and serialize them that way => then you get a cast exception. I think this is solved in OpenAPI 3.0 as there you have not only definitions but also other collections where the type is clear...
This is probably very hard to solve and ideally you'd just have an oai 3.0 spec
I also get this exception for https://storage.googleapis.com/libpod-master-releases/swagger-latest-master.yaml.
but at deserialization we assume "definitions" are schemas and serialize them that way
How can I see in the yaml this is the issue?
@tmds are there $refs from an operation response to the "definitions"?
For my understanding: is this something OpenAPI 2.0 doesn't allow? Or that NSwag doesn't support?
are there $refs from an operation response to the "definitions"?
Like the snippit below? Should the $ref:
only refer to #/responses
and not #/definitions
?
/libpod/manifests/{name:.*}:
delete:
description: Remove an image from a manifest list
operationId: RemoveManifest
parameters:
- description: the image associated with the manifest
in: path
name: name:.*
required: true
type: string
- description: image digest to be removed
in: query
name: digest
type: string
produces:
- application/json
responses:
"200":
$ref: '#/definitions/IDResponse'
I don't know much about about swagger. I'm adding @jwhonce who maintains the https://storage.googleapis.com/libpod-master-releases/swagger-latest-master.yaml file.
@RicoSuter @jwhonce I hope you can figure out what NSwag doesn't like about the podman swagger file.
Jhon, maybe you have an idea based on the comments that are in the issue. In case you want to reproduce the issue on Fedora and try something, you can do this:
$ sudo dnf install dotnet-sdk-3.1
$ dotnet tool install --global NSwag.ConsoleCore --version 13.9.4
$ wget https://storage.googleapis.com/libpod-master-releases/swagger-latest-master.yaml
$ nswag openapi2csclient /Input:swagger-latest-master.yaml /Namespace:Podman /Output:PodmanClient.cs /ClassName:PodmanClient
This is the output from running the last command:
NSwag command line tool for .NET Core Net50, toolchain v13.9.4.0 (NJsonSchema v10.3.1.0 (Newtonsoft.Json v12.0.0.0))
Visit http://NSwag.org for more information.
NSwag bin directory: /home/tmds/.dotnet/tools/.store/nswag.consolecore/13.9.4/nswag.consolecore/13.9.4/tools/net5.0/any
System.InvalidCastException: Unable to cast object of type 'NJsonSchema.JsonSchema' to type 'NSwag.OpenApiResponse'.
at NJsonSchema.References.JsonReferenceBase`1.NJsonSchema.References.IJsonReferenceBase.set_Reference(IJsonReference value)
at NJsonSchema.JsonSchemaReferenceUtilities.JsonReferenceUpdater.VisitJsonReferenceAsync(IJsonReference reference, String path, String typeNameHint, CancellationToken cancellationToken)
at NJsonSchema.Visitors.AsyncJsonReferenceVisitorBase.VisitAsync(Object obj, String path, String typeNameHint, ISet`1 checkedObjects, Action`1 replacer, CancellationToken cancellationToken)
at NJsonSchema.Visitors.AsyncJsonReferenceVisitorBase.VisitAsync(Object obj, String path, String typeNameHint, ISet`1 checkedObjects, Action`1 replacer, CancellationToken cancellationToken)
at NJsonSchema.Visitors.AsyncJsonReferenceVisitorBase.VisitAsync(Object obj, String path, String typeNameHint, ISet`1 checkedObjects, Action`1 replacer, CancellationToken cancellationToken)
at NJsonSchema.Visitors.AsyncJsonReferenceVisitorBase.VisitAsync(Object obj, String path, String typeNameHint, ISet`1 checkedObjects, Action`1 replacer, CancellationToken cancellationToken)
at NJsonSchema.Visitors.AsyncJsonReferenceVisitorBase.VisitAsync(Object obj, String path, String typeNameHint, ISet`1 checkedObjects, Action`1 replacer, CancellationToken cancellationToken)
at NJsonSchema.Visitors.AsyncJsonReferenceVisitorBase.VisitAsync(Object obj, String path, String typeNameHint, ISet`1 checkedObjects, Action`1 replacer, CancellationToken cancellationToken)
at NJsonSchema.Visitors.AsyncJsonReferenceVisitorBase.VisitAsync(Object obj, CancellationToken cancellationToken)
at NJsonSchema.JsonSchemaReferenceUtilities.JsonReferenceUpdater.VisitAsync(Object obj, CancellationToken cancellationToken)
at NJsonSchema.JsonSchemaReferenceUtilities.UpdateSchemaReferencesAsync(Object rootObject, JsonReferenceResolver referenceResolver, IContractResolver contractResolver, CancellationToken cancellationToken)
at NJsonSchema.Infrastructure.JsonSchemaSerialization.FromJsonAsync[T](String json, SchemaType schemaType, String documentPath, Func`2 referenceResolverFactory, IContractResolver contractResolver, CancellationToken cancellationToken)
at NSwag.OpenApiDocument.FromJsonAsync(String data, String documentPath, SchemaType expectedSchemaType, Func`2 referenceResolverFactory, CancellationToken cancellationToken) in C:\projects\nswag\src\NSwag.Core\OpenApiDocument.cs:line 197
at NSwag.OpenApiYamlDocument.FromYamlAsync(String data, String documentPath, SchemaType expectedSchemaType, Func`2 referenceResolverFactory, CancellationToken cancellationToken) in C:\projects\nswag\src\NSwag.Core.Yaml\OpenApiYamlDocument.cs:line 76
at NSwag.OpenApiYamlDocument.FromFileAsync(String filePath, CancellationToken cancellationToken) in C:\projects\nswag\src\NSwag.Core.Yaml\OpenApiYamlDocument.cs:line 98
at NSwag.Commands.OutputCommandBase.ReadSwaggerDocumentAsync(String input) in C:\projects\nswag\src\NSwag.Commands\Commands\OutputCommandBase.cs:line 49
at NSwag.Commands.InputOutputCommandBase.GetInputSwaggerDocument() in C:\projects\nswag\src\NSwag.Commands\Commands\InputOutputCommandBase.cs:line 46
at NSwag.Commands.CodeGeneration.SwaggerToCSharpClientCommand.<RunAsync>b__92_0() in C:\projects\nswag\src\NSwag.Commands\Commands\CodeGeneration\OpenApiToCSharpClientCommand.cs:line 253
at NSwag.Commands.CodeGeneration.SwaggerToCSharpClientCommand.RunAsync() in C:\projects\nswag\src\NSwag.Commands\Commands\CodeGeneration\OpenApiToCSharpClientCommand.cs:line 251
at NSwag.Commands.CodeGeneration.SwaggerToCSharpClientCommand.RunAsync(CommandLineProcessor processor, IConsoleHost host) in C:\projects\nswag\src\NSwag.Commands\Commands\CodeGeneration\OpenApiToCSharpClientCommand.cs:line 240
at NConsole.CommandLineProcessor.ProcessSingleAsync(String[] args, Object input)
at NConsole.CommandLineProcessor.ProcessAsync(String[] args, Object input)
at NConsole.CommandLineProcessor.Process(String[] args, Object input)
at NSwag.Commands.NSwagCommandProcessor.Process(String[] args) in C:\projects\nswag\src\NSwag.Commands\NSwagCommandProcessor.cs:line 55
I removed paths, and added them back until I hit the exception. It happens when adding this path:
/libpod/manifests/{name:.*}:
delete:
description: Remove an image from a manifest list
operationId: RemoveManifest
parameters:
- description: the image associated with the manifest
in: path
name: name:.*
required: true
type: string
- description: image digest to be removed
in: query
name: digest
type: string
produces:
- application/json
responses:
"200":
$ref: '#/definitions/IDResponse'
"400":
$ref: '#/responses/BadParamError'
"404":
$ref: '#/responses/NoSuchManifest'
"500":
$ref: '#/responses/InternalError'
summary: Remove
tags:
- manifests
@RicoSuter do you see what is causing the exception?
IDResponse
seems to be the common thing on the paths that cause the exception:
definitions:
...
IDResponse:
properties:
Id:
description: ID
type: string
x-go-name: ID
type: object
x-go-package: github.com/containers/podman/pkg/api/handlers
There is also a similar IdResponse
(different casing) that also has the issue.
Is that possible for you to clone the project and debug inside it to pinpoint the issue? run the Core command line project and see where it throws.
If you could make the PR, that would be even better
I've trimmed down the reproducer to the following. IdResponse
seems to be the offending thing.
basePath: /
consumes:
- application/json
- application/x-tar
definitions:
IdResponse:
description: IDResponse Response to an API call that returns just an Id
properties:
Id:
description: The id of the newly created object.
type: string
x-go-name: ID
required:
- Id
type: object
x-go-name: IDResponse
x-go-package: github.com/containers/podman/vendor/github.com/docker/docker/api/types
host: podman.io
paths:
/libpod/pods/create:
post:
operationId: CreatePod
parameters:
- description: attributes for creating a pod
in: body
name: create
schema:
$ref: '#/definitions/PodSpecGenerator'
type: object
produces:
- application/json
responses:
"200":
$ref: '#/definitions/IdResponse'
"400":
$ref: '#/responses/BadParamError'
"500":
$ref: '#/responses/InternalError'
summary: Create a pod
tags:
- pods
produces:
- application/json
- text/plain
- text/html
responses:
BadParamError:
description: Bad parameter in request
schema:
properties:
cause:
description: API root cause formatted for automated parsing
example: API root cause
type: string
x-go-name: Because
message:
description: human error message, formatted for a human to read
example: human error message
type: string
x-go-name: Message
response:
description: http response code
format: int64
type: integer
x-go-name: ResponseCode
type: object
InternalError:
description: Internal server error
schema:
properties:
cause:
description: API root cause formatted for automated parsing
example: API root cause
type: string
x-go-name: Because
message:
description: human error message, formatted for a human to read
example: human error message
type: string
x-go-name: Message
response:
description: http response code
format: int64
type: integer
x-go-name: ResponseCode
type: object
schemes:
- http
- https
swagger: "2.0"
I had a look at the swagger file for docker, which works with NSwag. Here is the difference:
responses:
201:
description: "no error"
schema:
$ref: "#/definitions/IdResponse"
note the schema
that shows up.
I've added the schema
s in the yaml file and now NSwag
is happy.
My changes look like:
@@ -10300,7 +10300,8 @@ paths:
- application/json
responses:
"200":
- $ref: '#/definitions/IDResponse'
+ schema:
+ $ref: '#/definitions/IDResponse'
"400":
$ref: '#/responses/BadParamError'
"404":
Would it be possible to report the line that caused this exception?
Hi all, I am using NSwagStudio with https://polygon.io/docs/swagger.json and I get the below error:
System.InvalidCastException: Unable to cast object of type 'NJsonSchema.JsonSchema' to type 'NSwag.OpenApiResponse'.
This is generated from swagger endpoint, so not sure what the issue is?
Runtime: NetCore31 at NJsonSchema.References.JsonReferenceBase
1.NJsonSchema.References.IJsonReferenceBase.set_Reference(IJsonReference value) at NJsonSchema.JsonSchemaReferenceUtilities.JsonReferenceUpdater.VisitJsonReferenceAsync(IJsonReference reference, String path, String typeNameHint) at NJsonSchema.Visitors.AsyncJsonReferenceVisitorBase.VisitAsync(Object obj, String path, String typeNameHint, ISet
1 checkedObjects, Action1 replacer) at NJsonSchema.Visitors.AsyncJsonReferenceVisitorBase.VisitAsync(Object obj, String path, String typeNameHint, ISet
1 checkedObjects, Action1 replacer) at NJsonSchema.Visitors.AsyncJsonReferenceVisitorBase.VisitAsync(Object obj, String path, String typeNameHint, ISet
1 checkedObjects, Action1 replacer) at NJsonSchema.Visitors.AsyncJsonReferenceVisitorBase.VisitAsync(Object obj, String path, String typeNameHint, ISet
1 checkedObjects, Action1 replacer) at NJsonSchema.Visitors.AsyncJsonReferenceVisitorBase.VisitAsync(Object obj, String path, String typeNameHint, ISet
1 checkedObjects, Action1 replacer) at NJsonSchema.Visitors.AsyncJsonReferenceVisitorBase.VisitAsync(Object obj, String path, String typeNameHint, ISet
1 checkedObjects, Action1 replacer) at NJsonSchema.Visitors.AsyncJsonReferenceVisitorBase.VisitAsync(Object obj) at NJsonSchema.JsonSchemaReferenceUtilities.JsonReferenceUpdater.VisitAsync(Object obj) at NJsonSchema.JsonSchemaReferenceUtilities.UpdateSchemaReferencesAsync(Object rootObject, JsonReferenceResolver referenceResolver, IContractResolver contractResolver) at NJsonSchema.Infrastructure.JsonSchemaSerialization.FromJsonAsync[T](String json, SchemaType schemaType, String documentPath, Func
2 referenceResolverFactory, IContractResolver contractResolver) at NSwag.OpenApiDocument.FromJsonAsync(String data, String documentPath, SchemaType expectedSchemaType, Func`2 referenceResolverFactory) in C:\projects\nswag\src\NSwag.Core\OpenApiDocument.cs:line 190 at NSwag.Commands.OutputCommandBase.ReadSwaggerDocumentAsync(String input) in C:\projects\nswag\src\NSwag.Commands\Commands\OutputCommandBase.cs:line 65 at NSwag.Commands.Generation.FromDocumentCommand.RunAsync() in C:\projects\nswag\src\NSwag.Commands\Commands\Generation\FromDocumentCommand.cs:line 62 at NSwag.Commands.Generation.FromDocumentCommand.RunAsync(CommandLineProcessor processor, IConsoleHost host) in C:\projects\nswag\src\NSwag.Commands\Commands\Generation\FromDocumentCommand.cs:line 53 at NSwag.Commands.NSwagDocumentBase.GenerateSwaggerDocumentAsync() in C:\projects\nswag\src\NSwag.Commands\NSwagDocumentBase.cs:line 280 at NSwag.Commands.NSwagDocument.ExecuteAsync() in C:\projects\nswag\src\NSwag.Commands\NSwagDocument.cs:line 81 at NSwag.Commands.Document.ExecuteDocumentCommand.ExecuteDocumentAsync(IConsoleHost host, String filePath) in C:\projects\nswag\src\NSwag.Commands\Commands\Document\ExecuteDocumentCommand.cs:line 86 at NSwag.Commands.Document.ExecuteDocumentCommand.RunAsync(CommandLineProcessor processor, IConsoleHost host) in C:\projects\nswag\src\NSwag.Commands\Commands\Document\ExecuteDocumentCommand.cs:line 32 at NConsole.CommandLineProcessor.ProcessSingleAsync(String[] args, Object input) at NConsole.CommandLineProcessor.ProcessAsync(String[] args, Object input) at NConsole.CommandLineProcessor.Process(String[] args, Object input) at NSwag.Commands.NSwagCommandProcessor.Process(String[] args) in C:\projects\nswag\src\NSwag.Commands\NSwagCommandProcessor.cs:line 56