Thanks to visit codestin.com
Credit goes to Github.com

Skip to content

Conversation

@Pepo48
Copy link
Contributor

@Pepo48 Pepo48 commented Feb 10, 2026

Closes: #46158

@mabartos
Copy link
Contributor

@michalvavrik @vmuzikar @robson90 Could you please check this PR? Thanks!

@michalvavrik
Copy link
Member

Looking.

* Detects classes with @JsonAnyGetter and sets additionalProperties on their schemas.
* This reflects that the class accepts arbitrary additional JSON properties at runtime.
*/
private void addAdditionalPropertiesToSchemas(OpenAPI openAPI) {
Copy link
Member

Choose a reason for hiding this comment

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

I am fine with doing this for any JsonAnyGetter provided they are missing from the generated OpenAPI document (which they are, I checked). But you explicitly speak about additonalProperties, so either:

  • you are dead certain there never will be any other such getter with different name
  • tweak javadoc or method name to clarify that this propagates any such a getter into openapi specs
  • filter method infos to only those with names getAdditionalFields

It is a nitpick...

Copy link
Contributor

Choose a reason for hiding this comment

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

We actually don't want anything to show up in the schema for JsonAnyGetter.

Copy link
Member

Choose a reason for hiding this comment

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

Ok, I didn't know. Also looking at the entry.getValue().setAdditionalPropertiesSchema(OASFactory.createSchema()); I think if it were to be present in the definition, you need to filter methods by name to do not include accidentally future getters.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The intention behind bringing back the additionalProperties was to try, whether it could solve issues with Kiota generator (reportedly it did). But I might've misunderstood the goal. Also I did not test this with Kiota myself - thus it is in a separate commit, which we can easily remove.

@michalvavrik can you confirm that this additionalProperties is what fixes the failures even for you and whether it is really what we need here?

Another approach would be adding the @Schema(additionalProperties = Schema.True.class), which I actually tried at first, but I decided not to use it, because it was syntactically different (generated just additionalProperties: true, not sure whether it poses some problem or not).

Thank you!

Copy link
Member

Choose a reason for hiding this comment

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

@michalvavrik can you confirm that this additionalProperties is what fixes the failures even for you and whether it is really what we need here?

it doesn't; gosh I need to make myself clearer in the future, sorry

So the issue with the kiota generator is that BaseRepresentation is empty in the generated OpenAPI document. But that is still the case, as currently, BaseRepresentation isn't augmented by the addAdditionalPropertiesToSchemas. Are there 2 ways I know about how to deal with it:

  • @edewit just removed @Schema and obviously unused BaseRepresentation disappeared, that is fine if we add comment that once the representation contains any properties, we would like to have it in the OpenAPI document
  • we can add dummy readonly property, e.g. A="1", but I looked into OpenAPI specs and I can't see how to instruct generators to never include it in clients. it is not nice, I'd not use it

Another approach would be adding the @Schema(additionalProperties = Schema.True.class), which I actually tried at first, but I decided not to use it, because it was syntactically different (generated just additionalProperties: true, not sure whether it poses some problem or not).

If there is no function for having the additionalProperties in the response, e.g. client doesn't need it, let's not do it.

Copy link
Member

Choose a reason for hiding this comment

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

Sorry for your time if you did it only because of my previous comments.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@michalvavrik no worries, it's misunderstanding on my end, partially caused by the fact that OpenAPI generator's behaviour was different. I just read your comment under Erik's PR and hopefully got the context. Now it should copy Erik's approach.

@Pepo48 Pepo48 force-pushed the fix-v2-polymorphism branch from 322fd00 to dd30861 Compare February 10, 2026 19:19
@robson90
Copy link
Contributor

For me the generation is failing, because of the non existent BaseRepresentation.

Logs:

[INFO] --- kiota:0.0.31:generate (default) @ keycloak-admin-openapi ---
[info] Going to execute the command: /Users/robinmeese/Documents/GitHub/meine/keycloak-client/admin-openapi/target/kiota/1.30.0/kiota generate --openapi /Users/robinmeese/Documents/GitHub/meine/keycloak-client/admin-openapi/src/main/resources/openapi-pr-46180.yaml --output /Users/robinmeese/Documents/GitHub/meine/keycloak-client/admin-openapi/target/generated-sources/kiota/org/keycloak/robin --language Java --class-name ApiClient --namespace-name org.keycloak.robin --type-access-modifier Public --serializer io.kiota.serialization.json.JsonSerializationWriterFactory --deserializer io.kiota.serialization.json.JsonParseNodeFactory --additional-data --log-level Warning
warn: Kiota.Builder.KiotaBuilder[534942631]
      OpenAPI warning: #/components/schemas/Auth/allOf/0/$ref - The schema reference '#/components/schemas/BaseRepresentation' does not point to an existing schema.
warn: Kiota.Builder.KiotaBuilder[534942631]
      OpenAPI warning: #/components/schemas/BaseClientRepresentation/allOf/0/$ref - The schema reference '#/components/schemas/BaseRepresentation' does not point to an existing schema.
warn: Kiota.Builder.KiotaBuilder[534942631]
      OpenAPI warning: #/ - Multiple servers entries were found in the OpenAPI description. Only the first one will be used. The root URL can be set manually with the request adapter.
crit: Kiota.Builder.KiotaBuilder[0]
      error generating the client: One or more errors occurred. (One or more errors occurred. (One or more errors occurred. (One or more errors occurred. (One or more errors occurred. (The type does not contain any information Path: \admin\api\{realmName}\clients\{version}, Reference Id: BaseRepresentation)))))

As said on Slack, my fix would be this part added to the openapi:

.....
    BaseRepresentation:
      type: object
      properties:
        additionalFields:
          type: object
          additionalProperties: { }
....

Just for testing I did change locally:
Screenshot 2026-02-11 at 15 20 11

Outcome:

    BaseRepresentation:
      description: Base representation with common properties for all representation
        types
      type: object
      properties:
        additionalFields:
          type: object
          additionalProperties: {}

After compiling and pasting it in, Kiota is running without any complaints, the calls with an OIDCRep is working.
Depending on what the useCase for the BaseRepresentation is, this could be a feasible option.
When looking at the field, it seems like you want to achieve, that every Representation has a field of name additionalFields.


Now the part where I don't know, how fix. When calling get on a Client it has the type BaseClientRep. As the discriminator is in place, we can leverage instanceOf To know which type it is. For all properties that are in BaseClientRep should just work. For specific OIDC attributes, we need to cast it.

Only way right now, as an easy fix and also a nice usable api on the Java side could be to support all of this:

/clients -> will return Type BaseClientRepresentation
/clients/oidc -> will return Type OIDCClientRepresentation
/clients/saml -> will return Type SAMLClientRepresentation

Depending on the UseCase I would then use the respective function for updating resources.

WDYT?

For reference here are my testings: robson90/keycloak-client#3

@michalvavrik
Copy link
Member

@Pepo48 the last time I read this PR it seemed fine and I didn't expect you to deal with BaseClientRepresentation. If you plan to, then additional work is probably needed. Please let us know once this is ready for a review so that you don't wait. Thanks.

@Pepo48
Copy link
Contributor Author

Pepo48 commented Feb 12, 2026

@michalvavrik OpenAPI generator didn't require any changes with regards to the base rep. Everything that is needed on top of my original PoC is just an attempt to help you guys, to stabilize Kiota.

That was the reason of the first attempt actually - I read the comment made by @robson90 from our offline conversation and tried to bring additionalFields back. But it didn't help to you, so I removed the schema completely to follow your suggestion, which broke it for Robin 😄.

But if I understand it correctly, then @JsonProperty("additionalFields") could work for both, right?

And as a next step I can try to add the return types that Robin suggested, if we agree on it.

@Pepo48
Copy link
Contributor Author

Pepo48 commented Feb 12, 2026

Regardless, feel free to bring your own adjustments at any point of time or anybody can take over this PR, if needed. My initial intention was just provide you with some basis that I already had, I don't have to necessarily drive this to the finish line (as I don't work with Kiota anyway, so you know better what you exactly need).

@Pepo48 Pepo48 force-pushed the fix-v2-polymorphism branch from dd30861 to 7c6252d Compare February 12, 2026 12:58
@michalvavrik
Copy link
Member

michalvavrik commented Feb 12, 2026

@michalvavrik OpenAPI generator didn't require any changes with regards to the base rep. Everything that is needed on top of my original PoC is just an attempt to help you guys, to stabilize Kiota.

Frankly, I had no idea that was the intention. I thought that you are fixing the class hierarchy, which seems helpful. Knowing this will help.

But if I understand it correctly, then @JsonProperty("additionalFields") could work for both, right?

IMO it would work if the additional properties were on BaseRepresentation and the BaseClientRepresentation extended it in the OpenAPI definition as well. (I am writing these names from the top of my head). but per Steven comment, I'd not go there.

Regardless, feel free to bring your own adjustments at any point of time or anybody can take over this PR, if needed. My initial intention was just provide you with some basis that I already had, I don't have to necessarily drive this to the finish line (as I don't work with Kiota anyway, so you know better what you exactly need).

Well, let see how much time I have tomorrow. I don't want your work to go waste, we can finish this one.

@robson90
Copy link
Contributor

That was the reason of the first attempt actually - I read the comment made by @robson90 from our offline conversation and tried to bring additionalFields back. But it didn't help to you, so I removed the schema completely to follow your suggestion, which broke it for Robin 😄.

Yeah, thanks for your investigation, this is now working "as expected".

Regrading my massive comments from above, we can also discuss the next steps on Monday.

PR itself LGTM, except CI is complaining about spotless...

IMO it would work if the additional properties were on BaseRepresentation and the BaseClientRepresentation extended it in the OpenAPI definition as well. (I am writing these names from the top of my head). but per Steven comment, I'd not go there.

@michalvavrik what is the exact use case for this attribute ?

@michalvavrik
Copy link
Member

 @michalvavrik what is the exact use case for this attribute ?

I don't know yet. It is not relevant because I don't want to include it.

* add additionalFileds to base representation

Closes: keycloak#46158
Signed-off-by: Peter Zaoral <[email protected]>
@Pepo48 Pepo48 force-pushed the fix-v2-polymorphism branch from 7c6252d to b8acc5a Compare February 12, 2026 15:57
Copy link
Member

@michalvavrik michalvavrik left a comment

Choose a reason for hiding this comment

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

Hello,

I had a look again and here is my conclusion.

  1. ATM this PR resolves Kiota generation issue and LGTM
  2. I lack knowledge about additionalFields, but IIUC @shawkins mentioned that we don't want them in the OpenApi document. In which case I can see only 2 options how to solve the "empty BaseRepresentation" issue:
    • add discriminator to the BaseRepresentation as I assume we are going to need it eventually to determine if it is a client or realm, user, or ...?
    • just bring back @JsonIgnore and drop @Schema as it has no function in regards to OpenAPI ATM

Thanks @Pepo48 for your work. You will have to decide what to do with your PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Enable client generators to create proper class hierarchies with inheritance

5 participants