Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #19439 and generated Java code for oneOf/anyOf models and enums #19443

Closed
wants to merge 9 commits into from

Conversation

beikov
Copy link
Contributor

@beikov beikov commented Aug 24, 2024

PR checklist

  • Read the contribution guidelines.
  • Pull Request title clearly describes the work in the pull request and Pull Request description provides details about how to validate the work. Missing information here may result in delayed response from the community.
  • Run the following to build the project and update samples:
    ./mvnw clean package 
    ./bin/generate-samples.sh ./bin/configs/*.yaml
    ./bin/utils/export_docs_generators.sh
    
    (For Windows users, please run the script in Git BASH)
    Commit all changed files.
    This is important, as CI jobs will verify all generator outputs of your HEAD commit as it would merge with master.
    These must match the expectations made by your contribution.
    You may regenerate an individual generator by passing the relevant config(s) as an argument to the script, for example ./bin/generate-samples.sh bin/configs/java*.
    IMPORTANT: Do NOT purge/delete any folders/files (e.g. tests) when regenerating the samples as manually written tests may be removed.
  • File the PR against the correct branch: master (upcoming 7.6.0 minor release - breaking changes with fallbacks), 8.0.x (breaking changes without fallbacks)
  • If your PR is targeting a particular programming language, @mention the technical committee members, so they are more likely to review the pull request.

@bbdouglas (2017/07) @sreeshas (2017/08) @jfiala (2017/08) @lukoyanov (2017/09) @cbornet (2017/09) @jeff9finger (2018/01) @karismann (2019/03) @Zomzog (2019/04) @lwlee2608 (2019/10) @martin-mfg (2023/08)

@martin-mfg
Copy link
Contributor

Hi @beikov, thanks for the PR!

I see in #19439 there's an explanation and sample case for why the condition schema.get$ref() == null should be added. That's good. However, there are several more changes in this PR besides this condition. Could you please summarize what additional changes you have made, and give an example input for which these additional changes are relevant?

And finally, could you please have a look at the failing check? Thanks!

@beikov
Copy link
Contributor Author

beikov commented Sep 21, 2024

Hi @martin-mfg, sure here is a short description of what the changes are about:

  • Fix oneOf/anyOf support for jersey2 and jersey3 - the code generator templates for jersey2 and jersey 3 are similar, but diverged a lot. The changes you see there are mostly to align the two again with respect to their one-of and any-of model templates as well as fix a compilation error due to a superfluous parenthesis. The alignment fixes a bunch of generics related issues in jersey3 that have already been fixed for jersey2
  • Fix invalid Java Enum generation - Fixes invalid code that is generated when an enumeration is based on e.g. booleans rather than strings

The other two commits are hopefully clear. I will look into the failures now.

@beikov
Copy link
Contributor Author

beikov commented Sep 21, 2024

The test failure is due to a test trying to deserialize {} as an any-of type. Since the empty object maps to 2 of the any-of objects, the test fails saying that Failed deserialization for GmFruit: 2 classes match result, expected 1.
I don't know if the test makes sense, but I added special handling for empty objects to return just an empty any-of/one-of shell without an actual instance.
Prior to my changes, it would just deserialize to the first one that matches i.e. the first type that is handled.

@beikov
Copy link
Contributor Author

beikov commented Sep 21, 2024

Now there is a failure in the OpenAPI3 tests (samples/openapi3/client/petstore/java/jersey2-java8) that expect an exception for an empty object org.openapitools.client.JSONComposedSchemaTest#testOneOfSchemaWithoutDiscriminator. Seems the tests contradict each other :)

I guess that the desired behavior is the exception though since the OpenAPI3 tests are probably newer. I'll revert my defaulting approach and adapt the old test.

@@ -23,7 +23,7 @@
{{#withXml}}
@XmlEnumValue({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}})
{{/withXml}}
{{{name}}}({{{value}}}){{^-last}},
{{{name}}}({{^isUri}}{{^isString}}{{dataType}}.valueOf({{/isString}}{{/isUri}}{{{value}}}{{^isUri}}{{^isString}}){{/isString}}{{/isUri}}){{^-last}},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please add to bin/configs/ an example of a case where this change prevents the generation of invalid code?

Btw, I noticed this doesn't work with e.g. type: string ; format: date. Because the method LocalDate.valueOf does not exist. Fixing this is not necessary to get this PR merged. But you are of course still very welcome to fix this.

@@ -912,7 +912,7 @@ public boolean isNullTypeSchema(Schema schema) {
}

if (schema instanceof JsonSchema) { // 3.1 spec
if (Boolean.TRUE.equals(schema.getNullable())) {
if (Boolean.TRUE.equals(schema.getNullable()) && schema.get$ref() == null) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please add to bin/configs/ a small example of a case where this change prevents the generation of invalid code?
Thanks.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried long and hard, but couldn't reproduce this within the sample specs. Can you take a look? Just take this spec and you will see the error in e.g. model.RepositoryWebhooks, where you will see AnyOf license instead of SimpleLicense license.

@beikov
Copy link
Contributor Author

beikov commented Sep 29, 2024

I was finally able to reproduce another issue that I found, which is using additionalProperties: false while also using oneOf in an object. This generates wrong code i.e. multiple public Object getObject() methods in the model.
Interestingly, it works when removing the additionalProperties: false config. I dug a bit into the various code paths where I found differences, but it's getting a bit too complicated for me.
I attempted to fix a few issues I found regarding additionalProperties handling, but couldn't get to the bottom of it yet. I would appreciate some help.

@wing328
Copy link
Member

wing328 commented Oct 4, 2024

I attempted to fix a few issues I found regarding additionalProperties handling, but couldn't get to the bottom of it yet. I would appreciate some help.

do you mind opening a separate issue with details to track it?

@martin-mfg
Copy link
Contributor

The fixes from this PR have been merged via #19815 and #19817. They also solve the problem @beikov mentioned above.

I attempted to fix a few issues I found regarding additionalProperties handling, but couldn't get to the bottom of it yet. I would appreciate some help.

do you mind opening a separate issue with details to track it?

@beikov
Copy link
Contributor Author

beikov commented Oct 10, 2024

I'll close this PR since @martin-mfg addressed all the issues I had with his recent commits.

@beikov beikov closed this Oct 10, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants