Skip to content

feat(java): read idempotency-key generation config from the IR#17012

Open
devin-ai-integration[bot] wants to merge 4 commits into
mainfrom
devin/1783699867-java-idempotency-key
Open

feat(java): read idempotency-key generation config from the IR#17012
devin-ai-integration[bot] wants to merge 4 commits into
mainfrom
devin/1783699867-java-idempotency-key

Conversation

@devin-ai-integration

@devin-ai-integration devin-ai-integration Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Description

Makes the v1 Java SDK generator's idempotency-key feature IR-driven. Instead of a per-generator generators.yml config flag with hardcoded Idempotency-Key/POST/PUT, the generator now reads ir.getSdkConfig().getIdempotencyKeyGeneration():

  • Present → feature enabled; absent → disabled.
  • Header name comes from IdempotencyKeyGeneration.getHeaderName() (no longer hardcoded).
  • Method-gating comes from IdempotencyKeyGeneration.getMethods() (no longer hardcoded POST/PUT).

Runtime behavior is preserved: a caller-supplied key always wins, otherwise a fresh UUID.randomUUID() is generated. When the feature is disabled, generated output is byte-identical to before (maybeWrapHeadersWithIdempotencyKey returns the original headers expression unchanged).

Built on the IR v67 upgrade (#17027, now merged). The SdkConfig.idempotencyKeyGeneration field and IdempotencyKeyGeneration model exist as of IR v67. This branch is rebased on main and targets main.

Changes Made

  • AbstractEndpointWriter.java: added idempotencyKeyGenerationForEndpoint() (filters the IR config by the endpoint's HTTP method) and maybeWrapHeadersWithIdempotencyKey(...); all four header-emitting sites now route through it.
  • NoRequestEndpointWriter.java / OnlyRequestEndpointWriter.java / WrappedRequestEndpointWriter.java: header emission wrapped via the same helper.
  • Cli.java: emit IdempotencyUtils only when getSdkConfig().getIdempotencyKeyGeneration().isPresent().
  • IdempotencyUtilsGenerator.java + resources/IdempotencyUtils.java: runtime helper withGeneratedIdempotencyKey(Map<String,String> headers, String headerName) (UUIDv4, putIfAbsent so caller wins). Header name is a parameter, not hardcoded.
  • Removed the per-generator config-flag plumbing (autoGenerateIdempotencyKey).
  • packages/commons/api-workspace-commons/src/checkVersionExists.ts: getGeneratorConfigObject() helper so the seed synthetic invocation can thread the auto-generate-idempotency-key config into the IR (falls back to the resolved config when no raw block is present).
  • Seed: idempotency-headers and java-idempotency-headers-file-upload now each generate an auto-generate-idempotency-key variant (via the kebab CLI key) alongside the off variant. Off variants are byte-identical to main.

Testing

  • pnpm seed test --generator java-sdk --fixture idempotency-headers --fixture java-idempotency-headers-file-upload --skip-scripts — 4/4 pass.
  • Injection confirmed: POST create wraps headers with IdempotencyUtils.withGeneratedIdempotencyKey(..., "Idempotency-Key"); DELETE does not (method-gating works).
  • Off variant (no-custom-config, default) byte-identical to base.

@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@nitpickybot nitpickybot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

AI Review Summary

Ports the auto-generate idempotency key feature to the Java SDK generator. Implementation is clean and follows existing conventions. One notable resource leak in the generator's error path and a minor thread-safety observation on the config flag boxing.

  • 🔵 1 suggestion(s)

Comment on lines +40 to +41
} catch (IOException e) {
throw new RuntimeException("Failed to read IdempotencyUtils.java");

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔵 suggestion

The original IOException is swallowed — chain it for debuggability.

Suggested change
} catch (IOException e) {
throw new RuntimeException("Failed to read IdempotencyUtils.java");
} catch (IOException e) {
throw new RuntimeException("Failed to read IdempotencyUtils.java", e);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done — chained the cause in 42b7a48: throw new RuntimeException("Failed to read IdempotencyUtils.java", e);.

@github-actions

github-actions Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

SDK Generation Benchmark Results

Comparing PR branch against median of 5 nightly run(s) on main (latest: 2026-07-13T05:08:13Z).

Full benchmark table (click to expand)
Generator Spec main (generator) main (E2E) PR (generator) Delta
java-sdk square 226s (n=5) 267s (n=5) 183s -43s (-19.0%)

main (generator): generator-only time via --skip-scripts (includes Docker image build, container startup, IR parsing, and code generation — this is the same Docker-based flow customers use via fern generate). main (E2E): full customer-observable time including build/test scripts (nightly baseline, informational). Delta is computed against generator-only baseline.
⚠️ = generation exited with a non-zero exit code (timing may not reflect a successful run).
Baseline from nightly runs on main (latest: 2026-07-13T05:08:13Z). Trigger benchmark-baseline to refresh.
Last updated: 2026-07-13 21:39 UTC

@devin-ai-integration devin-ai-integration Bot force-pushed the devin/1783699867-java-idempotency-key branch from df4de3f to a3f3815 Compare July 11, 2026 00:04
@devin-ai-integration devin-ai-integration Bot changed the title feat(java): auto-generate idempotency key for POST/PUT feat(java): read idempotency-key generation config from the IR Jul 11, 2026
@devin-ai-integration devin-ai-integration Bot changed the base branch from main to devin/1783725075-java-ir67-upgrade July 11, 2026 00:05
@github-actions

Copy link
Copy Markdown
Contributor

Docs Generation Benchmark Results

Comparing PR branch against median of 5 nightly run(s) on main (latest: 2026-07-10T05:18:08Z).

Fixture main PR Delta
docs 241.5s (n=5) 230.0s (35 versions) -11.5s (-4.8%)

Docs generation runs fern generate --docs --preview end-to-end against the benchmark fixture with 35 API versions (each version: markdown processing + OpenAPI-to-IR + FDR upload).
Delta is computed against the nightly baseline on main.
Baseline from nightly run(s) on main (latest: 2026-07-10T05:18:08Z). Trigger benchmark-baseline to refresh.
Last updated: 2026-07-11 00:38 UTC

Base automatically changed from devin/1783725075-java-ir67-upgrade to main July 13, 2026 14:40
cade and others added 2 commits July 13, 2026 14:42
Drive idempotency-key auto-generation from ir.getSdkConfig().getIdempotencyKeyGeneration() instead of a per-generator config flag. The header name and eligible HTTP methods come from the IR; a caller-supplied key always wins, otherwise a UUIDv4 is generated. Output is byte-identical when the feature is disabled.

Depends on #17027 (IR v67 upgrade).

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@devin-ai-integration devin-ai-integration Bot force-pushed the devin/1783699867-java-idempotency-key branch from 42b7a48 to f6dab18 Compare July 13, 2026 14:44
… idempotency resolver conflict in favor of main (global api.settings support)

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

Devin is archived and cannot be woken up. Please unarchive Devin if you want to continue using it.

5 similar comments
@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

Devin is archived and cannot be woken up. Please unarchive Devin if you want to continue using it.

@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

Devin is archived and cannot be woken up. Please unarchive Devin if you want to continue using it.

@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

Devin is archived and cannot be woken up. Please unarchive Devin if you want to continue using it.

@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

Devin is archived and cannot be woken up. Please unarchive Devin if you want to continue using it.

@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

Devin is archived and cannot be woken up. Please unarchive Devin if you want to continue using it.

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.

1 participant