Attempt to generate an OpenAPI based redfish client
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)
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.
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
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!
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.
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)
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
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?
Closing; would like to test with newer schema bundle releases and updated OpenAPI tooling