sundapeng opened a new pull request, #9937:
URL: https://github.com/apache/paimon/pull/9937

   ### Purpose
   
   Follow-up to #9918. `DLFOpenApiV4Signer` signs with ACS4-HMAC-SHA256 
correctly, but some DlfNext POP gateway deployments will not route a request 
that does not name its API. The first call a catalog makes, `GET /v1/config`, 
is refused:
   
   ```
   400 MissingHeader: Specified header x-acs-action is mandatory for this 
action.
   ```
   
   Setting `header.x-acs-action` does not help. The gateway requires the header 
to be signed and to match the request:
   
   | request | gateway response |
   | --- | --- |
   | no `x-acs-action` (current signer) | `400 MissingHeader` |
   | `x-acs-action` sent but not in `SignedHeaders` | `400 
SignatureDoesNotMatch.HeaderUnsigned` |
   | signed, but naming another API for the same path | `400 
InvalidAction.Mismatch` |
   | signed and matching | `200` |
   
   So the signer has to resolve the action per request:
   
   - `DLFRequestSigner` gains `signRequestHeaders(RESTAuthParameter, ...)`. It 
sees the method and path, and its default delegates to `signHeaders(body, 
...)`. `DLFAuthProvider` now calls it.
   - `DLFOpenApiV4Signer` overrides it to add `x-acs-action`. 
`buildCanonicalHeaders` already signs every `x-acs-*` header, so nothing else 
changes in the signature.
   - `DLFOpenApiActions` resolves the action from the method and path, matching 
whole segments against the 53 operations registered for DlfNext `2026-01-18`. A 
request that matches none, such as `GET /v1/{prefix}/tables`, is signed as 
before with no action.
   - The `default` and `openapi` signers do not change. pypaimon gets the same 
change in `dlf_openapi_actions.py`, `DLFRequestSigner.sign_request_headers` and 
`DLFAuthProvider`.
   
   ### Tests
   
   - `DLFOpenApiActionsTest` (5 tests):
     - every operation template, filled in, resolves to its own action (no 
template shadows another)
     - every matching `ResourcePaths` method resolves to its registered action
     - names spelled like literal segments (`tables`, `token`, `forward`, 
`config`) and encoded names still resolve
     - unregistered paths, other methods, and empty or trailing segments 
resolve to nothing
   - `DLFOpenApiV4SignerTest` (+3 tests):
     - a known-answer signature for a POST with a body and a resolved action; 
the same value was also computed by an independent script
     - an unregistered path gets the same headers as before
     - `DLFAuthProvider` sends `x-acs-action` inside `SignedHeaders`
   - `DLFRequestSignerTest` (+1 test): the `default` and `openapi` signers 
still send no action.
   - `dlf_signer_test.py` (+8 tests): mirrors the Java tests and pins the same 
known-answer string.
   - `org.apache.paimon.rest.**` tests: 154 pass. Checkstyle, spotless, flake8 
and the license check are clean.
   - Against a gateway that requires the header: before this change, a 
`RESTCatalog` with `dlf.signing-algorithm=openapi-v4` failed on `GetConfig`. 
With it, the Java client ran end to end, and pypaimon passed the metadata calls 
including `AuthTableQuery`, `ListPartitions`, `ListTags` and `ListBranches`. 
The Java run did: create database, create table, paged list with a `%` pattern, 
alter table, write, commit, read back, drop. That covered 13 actions, including 
`GetTableToken`, `GetTableSnapshot` and `CommitTable`.
   - Against the public `dlfnext` endpoint in cn-hangzhou, no regression: the 
same Java end-to-end run passes 11/11, and pypaimon's metadata calls pass.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to