Title: feat: opt-in API version auto-negotiation by postalservice14 · Pull Request #2630 · docker-java/docker-java · GitHub
Open Graph Title: feat: opt-in API version auto-negotiation by postalservice14 · Pull Request #2630 · docker-java/docker-java
X Title: feat: opt-in API version auto-negotiation by postalservice14 · Pull Request #2630 · docker-java/docker-java
Description: Summary Adds an opt-in API version auto-negotiation flag, similar to moby/client.NegotiateAPIVersion. When enabled, the client queries GET /version once at construction and pins itself to min(daemon ApiVersion, latest version supported by docker-java). If that result is below the daemon's MinAPIVersion, the daemon's minimum is used and a WARN is logged. Fixes #2547. Behaviour Default off. Existing callers see no behaviour change. Opt-in surface: DefaultDockerClientConfig.Builder.withApiVersionAutoNegotiation(boolean), env var DOCKER_API_VERSION_AUTO_NEGOTIATION, property api.version.auto.negotiation (truthy values: true case-insensitive, 1). Precedence: explicit withApiVersion(...) always wins. If both are set, the explicit version is used and negotiation is skipped. Failure mode: a non-2xx /version response or transport exception throws DockerClientException — the caller opted in, so loud failure is the right call. Implementation DockerClientConfig gets a new default boolean isApiVersionAutoNegotiationEnabled() { return false; }. The project's japicmp config already tolerates METHOD_NEW_DEFAULT, so this is binary-compatible against the 3.3.4 baseline. ApiVersionNegotiator is a new public utility class that calls GET /version directly via DockerHttpClient and applies the moby negotiation formula. It deliberately does not reuse VersionCmdExec to avoid a circular dependency with the cmd-exec factory that's still being constructed. NegotiatedDockerClientConfig is a package-private decorator that overrides only getApiVersion(), so DefaultDockerClientConfig stays immutable. The negotiation hook runs inside DockerClientImpl.getInstance(DockerClientConfig, DockerHttpClient), before the cmd-exec factory is built, so every subsequent command picks up the negotiated version. The client's "latest supported version" is discovered by reflection over RemoteApiVersion's VERSION_1_X constants — adding new constants in future bumps just works without touching the negotiator. Test plan ./mvnw -pl docker-java -am test -Dtest='ApiVersionNegotiatorTest,DefaultDockerClientConfigTest' — 30 tests, all green ./mvnw clean install -DskipITs — full reactor build, japicmp clean on docker-java-api + every transport adapter, Checkstyle clean across all modules Negotiator covers: daemon newer than client (pins to client max), daemon older than client (pins to daemon), daemon min above client max (pins to daemon min, warns), non-2xx and missing-ApiVersion failure paths Config covers: builder default-off, builder boolean setter, string parser parity with withDockerTlsVerify, env-var path, system-property path Note: OkHttpClientTests#testHijacking is flaky on my dev machine — failing identically on this branch and on main — but it's untouched by this PR. Out of scope Flipping the default to on (a future PR can do that once this one has shipped). Re-running negotiation after a daemon restart / reconnect. The current behaviour is one-shot at construction, matching moby's NegotiateAPIVersion. This change is
Open Graph Description: Summary Adds an opt-in API version auto-negotiation flag, similar to moby/client.NegotiateAPIVersion. When enabled, the client queries GET /version once at construction and pins itself to min(daemo...
X Description: Summary Adds an opt-in API version auto-negotiation flag, similar to moby/client.NegotiateAPIVersion. When enabled, the client queries GET /version once at construction and pins itself to min(daemo...
Opengraph URL: https://github.com/docker-java/docker-java/pull/2630
X: @github
Domain: github.com
| route-pattern | /:user_id/:repository/pull/:id/files(.:format) |
| route-controller | pull_requests |
| route-action | files |
| fetch-nonce | v2:ff3955d8-d315-dd71-5e95-30ff01dbc544 |
| current-catalog-service-hash | ae870bc5e265a340912cde392f23dad3671a0a881730ffdadd82f2f57d81641b |
| request-id | D870:13D32C:6B6F69:919A67:6A51D1EA |
| html-safe-nonce | 0492994eeca1eee81b920e5dbe6800e378bcd1f80037c7d0012c7749ec4d36e6 |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJEODcwOjEzRDMyQzo2QjZGNjk6OTE5QTY3OjZBNTFEMUVBIiwidmlzaXRvcl9pZCI6IjMxMzk0NTEyNDYzODMwNTk0MzQiLCJyZWdpb25fZWRnZSI6ImlhZCIsInJlZ2lvbl9yZW5kZXIiOiJpYWQifQ== |
| visitor-hmac | 821e2db4d54c97c57426789661d768eb27e5adb584a345786da441172cd66a9c |
| hovercard-subject-tag | pull_request:3718815225 |
| github-keyboard-shortcuts | repository,pull-request-list,pull-request-conversation,pull-request-files-changed,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/docker-java/docker-java/pull/2630/files |
| twitter:image | https://avatars.githubusercontent.com/u/46067?s=400&v=4 |
| twitter:card | summary_large_image |
| og:image | https://avatars.githubusercontent.com/u/46067?s=400&v=4 |
| og:image:alt | Summary Adds an opt-in API version auto-negotiation flag, similar to moby/client.NegotiateAPIVersion. When enabled, the client queries GET /version once at construction and pins itself to min(daemo... |
| og:site_name | GitHub |
| og:type | object |
| hostname | github.com |
| expected-hostname | github.com |
| None | b9a586c06a05a7a86fc7e3f4dbd03e42f6869085879aa184aa6369456dbd50fb |
| turbo-cache-control | no-preview |
| diff-view | unified |
| go-import | github.com/docker-java/docker-java git https://github.com/docker-java/docker-java.git |
| octolytics-dimension-user_id | 7772003 |
| octolytics-dimension-user_login | docker-java |
| octolytics-dimension-repository_id | 20415251 |
| octolytics-dimension-repository_nwo | docker-java/docker-java |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 20415251 |
| octolytics-dimension-repository_network_root_nwo | docker-java/docker-java |
| turbo-body-classes | logged-out env-production page-responsive full-width |
| disable-turbo | true |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | 7aed05249554b889eb33d002851a973eebcc7e91 |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width