fix: Jackson polymorphism/serialization, pagination, and GH-reported bugs (GH-1642, GH-1689, GH-1690) - #1699
Merged
Conversation
…gination type consistency - Disable broken @JsonSubTypes-based polymorphic resolution on ListJwk200ResponseInner/SamlAttributeStatement, whose spec-declared discriminator subtypes don't actually extend them, causing InvalidTypeIdException on deserialization. - Restore NON_NULL serialization on Application and its subtypes via a JsonFilter mixin, overriding the @JsonInclude(ALWAYS) generated for their required properties, which was forcing partial PUT updates to null out unrelated fields like credentials/name/settings. - Always wrap list responses in PagedList, even without a Link header (e.g. a filtered query that fits on one page), so callers get a consistent return type instead of an occasional ClassCastException. - Add maxConsecutiveCharacters to PasswordPolicyPasswordSettingsComplexity, which was missing from the spec and silently dropped on write. Co-Authored-By: Claude Code
…ype, bump bouncycastle - GroupProfileDeserializer's default case for unrecognized keys was discarding them instead of routing them into additionalProperties, so custom group schema attributes were silently dropped on read. Fixed to match the existing UserProfileDeserializer/ OktaUserGroupProfileDeserializer pattern. (GH-1642) - LogSecurityContext.userBehaviors was missing an items type, so the generator defaulted to List<String> while the API returns a list of objects, causing a MismatchedInputException. Declared items: {} so it generates List<Object>. (GH-1689) - Bump bcprov-jdk18on/bcpkix-jdk18on 1.79 -> 1.84 to address reported CVEs; commons-lang3 was already at 3.18.0. (GH-1690) Co-Authored-By: Claude Code
…Setting IT jdk11 and jdk21 run the identical integration test suite against the same shared live test org with no per-job isolation, and previously ran concurrently in the CircleCI workflow. OrgSettingGeneralIT mutates OrgSetting, which is a singleton per org, so one job's write could be clobbered by (or read back as) the other job's concurrent write to the same fields, causing flaky read-after-write assertion failures that no amount of retrying could fix. - Make jdk21 require jdk11 so the two jobs no longer run concurrently against the shared org. - Belt-and-suspenders: give OrgSettingGeneralIT's lifecycle test unique per-run values (UUID-suffixed) for the fields it writes, so even concurrent runs can no longer be confused by each other's writes. Co-Authored-By: Claude Code
…1 serialization
The real root cause of the flaky assertion was a Groovy GString/String
equality bug in my own previous fix, not job concurrency: string
interpolation ("...${runId}...") produces a GString, and
GString.equals(String) is always false even when the text matches -
CI logs showed the "Expected" and "was" values as byte-for-byte
identical strings while the assertion still failed.
- Add .toString() to the three unique per-run values so they're real
Strings, fixing the equalTo() comparisons.
- Revert the jdk21->jdk11 CircleCI dependency added in bc649b9,
since it's no longer needed and unnecessarily halves CI coverage
whenever jdk11 fails for any reason; jdk11/jdk21 run independently
again.
Co-Authored-By: Claude Code
…blicKeysIT.setup
CI observed a one-off ApiException{code=500, errorCode=E0000009} from
createApplication while provisioning the test OIDC app in @BeforeClass.
The SDK's built-in retry strategy (OktaHttpRequestRetryStrategy) only
retries 429/503/504, not a bare 500, and this call runs in @BeforeClass
so a single spurious 500 fails the entire test class. Add a small
bounded retry (3 attempts, linear backoff) scoped to this one call.
Co-Authored-By: Claude Code
aditya-okta
approved these changes
Jul 21, 2026
This was referenced Jul 21, 2026
prachi-okta
added a commit
that referenced
this pull request
Jul 21, 2026
…hemas (GH issues deep-dive) (#1701) * fix: disable broken polymorphic resolution on 6 more oneOf/discriminator schemas Deep-dive into the still-open GitHub issues (#1654, #1664, #1693) led to auditing every oneOf/anyOf + discriminator pair in the spec for the same defect class as OKTA-1227472 (subtypes that don't actually extend the declared base type via allOf, so Jackson's @JsonSubTypes throws InvalidTypeIdException). Found and fixed 6 more instances: - AgentJsonSigningKeyRequest / AgentJsonSigningKeyResponse (unreferenced in the spec today, but fixed for correctness/consistency) - ManagedConnection / ManagedConnectionCreatable - PotentialConnection - OrgContactTypeObj - this one is live and reachable from the real listOrgContactTypes endpoint Also adds a regression test confirming GH-1654's likely root cause: a mixed OIDC/SAML Application list, where the SAML app's settings.signOn.attributeStatements uses the SamlAttributeStatement type fixed in OKTA-1227472/#1699, now deserializes without throwing. Before that fix, an org with SAML apps using attribute statements could see listApplications fail on those specific apps. Co-Authored-By: Claude Code * test: add missing coverage for the 5 Agent/Connection discriminator fixes AgentJsonSigningKeyRequest, AgentJsonSigningKeyResponse, ManagedConnection, ManagedConnectionCreatable, and PotentialConnection got the same @JsonTypeInfo(Id.NONE) mixin fix as OrgContactTypeObj in the previous commit, but only OrgContactTypeObj had a regression test. Add the missing five. Note: ManagedConnection/ManagedConnectionCreatable/PotentialConnection have a separate, pre-existing quirk where their flattened ConnectionTypeEnum only retains one oneOf branch's single-value enum (STS_SERVICE_ACCOUNT) - every other connectionType value falls back to UNKNOWN_DEFAULT_OPEN_API. That's harmless (no exception) but means these tests only assert the polymorphism fix, not full enum fidelity; fully fixing that would require reworking how the spec merges oneOf branches, which is out of scope here. Co-Authored-By: Claude Code
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Issue(s)
Fixes internally-triaged SDK defects (Jira, tracked in OKTA-1228415 for the GitHub-reported ones):
@JsonSubTypesmaps invalid subtypes onListJwk200ResponseInner/SamlAttributeStatementFixes GitHub issues:
userBehaviorsproperty inLogSecurityContexthas incorrect typeAlso includes two CI stability fixes discovered while getting this PR green (see below).
Description
1. Jackson polymorphism / null-serialization / pagination fixes
ListJwk200ResponseInner/SamlAttributeStatement: these classes declare@JsonSubTypesentries (from the OpenAPI spec'soneOf/anyOf+discriminator) pointing at classes that don't actually extend them in the generated Java, since their source schemas don't useallOf-based inheritance. Jackson requires real Java inheritance for polymorphic resolution, so deserializing them threwInvalidTypeIdException. Fixed by registering@JsonTypeInfo(use = Id.NONE)mixins for these two classes inApiClient's defaultObjectMapper- both classes already contain the union of all their branches' properties as flat fields, so disabling polymorphic resolution loses no data.Applicationsubtypes (e.g.OpenIdConnectApplication):credentials/name/settingsare markedrequired, which makes the generator emit@JsonInclude(ALWAYS)on them. That overrides the ObjectMapper's globalNON_NULLdefault, so a partial PUT update (e.g. only updatingvisibility) would serialize those fields as literalnull, overwriting them server-side. Fixed with a@JsonFilter+SimpleBeanPropertyFiltermixin onApplicationthat skips null-valued properties at serialization time (filters run before per-property@JsonInclude), applied uniformly across allApplicationsubtypes.PagedList.constructPagedList: returned a plainArrayList(not aPagedList) whenever the response had noLinkheader - e.g. a filtered/qquery that fits on a single page. Callers casting toPagedListgot aClassCastException. Now always returns aPagedList;getAfter()/hasMoreItems()already report "no more pages" correctly when there's no next page.PasswordPolicyPasswordSettingsComplexity: added the missingmaxConsecutiveCharactersfield tosrc/swagger/api.yaml.2. GitHub issue fixes
GroupProfileDeserializeris a hand-writtenStdDeserializerthat bypasses Jackson's annotation-based handling (includingadditionalProperties/@JsonAnySetter). Itsdefaultcase for unrecognized keys was a no-opbreak;, silently discarding custom group schema attributes (e.g.MaxUsersCount) instead of routing them intoadditionalProperties, unlike the correctUserProfileDeserializer/OktaUserGroupProfileDeserializersiblings. Fixed to match that pattern.LogSecurityContext.userBehaviorshad noitemstype in the spec, so the generator defaulted toList<String>, while the Okta API returns a list of objects - causing aMismatchedInputExceptionwhen reading System Log events. Declareditems: {}, which now generatesList<Object>.bcprov-jdk18on/bcpkix-jdk18on1.79 -> 1.84 to address reported CVEs (commons-lang3was already at 3.18.0).3. CI stability fixes (found while landing this PR)
OrgSettingGeneralIT: the lifecycle test used fixed literal website/support-URL values, which could be clobbered by another concurrently-running JDK matrix job mutating the same org-singletonOrgSettingresource in the shared live test org. Gave the test unique per-run values. (One iteration of this fix used Groovy string interpolation directly in Hamcrest assertions, which is aGStringvsStringequality trap -GString.equals(String)is alwaysfalseeven when the text matches. Fixed by adding.toString()to produce realStrings.)ApplicationSSOPublicKeysIT.setup: hit a one-offApiException{code=500}fromcreateApplication. The SDK's built-in retry strategy only retries 429/503/504, not a bare 500, and this call runs in@BeforeClass, so a single transient 500 fails the whole test class. Added a small bounded retry (3 attempts, linear backoff) scoped to this one call.Category
Signoff