Redfish-Tools icon indicating copy to clipboard operation
Redfish-Tools copied to clipboard

Attempt to generate an OpenAPI based redfish client

Open joelrebel opened this issue 7 years ago • 7 comments

If this issue does not belong here, do let me know where to raise it,

I'm basically attempting to generate a Go client for Redfish using the OpenAPI spec, and I've not had any luck so far, these were the steps I followed,

  • The openapi.yaml was taken from https://www.dmtf.org/sites/default/files/standards/documents/DSP8010_2018.3.zip
  • Attempted to use go-swagger, although that throws a whole bunch of errors, see below
  • Attempted to use the latest release of swagger-codegen with OpenAPI 3 support, still no go.

My queries here are,

  • Which OpenAPI version is the current spec based on? since I'm seeing various complaints from the validator.
  • Is the approach below to generate a client based on the the spec right, or am I missing something?

go-swagger

 swagger validate  openapi/openapi.yaml  &> validator.log
-- see gist below for the output.

https://gist.github.com/joelrebel/4a5def94a39a0f504bed854376a80b72

swagger-codegen

sudo ./run-in-docker.sh generate -i  ./openapi/openapi.yaml -l go -o redgopher -DpackageName=redgopher

[INFO] swagger-codegen-project ............................ SUCCESS [  1.731 s]
[INFO] swagger-codegen (core library) ..................... SUCCESS [01:05 min]
[INFO] swagger-codegen (executable) ....................... SUCCESS [  5.168 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  01:13 min
[INFO] Finished at: 2019-02-08T19:52:02Z
[INFO] ------------------------------------------------------------------------
[main] INFO io.swagger.parser.Swagger20Parser - reading from ./openapi/openapi.yaml
[main] ERROR io.swagger.parser.util.DeserializationUtils - Error snake-parsing yaml content
io.swagger.parser.util.DeserializationUtils$SnakeException: Exception safe-checking yaml content  (maxDepth 2000)
        at io.swagger.parser.util.DeserializationUtils$CustomSnakeYamlConstructor.getSingleData(DeserializationUtils.java:300)
        at org.yaml.snakeyaml.Yaml.loadFromReader(Yaml.java:450)
        at org.yaml.snakeyaml.Yaml.load(Yaml.java:369)
        at io.swagger.parser.util.DeserializationUtils.readYamlTree(DeserializationUtils.java:137)
        at io.swagger.parser.Swagger20Parser.deserializeYaml(Swagger20Parser.java:83)
        at io.swagger.parser.Swagger20Parser.convertToSwagger(Swagger20Parser.java:125)
        at io.swagger.parser.Swagger20Parser.read(Swagger20Parser.java:109)
        at io.swagger.parser.SwaggerParser.read(SwaggerParser.java:69)
        at io.swagger.codegen.config.CodegenConfigurator.toClientOptInput(CodegenConfigurator.java:431)
        at io.swagger.codegen.cmd.Generate.run(Generate.java:283)
        at io.swagger.codegen.SwaggerCodegen.main(SwaggerCodegen.java:35)
Caused by: java.lang.IllegalAccessError: tried to access field org.yaml.snakeyaml.constructor.BaseConstructor.composer from class io.swagger.parser.util.DeserializationUtils$CustomSnakeYamlConstructor                                                                      
        at io.swagger.parser.util.DeserializationUtils$CustomSnakeYamlConstructor.getSingleData(DeserializationUtils.java:279)
        ... 10 more
[main] INFO io.swagger.parser.Swagger20Parser - reading from ./openapi/openapi.yaml
[main] ERROR io.swagger.parser.util.DeserializationUtils - Error snake-parsing yaml content
io.swagger.parser.util.DeserializationUtils$SnakeException: Exception safe-checking yaml content  (maxDepth 2000)
        at io.swagger.parser.util.DeserializationUtils$CustomSnakeYamlConstructor.getSingleData(DeserializationUtils.java:300)
        at org.yaml.snakeyaml.Yaml.loadFromReader(Yaml.java:450)
        at org.yaml.snakeyaml.Yaml.load(Yaml.java:369)
        at io.swagger.parser.util.DeserializationUtils.readYamlTree(DeserializationUtils.java:137)
        at io.swagger.parser.Swagger20Parser.deserializeYaml(Swagger20Parser.java:83)
        at io.swagger.parser.Swagger20Parser.convertToSwagger(Swagger20Parser.java:125)
        at io.swagger.parser.Swagger20Parser.read(Swagger20Parser.java:109)
        at io.swagger.parser.SwaggerParser.read(SwaggerParser.java:79)
        at io.swagger.codegen.config.CodegenConfigurator.toClientOptInput(CodegenConfigurator.java:431)
        at io.swagger.codegen.cmd.Generate.run(Generate.java:283)
        at io.swagger.codegen.SwaggerCodegen.main(SwaggerCodegen.java:35)
Caused by: java.lang.IllegalAccessError: tried to access field org.yaml.snakeyaml.constructor.BaseConstructor.composer from class io.swagger.parser.util.DeserializationUtils$CustomSnakeYamlConstructor                                                                      
        at io.swagger.parser.util.DeserializationUtils$CustomSnakeYamlConstructor.getSingleData(DeserializationUtils.java:279)
        ... 10 more
[main] ERROR io.swagger.parser.SwaggerCompatConverter - failed to read resource listing
com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'components': was expecting ('true', 'false' or 'null')
 at [Source: (StringReader); line: 1, column: 11]
        at com.fasterxml.jackson.core.JsonParser._constructError(JsonParser.java:1804)
        at com.fasterxml.jackson.core.base.ParserMinimalBase._reportError(ParserMinimalBase.java:673)
        at com.fasterxml.jackson.core.json.ReaderBasedJsonParser._reportInvalidToken(ReaderBasedJsonParser.java:2835)
        at com.fasterxml.jackson.core.json.ReaderBasedJsonParser._handleOddValue(ReaderBasedJsonParser.java:1889)
        at com.fasterxml.jackson.core.json.ReaderBasedJsonParser.nextToken(ReaderBasedJsonParser.java:747)
        at com.fasterxml.jackson.databind.ObjectMapper._readTreeAndClose(ObjectMapper.java:4030)
        at com.fasterxml.jackson.databind.ObjectMapper.readTree(ObjectMapper.java:2539)
        at io.swagger.parser.SwaggerCompatConverter.readResourceListing(SwaggerCompatConverter.java:210)
        at io.swagger.parser.SwaggerCompatConverter.read(SwaggerCompatConverter.java:123)
        at io.swagger.parser.SwaggerParser.read(SwaggerParser.java:79)
        at io.swagger.codegen.config.CodegenConfigurator.toClientOptInput(CodegenConfigurator.java:431)
        at io.swagger.codegen.cmd.Generate.run(Generate.java:283)
        at io.swagger.codegen.SwaggerCodegen.main(SwaggerCodegen.java:35)
[main] WARN io.swagger.codegen.ignore.CodegenIgnoreProcessor - Output directory does not exist, or is inaccessible. No file (.swagger-codegen-ignore) will be evaluated.                                                                                                      
Exception in thread "main" java.lang.RuntimeException: missing swagger input or config!
        at io.swagger.codegen.DefaultGenerator.generate(DefaultGenerator.java:739)
        at io.swagger.codegen.cmd.Generate.run(Generate.java:285)
        at io.swagger.codegen.SwaggerCodegen.main(SwaggerCodegen.java:35)

joelrebel avatar Feb 08 '19 20:02 joelrebel

The schemas we publish should follow OpenAPI 3.0.1. I've had limited success so far with code generators with OpenAPI 3.0.

At least looking at go-swagger, it appears it's still on Swagger 2.0 (at least as far as I can tell), so that will be a no go.

swagger-codegen I know has been rolling out support for 3.0 over the last few months. I can take a look at it again since the last time I tried it.

mraineri avatar Feb 08 '19 21:02 mraineri

Since what I posted earlier, we had some success with openapi-generator-cli and are now testing the generated client https://github.com/bmc-toolbox/redgopher

There was just one fix to the spec that was required, sed -e 's@definitions/GenerateCSRResponse@components/schemas/GenerateCSRResponse@g' -i openapi.yaml

joelrebel avatar Feb 19 '19 20:02 joelrebel

Please keep us updated on your progress! The 3.0 ecosystem is still very new, so anything we can do on our end to make this process work easier, or at least document the howto's, we're interested!

jautor avatar Feb 27 '19 22:02 jautor

Excellent work @joelrebel !

I have a fix in the tool ready for what you did; it was brought up in issue #169 and will be ready for the next publication of schema.

mraineri avatar Feb 28 '19 13:02 mraineri

What is the actual cause of Exception safe-checking of maxDepth 2000 ? My file generation always falls into this error on longer .yaml file. Tried on swagger-codegen version 2.4.2 and 3.0.5. Interesingly on version 2.3.0 generator does not throw this error.

ERROR io.swagger.parser.util.DeserializationUtils - Error snake-parsing yaml content io.swagger.parser.util.DeserializationUtils$SnakeException: Exception safe-checking yaml content (maxDepth 2000)

Yurdaaaaa avatar Mar 14 '19 13:03 Yurdaaaaa

Sorry to be polluting this project's issue discussion, but since google brought me here for my search on "IllegalAccessError snakeyaml DeserializationUtils", let me drop a quick answer to this question by @Yurdaaaaa and share the results of my research:

What is the actual cause of Exception safe-checking of maxDepth 2000 ? My file generation always falls into this error on longer .yaml file. Tried on swagger-codegen version 2.4.2 and 3.0.5. Interesingly on version 2.3.0 generator does not throw this error.

This has to do with the version <snakeyaml / issues / #320> is fixed (1.17+), and the snakeyaml jar/binary that's bundled in swagger-codegen version 2.4.2!

It seems swagger parser code was written assuming SnakeYAML 1.17+ codebase (where "composer" field is protected, and therefore visible to derived classes), whereas earlier versions had this as private.

So, as far as I can see the root of the problem has to do with swagger-codegen packaging (of version 2.4.2 at least)! I've changed the dependency to version 2.4.4, and do not get the IllegalAccessError callstack anymore.

And tracking a bit more on that path, I've noticed there indeed was an intentional fix on the source of the problem: Issue 9268 - PR 9243

ohuseyinoglu avatar Apr 08 '19 11:04 ohuseyinoglu

An update from recent testing: working with 2019.2 and the latest version of Swagger Codegen, everything seems to work successfully, with one minor exception. When generating Python code, it will throw an exception about the format of the pattern strings; it's currently expecting them to be wrapped with "/" characters per Perl conventions. However, I found a discussion on the OpenAPI group that this isn't correct and will need to be fixed in the tool's handling of pattern (see https://github.com/OAI/OpenAPI-Specification/issues/1985).

@joelrebel have you been trying conversion on your end with 2019.1 or 2019.2 with updated versions of Swagger Codegen?

mraineri avatar Oct 04 '19 12:10 mraineri

Closing; would like to test with newer schema bundle releases and updated OpenAPI tooling

mraineri avatar Jun 14 '24 19:06 mraineri