Skip to content

[fix](iceberg) Route Azure data files through native credentials - #67470

Open
xylaaaaa wants to merge 10 commits into
apache:masterfrom
xylaaaaa:codex/azure-native-migration
Open

xylaaaaa wants to merge 10 commits into
apache:masterfrom
xylaaaaa:codex/azure-native-migration

Conversation

@xylaaaaa

@xylaaaaa xylaaaaa commented Sep 3, 2026 •

Copy link
Copy Markdown
Contributor

What problem does this PR solve?

Issue Number: None

Related PR: None

Problem Summary: Azure Iceberg data-file access was coupled to Hadoop ABFS compatibility paths and Hadoop-shaped credential maps. This PR makes the Azure storage provider responsible for resolving native credentials, URI identity, and backend access information, and routes ordinary Azure data files through the native Azure Blob C++ client.

  • Preserve Azure account/container/object identity instead of rewriting Azure locations into S3-style URIs. Reuse FILE_S3 as the existing wire reader slot with provider=azure; the underlying client is Azure, not AWS S3 or Hadoop ABFS.
  • Share request-local storage binding resolution across ordinary scans, Puffin deletion vectors, native $position_deletes, Iceberg writes, and UPDATE/MERGE reads of existing delete files.
  • Retain SharedKey compatibility and add native SAS and Entra ID client-credentials authentication using Azure::Identity::ClientSecretCredential. This does not claim native support for arbitrary bearer tokens, Managed Identity, or Workload Identity.
  • Validate known SAS expiry and credential/account scope, preserve credential identity in client caching, and redact sensitive values. Fixed SAS credentials are not claimed to refresh transparently during a running query.
  • Preserve genuine Fabric OneLake's explicit Hadoop/OAuth2 data path and the generic HDFS/Hadoop paths used by other connectors.
  • Fix Iceberg REST FileIO credential propagation and JNI metadata-task expiry handling. FE metadata planning and BE Java metadata tasks still use Iceberg FileIO; they are not migrated to the native data-file reader. Materialized StaticDataTask rows keep their existing execution path.

Network scope: native Azure access issues BE requests to configured storage endpoints. Client-secret authentication also issues token requests to the configured OAuth authority. User-configurable outbound destinations are an SSRF surface: configuring them is governed by CREATE/ALTER CATALOG privileges, and operators must restrict catalog configuration and outbound network access. This PR does not add URL-based artifact loading.

Release note

Iceberg Azure data-file reads and writes can use provider-owned native Azure credentials, including SharedKey, SAS, and Entra ID client credentials. OneLake retains its explicit Hadoop path. Expired fixed credentials fail with a diagnostic error rather than falling back to another authentication mode.

Upgrade all BEs before enabling native SAS/OAuth2 from a new FE. SharedKey retains matching legacy wire fields for rolling compatibility; SAS/OAuth2 have no equivalent legacy representation. Do not roll back only the BE while the FE continues sending native SAS/OAuth2 requests.

The connector/filesystem SPI changes require matching plugin API versions; rebuild external plugins against the updated interfaces. See native Azure acceptance and rollout instructions.

Check List (For Author)

  • Test

    • Unit Test (historical targeted runs)
      • Retained run-fe-ut.sh logs confirm 401 passing tests: 355 Azure filesystem, 7 REST FileIO, 32 FE callers, and 7 Java scanner tests, with no failures/errors/skips in that run.
      • Retained run-be-ut.sh ASAN logs confirm 19 passing targeted tests: 12 AzureAuthFactory and 7 S3ClientFactory tests. BE unit tests have been built and run; this is not a claim that the full BE suite passed.
    • Manual test / external regression (historical runs, 2026-09-14/15)
      • Databricks v3/Parquet with vended SAS: native data reads, writes, deletion vectors, UPDATE, MERGE, and overwrite were exercised through the standard regression runner.
      • SharedKey and Entra client credentials were exercised with a local Iceberg REST fixture and real Azure Storage for v2/v3 Parquet. This does not establish external Databricks REST OAuth login coverage.
      • Full ORC validation did not pass: basic reads/writes succeeded, but the expected native GET profile counters were absent. OneLake v3 Puffin reads also had a recorded failure. Neither is presented as passing coverage.
    • Re-run relevant tests against the latest rebased head. Historical results above are not post-rebase validation, and -genOut or fixture dry-run alone is not a passing result comparison.
    • Build: prior FE/BE builds were recorded; no new full build is claimed by this description update.
  • Behavior changed:

    • Yes. Ordinary Azure Iceberg data access uses native provider-owned credentials; metadata FileIO credentials and expiry are preserved separately. Plugin API and FE/BE rollout requirements apply.
  • Does this need documentation?

    • Yes. Acceptance fixture requirements and upgrade/rollback constraints are documented in docs/azure-native-iceberg-acceptance.md.

Check List (For Reviewer who merge this PR)

  • Confirm the release note
  • Confirm test cases and post-rebase results
  • Confirm documentation
  • Add branch pick label

@hello-stephen

Copy link
Copy Markdown
Contributor

Thank you for your contribution to Apache Doris.
Don't know what should be done next? See How to process your PR.

Please clearly describe your PR:

  1. What problem was fixed (it's best to include specific error reporting information). How it was fixed.
  2. Which behaviors were modified. What was the previous behavior, what is it now, why was it modified, and what possible impacts might there be.
  3. What features were added. Why was this function added?
  4. Which code was refactored and why was this part of the code refactored?
  5. Which functions were optimized and what is the difference before and after the optimization?

xylaaaaa added a commit to xylaaaaa/doris that referenced this pull request Sep 4, 2026
### What problem does this PR solve?

Issue Number: None

Related PR: apache#67470

Problem Summary: Iceberg metadata system-table tasks serialize their FileIO implementation. The BE metadata scanner used the default ObjectInputStream resolver, which ignored the scanner classloader and failed to deserialize Azure ADLSFileIO even when the Azure dependencies were packaged. Add the Iceberg Azure runtime closure to both FE and BE Iceberg artifacts, use the JDK Azure HTTP transport to avoid Doris Netty incompatibility, and resolve serialized classes with the scanner classloader.

### Release note

Azure Iceberg metadata scans can load vended ADLSFileIO credentials; native BE data-file reads remain on the Azure object client.

### Check List (For Author)

- Test: Targeted Maven unit tests for FE connector and BE metadata scanner; manual Databricks Azure SAS scan including dollar-files and dollar-position-deletes
- Behavior changed: Yes (Azure Iceberg metadata classpath and deserialization)
- Does this need documentation: No
@xylaaaaa
xylaaaaa force-pushed the codex/azure-native-migration branch from ebb36da to 4c88df2 Compare September 4, 2026 02:34
xylaaaaa added a commit to xylaaaaa/doris that referenced this pull request Sep 4, 2026
### What problem does this PR solve?\n\nIssue Number: N/A\n\nRelated PR: apache#67470\n\nProblem Summary: Record the verified Iceberg Azure native-client data-file capabilities separately from historical Hadoop ABFS evidence, including the tested SAS scan and DML path and explicit SharedKey and OAuth2 boundaries.\n\n### Release note\n\nNone\n\n### Check List (For Author)\n\n- Test: Manual Databricks Azure E2E with compiled FE/BE; documentation and diff checks\n- Behavior changed: No\n- Does this need documentation: Yes (this document)
@xylaaaaa
xylaaaaa force-pushed the codex/azure-native-migration branch 2 times, most recently from c296b2d to ca8b1ab Compare September 7, 2026 04:22
xylaaaaa added a commit to xylaaaaa/doris that referenced this pull request Sep 11, 2026
### What problem does this PR solve?

Issue Number: N/A

Related PR: apache#67470

Problem Summary: Normalize the PR apache#67470 Azure routing overview into copy-ready Markdown. The document now leads with verified conclusions and uses consistent headings, punctuation, code formatting, tables, and lists while preserving the technical details and validation gaps.

### Release note

None

### Check List (For Author)

- Test: No need to test (documentation-only formatting change)

- Behavior changed: No

- Does this need documentation: No
xylaaaaa added a commit to xylaaaaa/doris that referenced this pull request Sep 11, 2026
### What problem does this PR solve?

Issue Number: N/A

Related PR: apache#67470

Problem Summary: Azure provider inputs accepted SharedKey, SAS, and OAuth2 spellings through independent string predicates. The backend map emitted SHARED_KEY while the property binder did not accept that canonical value on a round trip, and native client dispatch implicitly treated every non-SharedKey/non-SAS value as OAuth2. Add a provider-owned AzureAuthType parser, make validation and output exhaustive, and preserve the existing Hadoop/OneLake configuration view and native credential keys. Unknown explicit values now fail without falling back to another credential type.

### Release note

None

### Check List (For Author)

- Test: Checkstyle validate and git diff --check; FE UT source added but not run pending user compilation
- Behavior changed: Yes (canonical Azure auth values now round-trip and unknown explicit values are rejected)
- Does this need documentation: No
xylaaaaa added a commit to xylaaaaa/doris that referenced this pull request Sep 11, 2026
### What problem does this PR solve?

Issue Number: N/A

Related PR: apache#67470

Problem Summary: Azure endpoint and SAS normalization were duplicated across provider properties and Java client paths. Add provider-owned AzureAccountHost and AzureSasToken models, preserve Azure cloud suffixes, normalize only SAS transport prefixes, reconcile explicit/token expiry using the earliest known time, and route existing outputs through these models without changing the FE-to-BE key contract or OneLake Hadoop path.

### Release note

None

### Check List (For Author)

- Test: Checkstyle validate and git diff --check; FE UT source added but not run pending user compilation
- Behavior changed: Yes (DFS endpoints are normalized to Blob endpoints for native Blob client; malformed/expired known SAS expiry is rejected)
- Does this need documentation: No
xylaaaaa added a commit to xylaaaaa/doris that referenced this pull request Sep 11, 2026
### What problem does this PR solve?

Issue Number: N/A

Related PR: apache#67470

Problem Summary: Azure SAS expiry was evaluated while binding properties, which made a short-lived credential unusable even when the bound object was only being inspected or reused later. Defer time-dependent checks to backend/Hadoop credential output and native Azure client creation, allow tests to inject a Clock, and reject conflicting SharedKey, SAS, and OAuth2 material instead of inferring an ambiguous mode.

### Release note

None

### Check List (For Author)

- Test: Checkstyle validate and git diff --check; FE UT source added but not run pending user compilation
- Behavior changed: Yes (expiry is enforced at credential use points; ambiguous credential combinations are rejected)
- Does this need documentation: No
xylaaaaa added a commit to xylaaaaa/doris that referenced this pull request Sep 11, 2026
### What problem does this PR solve?

Issue Number: N/A

Related PR: apache#67470

Problem Summary: The new Azure host model omitted the separator after the account name and discarded transport settings while converting DFS endpoints. SAS properties computed an effective expiry but still exported the raw explicit timestamp, and cached Java clients bypassed expiry validation. Correct host rendering, retain the explicit scheme, port and encoded path, export the earliest known expiry and check cached client access with an injectable clock. Reject malformed or ambiguous expiry without exposing credential input in exception causes. Add unit-test coverage and correct the SharedKey fixture to include its required account name.

### Release note

Preserve Azure endpoint transport settings and reject known expired SAS credentials when retrieving a cached FE Azure client.

### Check List (For Author)

- Test: Maven Checkstyle validate (7 modules, 0 violations) and git diff --check; unit tests added but not run, with compilation and UT execution handed to the user
- Behavior changed: Yes (correct host rendering and effective expiry export; cached FE client expiry checks; malformed SAS expiry rejection)
- Does this need documentation: No
xylaaaaa added a commit to xylaaaaa/doris that referenced this pull request Sep 11, 2026
### What problem does this PR solve?

Issue Number: N/A

Related PR: apache#67470

Problem Summary: StorageAdapter converts backend properties once and returns cached copies on later calls. Azure SAS expiry checks in the provider converter therefore do not protect cached backend configurations. Add a provider-owned local access-validation hook and invoke it before every backend-map access. Azure reuses its typed SAS expiry validation, while other providers retain the default no-op behavior and existing caches. Keep binding/replay validation separate from credential lifetime checks. Add contract tests for cache hits, error propagation, copy isolation, and non-Azure providers.

### Release note

FE rejects known-expired Azure SAS credentials when retrieving cached backend configuration instead of forwarding the stale configuration.

### Check List (For Author)

- Test: Manual test / Unit Test
    - Manual test: Maven Checkstyle passed for fe-core, fe-filesystem-api, and fe-filesystem-azure; metadata-funnel gate and git diff --check passed.
    - Unit Test: Added and updated targeted tests; not run for this commit. Compilation and UT execution are delegated to the user.
    - Standalone Maven validate could not resolve uninstalled internal SNAPSHOT artifacts for fe-core; the same Checkstyle configuration was run directly without compilation.
- Behavior changed: Yes (cached Azure SAS access now checks known expiry; no automatic credential refresh)
- Does this need documentation: No (internal validation boundary; local test records are not committed)
xylaaaaa added a commit to xylaaaaa/doris that referenced this pull request Sep 11, 2026
### What problem does this PR solve?

Issue Number: N/A

Related PR: apache#67470

Problem Summary: ObjectInfoAdapter can forward both the stored Azure account key and a supplied SAS token, but the typed Azure provider rejects mixed authentication material. Convert a supplied SAS as the complete authentication choice without forwarding the old SharedKey; preserve account, endpoint and container. Keep malformed or expired SAS failures explicit instead of falling back to SharedKey. Preserve the no-token SharedKey path and the S3-compatible STS converter. Redact ObjectInfo token rendering so logging this credential holder does not expose SAS or session tokens. This change does not implement Azure getStsToken or claim Cloud ARN support.

### Release note

Azure stage credential conversion keeps SAS separate from SharedKey. ObjectInfo log rendering masks tokens without changing the values used for authentication.

### Check List (For Author)

- Test: Manual test / Unit Test
    - Manual test: fe-core Checkstyle passed with zero violations; metadata-funnel gate and git diff --check passed.
    - Unit Test: Added SharedKey/SAS conversion, malformed/blank/expired SAS rejection and token-redaction tests; existing S3/OSS tests retained. New tests and compilation are not run in this turn and are delegated to the user.
- Behavior changed: Yes (a supplied Azure SAS replaces SharedKey authentication; token log rendering is masked)
- Does this need documentation: No (conversion compatibility fix; local execution records are not committed)
xylaaaaa added a commit to xylaaaaa/doris that referenced this pull request Sep 11, 2026
### What problem does this PR solve?

Issue Number: N/A

Related PR: apache#67470

Problem Summary: Bind account-scoped Iceberg ADLS SAS directly to typed Azure properties. Replace authentication as a group while preserving connection defaults and scope checks. Propagate recognized invalid or expired credentials without the legacy fail-soft fallback, remove Azure conversion from CredentialUtils, and preserve Azure URI authorities and object keys. Leave non-Azure vended routing and genuine Hadoop bindings on their existing paths.

### Release note

Azure vended SAS is bound directly by the filesystem provider. Filesystem plugins must target API version 2.0 after the new provider binding hook.

### Check List (For Author)

- Test: Unit Test - 333 tests across 17 targeted classes through run-fe-ut.sh; incremental build.sh --fe with Checkstyle; metadata-funnel and whitespace checks. No live Azure data access tested.
- Behavior changed: Yes - Azure provider owns ADLS SAS conversion and recognized credential failures propagate; non-Azure legacy failure behavior is retained.
- Does this need documentation: No - local implementation and validation notes are not included in this commit.
xylaaaaa added a commit to xylaaaaa/doris that referenced this pull request Sep 11, 2026
…fetimes

### What problem does this PR solve?

Related PR: apache#67470

Problem Summary: Native Azure data access still borrowed AWS credential fields and accepted Hadoop or catalog aliases. Move authentication into an SDK-independent Azure model, preserve legacy SharedKey only at wire boundaries, validate provider and URI scope, and retain literal Iceberg ADLS object names. Bound the Azure client cache, reject expired SAS before access and publication, preserve concurrent holder refresh, and avoid leaking container SAS or deleting published blobs during abort.

### Release note

Native Azure access rejects conflicting or expired credentials. SAS and OAuth2 credentials cannot produce a user-facing presigned URL; error logs retain their local path. Aborting a staged Azure upload no longer deletes an existing blob.

### Check List (For Author)

- Test: Unit tests added for native protocol, SDK-backed fake-transport range reads, expiry/cache concurrency, presigning, and abort/error-log behavior; not run yet. Standard incremental BE build attempted and stopped at a stale PCH/generated-header mismatch before Azure verification. Clang-format 16 and build hygiene passed; clang-tidy passed for both modified common Azure implementations. Remaining BE build and UT require the user-run near-full PCH rebuild.
- Behavior changed: Yes, explicit Azure protocol and credential admission, bounded Azure-only cache, literal ADLS names, and non-destructive abort/presign failure handling.
- Does this need documentation: No, local redesign and verification notes are maintained outside the commit.
xylaaaaa added a commit to xylaaaaa/doris that referenced this pull request Sep 11, 2026
### What problem does this PR solve?

Related PR: apache#67470

Problem Summary: Percent-decoding ABFS and WASB object names changes the object selected by Iceberg ADLSFileIO, which passes those names literally to the Azure SDK. Preserve literal ADLS names and decode Azure HTTP URL paths only once. Add a contract test against the actual Iceberg ADLSLocation and Java Blob SDK, using a test-scope Iceberg dependency without changing FileIO or plugin runtime dependencies. Correct the OneLake routing fixture to use its own OAuth2 binding, explicitly select Azure, and supply the existing Iceberg REST catalog context; preserve rejection of an unrelated account binding.

### Release note

Native Azure paths preserve percent sequences in Iceberg ABFS and WASB object names instead of addressing a different object.

### Check List (For Author)

- Test: Standard incremental FE build and Checkstyle passed. Standard run-fe-ut.sh targeted 25 classes: 435 reported tests, 434 passed, zero failures/errors, one pre-existing disabled GCS case. Actual Iceberg ADLSLocation/Java SDK contract tests passed without network I/O. OneLake binding failure was reproduced with a pre-routing assertion before the fixture fix. BE and live Azure verification remain pending separately.
- Behavior changed: Yes, ABFS/WASB names retain literal percent sequences; HTTP path decoding is unchanged.
- Does this need documentation: No, compatibility fix; detailed verification notes remain local and are not committed.
xylaaaaa added a commit to xylaaaaa/doris that referenced this pull request Sep 11, 2026
### What problem does this PR solve?

Issue Number: N/A

Related PR: apache#67470

Problem Summary: Resolve Azure credentials, URI, reader and backend properties from a request-local provider binding. Replace stale static authentication before reading its backend view, keep native Azure parameters separate from OneLake Hadoop configuration, and use the same resolved contract in data scans, delete vectors and write sinks. Preserve legacy non-Azure routing and serialized Iceberg FileIO metadata tasks. Add real engine/provider and Thrift-range contract tests, including metadata roots on a different store and scoped credentials. Align one stale writer assertion with the existing empty-snapshot OCC contract without changing transaction code.

### Release note

Azure data access uses provider-owned native parameters and binding-aware HTTPS routing. OneLake keeps its Hadoop backend view. Connector and filesystem plugins must be rebuilt against API majors 8 and 4 respectively.

### Check List (For Author)

- Test: Unit Test / Manual test
    - run-fe-ut.sh: 71 selected classes, 1067 passed, 0 failures/errors, 1 pre-existing disabled test
    - build.sh --fe: incremental build and Checkstyle passed; target/output hashes and plugin API manifests verified
    - Connector import and metadata-funnel gates passed
    - BE build/tests and cloud end-to-end validation not run for this slice
- Behavior changed: Yes (provider-resolved Azure routing and isolated native/Hadoop credential views)
- Does this need documentation: No (internal protocol refactor; local implementation and testing notes intentionally excluded)
xylaaaaa added a commit to xylaaaaa/doris that referenced this pull request Sep 11, 2026
### What problem does this PR solve?

Issue Number: N/A

Related PR: apache#67470

Problem Summary: Add a storage-provider output for the official Iceberg
FileIO without round-tripping BE or Hadoop credentials. Azure renders
SharedKey and SAS in the SDK's dialect, checks expiry and rejects endpoints
that carry separate credential material. Client-secret OAuth2 contributes
only a HadoopFileIO selection requirement; native credentials are unchanged.
Equivalent DFS and Blob SAS aliases now rebind as one account while
conflicting credentials remain rejected. Update both plugin API surfaces
and version gates for the shared contract. Catalog integration remains a
subsequent change; this commit does not claim to wire REST FileIO selection.

### Release note

Accept equivalent same-account DFS and Blob aliases for Azure vended SAS.
Connector and filesystem plugins require API versions 9.0 and 5.0.

### Check List (For Author)

- Test: Unit Test / Incremental FE build
    - Standard run-fe-ut.sh: 78 classes, 1175 tests, 0 failures, 0 errors,
      1 pre-existing disabled GCS test; Surefire XML counts verified.
    - Official ADLSFileIO and Azure Java SDK metadata reads against a
      loopback HTTP fixture with dummy SAS and SharedKey credentials.
    - Standard build.sh --fe, Checkstyle and packaged API version checks.
    - No BE build, cloud I/O or cluster restart in this change.
- Behavior changed: Yes (equivalent Azure SAS host aliases; new provider
  FileIO contract, not yet connected to catalog initialization)
- Does this need documentation: No (local execution notes are not committed)
xylaaaaa added a commit to xylaaaaa/doris that referenced this pull request Sep 11, 2026
### What problem does this PR solve?

Issue Number: N/A

Related PR: apache#67470

Problem Summary: Native Azure credentials were not connected to the official Iceberg REST FileIO construction path. Per-key SDK configuration merging could retain an obsolete key or SAS expiry, while unconditional response adaptation could reject a metadata refresh using an already established FileIO. Resolve complete Azure authentication groups through the provider-owned storage binding, preserve metadata and scoped credentials, and adapt GET responses only during initial table loading. Validate metadata identity and incompatible explicit FileIO choices, and prevent a local response-binding failure from replaying a successful create/register request. Keep non-Azure storage, Hadoop metadata authentication, and the official SDK FileIO lifecycle intact. Bump the connector/filesystem API versions with their shared interface changes.

### Release note

Iceberg REST metadata FileIO and native Azure data access now share provider-selected SharedKey/SAS credentials. Unsupported explicit FileIO/authentication combinations fail clearly instead of silently selecting another identity.

### Check List (For Author)

- Test: Unit Test / offline SDK integration
    - run-fe-ut.sh: 88 related classes, 1305 tests, 0 failures/errors, 1 pre-existing GCS skip
    - build.sh --fe incremental build with Checkstyle; packaged plugin/API consistency checks
    - No BE full build or cloud E2E in this batch
- Behavior changed: Yes, bind Azure REST FileIO credentials as complete groups and validate selected metadata access
- Does this need documentation: No; local verification notes are not included in the commit
xylaaaaa added a commit to xylaaaaa/doris that referenced this pull request Sep 11, 2026
### What problem does this PR solve?

Issue Number: None

Related PR: apache#67470

Problem Summary: Metadata scan properties exported an expired static Azure SAS before replacing it with valid vended credentials. A cold serialized ResolvingFileIO also used the parent-loaded CatalogUtil, which could not see ADLSFileIO bundled in the JNI scanner and fell back to Hadoop. Replace only the typed Azure binding before exporting credentials and load the two FileIO factories locally in the Iceberg scanner while retaining shared interfaces, tasks, other FileIO implementations, and other scanners. Keep the existing all-manifests resolver and JNI credential forwarding until their replacement is verified across the remaining paths.

### Release note

Iceberg Azure metadata scans can select fresh vended SAS before static expiry validation and resolve cold serialized Azure FileIO in the BE Java scanner.

### Check List (For Author)

- Test: Unit Test - standard run-fe-ut.sh, 11 classes / 208 tests passed with packaged FileIO tests explicitly enabled; rerun against final target jars. Standard build.sh --fe incremental build and Checkstyle passed. Verified packaged class identity, Azure HTTP service discovery, loopback Azure/S3 reads, Hadoop configuration and local reads, real FE-planned all-manifests task rows, and static snapshot consumption. No BE C++ or live Azure/OneLake tests in this batch.
- Behavior changed: Yes - replace selected Azure credentials before expiry validation and use scanner-local Iceberg FileIO factories.
- Does this need documentation: No - no new configuration; local validation notes remain uncommitted.
xylaaaaa added a commit to xylaaaaa/doris that referenced this pull request Sep 11, 2026
### What problem does this PR solve?

Issue Number: N/A

Related PR: apache#67470

Problem Summary: The native Azure SAS reader test transport left HEAD response bodies null. The Azure SDK transport policy consumes a body stream even for HEAD, causing an ASAN null dereference before the range-read assertions ran. Provide a zero-length memory stream for HEAD while retaining the four-byte GET body and all existing assertions. Only the test fixture changes.

### Release note

None

### Check List (For Author)

- Test: Unit Test
    - run-be-ut.sh --run: 103 selected tests from 13 suites passed on the current migration worktree; no failures, errors, or skips.
    - Eleven cache and concurrency tests passed five repeated iterations using GTEST_REPEAT=5.
    - clang-format 16 and git diff --check passed. clang-tidy remains blocked by existing NOLINTEND, helper complexity, and getenv nullability diagnostics.
- Behavior changed: No; production client and reader code are unchanged.
- Does this need documentation: No
xylaaaaa added a commit to xylaaaaa/doris that referenced this pull request Sep 11, 2026
### What problem does this PR solve?

Issue Number: N/A

Related PR: apache#67470

Problem Summary: The Iceberg scanner resolved every serialized class descriptor with Class.forName, which throws ClassNotFoundException for primitive descriptors such as int and does not resolve child-only proxy interfaces. Reuse the parent-provided Commons IO ClassLoaderObjectInputStream to preserve extension visibility and standard Java descriptor handling. Cover the public scanner boundary with primitive, array, ordinary class, isolated task and public/private proxy cases.

### Release note

Iceberg metadata tasks containing primitive class descriptors or extension-local proxy interfaces can be deserialized by the BE Java scanner.

### Check List (For Author)

- Test: Unit Test
    - Reproduced ClassNotFoundException: int before the fix; the same scanner test passes after it.
    - All 15 serialization tests passed via run-fe-ut.sh. The current migration worktree also passed 438 selected Java tests, including real packaged-scanner loopback reads.
    - build.sh --fe --be-java-extensions and Checkstyle passed; packaged parent Commons IO and scanner class bytes were verified.
- Behavior changed: Yes; preserve Java primitive/proxy serialization while retaining the scanner classloader.
- Does this need documentation: No
xylaaaaa added a commit to xylaaaaa/doris that referenced this pull request Sep 11, 2026
### What problem does this PR solve?

Issue Number: N/A

Related PR: apache#67470

Problem Summary: A metadata query requesting split_offsets without file_size_in_bytes receives null even when the manifest contains valid offsets. The Iceberg BaseFile getter validates the last offset against the projected file size, which otherwise defaults to -1. Append the size field only as an internal dependency after the requested columns. The BE continues reading the requested prefix positionally, so visible columns and ordering remain unchanged. This is an Iceberg metadata projection issue exposed by the Azure packaged-scanner tests, not an Azure authentication failure.

### Release note

Iceberg files metadata projections retain split_offsets when file_size_in_bytes is not selected.

### Check List (For Author)

- Test: Unit Test
    - Nine projection tests passed across files, data_files, all_files and all_data_files, including explicit-size ordering and unrelated projections.
    - The original packaged Azure scanner test now returns exact map/array values across batches of two and one rows. A diagnostic control reproduced null before the packaged scanner prior to the fix.
    - run-fe-ut.sh: all 438 selected Java tests passed on the migration worktree. build.sh --fe --be-java-extensions, Checkstyle and git diff --check passed.
- Behavior changed: Yes; preserve non-null split offsets without adding user-visible columns or changing FileIO.
- Does this need documentation: No
xylaaaaa added a commit to xylaaaaa/doris that referenced this pull request Sep 11, 2026
### What problem does this PR solve?

Issue Number: N/A

Related PR: apache#67470

Problem Summary: Azure metadata tasks previously depended on native reader credentials copied into the JNI Hadoop channel and a BE Java resolver that reflectively replaced all-manifests FileIO. Bind REST scoped metadata SAS through the existing provider bridge before task serialization, reject conflicting scopes, and retain the original official Iceberg FileIO. Forward only actual Hadoop execution configuration for metadata tasks, preserving HadoopFileIO and the authentication wrapper. Carry known fixed SAS expiry separately in optional Thrift field 13 and reject expired tasks at scanner open without echoing credentials. Remove the old resolver and replace reflection-based tests with real planned tasks and packaged-scanner loopback reads, including multi-batch map/array output.

### Release note

Azure Iceberg metadata tasks retain their planned FileIO credentials without native Azure Hadoop sideband rebinding. Known expired fixed SAS credentials are diagnosed before task execution; genuine Hadoop configuration and materialized metadata rows keep their existing paths.

### Check List (For Author)

- Test: Unit Test
    - run-fe-ut.sh on the complete migration worktree: 26 classes, 438 tests, zero failures/errors/skips; actual per-class XML agrees with the execution log.
    - Packaged scanner tests exercise cold all_manifests, files and entries reads through the official Azure Java SDK against a loopback fixture, plus materialized manifests/snapshots and fixed-credential expiry.
    - Previously executed run-be-ut.sh subset: 103 tests passed, including all five C++ JNI expiry/configuration forwarding tests; C++ code has not changed since that run.
    - build.sh --fe --be-java-extensions, Java Checkstyle, clang-format 16 for the four P7 C++ files, build hygiene and git diff --check passed.
    - clang-tidy remains unpassed due to the existing unmatched NOLINTEND in core/types.h; builtin-header lookup also required a local toolchain include-path correction. No checks were disabled.
    - Not claimed: live Azure/Entra/OneLake authentication, full C++ to JVM query execution, all custom FileIO combinations or mixed-version deployment.
- Behavior changed: Yes; metadata credentials stay in serialized FileIO, with a separate optional expiry value. Native Azure data access and true Hadoop channels retain their responsibilities.
- Does this need documentation: No; local verification notes and environment configuration are not committed.
xylaaaaa added a commit to xylaaaaa/doris that referenced this pull request Sep 11, 2026
### What problem does this PR solve?

Issue Number: N/A

Related PR: apache#67470

Problem Summary: The generated Thrift setters accept const references, so std::move in the two Iceberg JNI fixtures still copies and triggers performance-move-const-arg. Remove those four ineffective moves and the unused utility includes without changing fixture values, assertions or production code.

### Release note

None

### Check List (For Author)

- Test: No need to rerun GTest for the value-category-only cleanup: both setter signatures accept const references and preserve the same copies and assertions.
    - Both files passed syntax-only checks derived from their real UT compile database entries; no objects or PCH were generated.
    - clang-format 16, build hygiene and git diff --check passed.
    - Re-running repository clang-tidy removed all four move diagnostics. The check still exits 1 on the existing unmatched NOLINTEND in core/types.h; it is not reported as passing.
- Behavior changed: No; tests and production behavior are unchanged.
- Does this need documentation: No
xylaaaaa added a commit to xylaaaaa/doris that referenced this pull request Sep 11, 2026
### What problem does this PR solve?

Issue Number: N/A

Related PR: apache#67470

Problem Summary: clang-tidy stops on core/types.h because its trailing
NOLINTEND has no matching NOLINTBEGIN. Remove only that dangling comment
so the native Azure and Iceberg JNI translation units can be analyzed.
No C++ declarations, definitions, or suppression settings are changed.

### Release note

None

### Check List (For Author)

- Test: Manual static checks: repository clang-tidy script passes all five
  selected Azure/JNI source and test files; clang-format 16 and build hygiene pass.
  No BE rebuild or GTest rerun for this comment-only change.
- Behavior changed: No
- Does this need documentation: No
xylaaaaa added a commit to xylaaaaa/doris that referenced this pull request Sep 11, 2026
### What problem does this PR solve?

Issue Number: N/A

Related PR: apache#67470

Problem Summary: The native SAS reader fixture exceeds the cognitive
complexity gate through nested assertion macros, and repeated getenv calls
produce nullable-string diagnostics. Separate the reader-content and client
configuration assertions without removing checks, propagate fatal read
failures, and validate and consume the same environment-variable pointers.

### Release note

None

### Check List (For Author)

- Test: Repository clang-tidy, clang-format 16 and build hygiene pass.
  Exact Azure-enabled UT compile command passes syntax-only verification.
  GTest was not rerun after this cleanup; real Azure access was not attempted.
- Behavior changed: No production behavior change
- Does this need documentation: No
xylaaaaa added a commit to xylaaaaa/doris that referenced this pull request Sep 11, 2026
### What problem does this PR solve?

Issue Number: N/A

Related PR: apache#67470

Problem Summary: The native Azure migration needs a repeatable cloud
acceptance entrypoint after the storage-binding and metadata-FileIO refactor.
Use a preconfigured write-enabled Azure catalog and an authorized namespace,
without putting credentials into suite SQL. Cover Parquet/ORC v2 and v3
reads, position deletes, Puffin DV consumers, UPDATE/MERGE, overwrite, and
metadata tables. Require positive native GET/byte counters on uncached reads.
Keep suite-owned tables for diagnosis and require explicit fixture opt-in.
Validate configuration before registration; disabled and dry runs register
no successful empty suites. Generate golden results only against real Azure.

### Release note

None

### Check List (For Author)

- Test: Standard run-regression-test.sh --compile succeeds, including 9
  existing framework unit tests. Suite parses with the actual SuiteScript base.
  Official dryRun verifies disabled/configuration-only execution reports zero
  suites, and enabled missing configuration exits nonzero before suite SQL.
  Real Azure/DBX execution and generated .out results remain pending; no cloud
  pass or writer/credential-mode acceptance is claimed.
- Behavior changed: No production behavior change
- Does this need documentation: No
xylaaaaa added a commit to xylaaaaa/doris that referenced this pull request Sep 11, 2026
### What problem does this PR solve?

Issue Number: N/A

Related PR: apache#67470

Problem Summary: New Azure lifecycle and error-log tests used positional
SDK aggregate initialization and nested namespace syntax. GTest assertion
expansions also pushed the concurrent client snapshot test over the
complexity limit. Use designated fields and a qualified namespace, and
extract the snapshot assertions without changing their nonfatal behavior
or the test's barriers and join.

### Release note

None

### Check List (For Author)

- Test: clang-format 16 and official clang-tidy changed-line checks passed;
  lifecycle and runtime tests also pass full-file clang-tidy. GTest was not
  rerun; seven unrelated pre-existing factory diagnostics remain.
- Behavior changed: No
- Does this need documentation: No
xylaaaaa added a commit to xylaaaaa/doris that referenced this pull request Sep 11, 2026
### What problem does this PR solve?

Issue Number: None

Related PR: apache#67470

Problem Summary: Iceberg FileIO properties can contain provider-normalized DFS and Blob aliases alongside the original scoped credential. Merging the scoped values per key leaves an inconsistent expiry or an older authentication identity in native Azure bindings. Replace the complete Azure authentication group before applying the scoped credential, while retaining connection settings, strict scope validation and non-Azure merge behavior. Add extractor and real engine/provider tests that reproduce the expiry and token conflicts before the fix.

### Release note

Fix native Azure credential binding when vended SAS credentials coexist with normalized or older FileIO authentication properties.

### Check List (For Author)

- Test: Unit Test - standard run-fe-ut.sh, 8 classes and 426 tests passed; the four new real-provider cases failed before the fix. Standard build.sh --fe and Checkstyle passed. Manual read-only Azure data/Puffin/metadata queries passed on the updated FE; an uncached data query recorded a native GET. Full DML regression remains pending.
- Behavior changed: Yes - native Azure extraction replaces authentication atomically instead of retaining stale aliases; non-Azure and legacy extraction remain unchanged.
- Does this need documentation: No - internal credential-binding fix.
@hello-stephen

Copy link
Copy Markdown
Contributor

FE Regression Coverage Report

Increment line coverage 18.91% (66/349) 🎉
Increment coverage report
Complete coverage report

xylaaaaa added a commit to xylaaaaa/doris that referenced this pull request Sep 17, 2026
### What problem does this PR solve?

Issue Number: N/A
Related PR: apache#67470

Problem Summary: After merging the Iceberg 1.11 upgrade, RESTSessionCatalog
loads tables through a GET overload with a response-header consumer. The
native Azure FileIO client wrapper did not override it, so even S3-backed
REST catalogs failed with "Returning response headers is not supported"
before sending the table request. Forward this overload to the delegate
while retaining response adaptation, authentication and error handling.

Add local HTTP tests through the real RESTCatalog.loadTable path for S3 and
Azure locations, plus response adaptation/header forwarding, Supplier and
authenticated-client dispatch, HTTP 204/304 and missing-table errors. These
tests need neither cloud credentials nor an external storage environment.

### Release note

Restore Iceberg REST table loading after the Iceberg 1.11 upgrade, including
S3 and Azure-backed catalogs using the native FileIO client wrapper.

### Check List (For Author)

- Test: Unit Test / Manual test
    - Reproduced the original failure with five tests before the fix
    - ./run-fe-ut.sh: 224 targeted tests passed, including six new cases
    - ./build.sh --fe: build and Checkstyle passed
    - Original local HTTP loadTable reproducer passes with the fixed wrapper
    - Full external regression CI was not rerun locally
- Behavior changed: Yes (forward SDK response-header GET instead of throwing)
- Does this need documentation: No

### Self-review

- Goal and evidence: real SDK table loads now reach HTTP and construct the
  adapted FileIO; pre-fix failure and post-fix success were both observed.
- Scope: one missing forwarding overload, its null-response comment and tests.
- Concurrency: no new shared state, threads or locks in production.
- Lifecycle: existing auth-session wrappers and delegate ownership are unchanged;
  test HTTP servers and clients are closed after each case.
- Configuration: no new options or environment changes are committed.
- Compatibility: implements the existing SDK contract; no Doris SPI or persistent
  format changes and no plugin API version bump is required.
- Parallel paths: Map and inherited Supplier dispatch are covered, including
  withAuthSession; other GET and POST overloads are unchanged.
- Conditional handling: reuse null-response adaptation for HTTP 204/304;
  delegate errors propagate without adapting failed responses.
- Coverage: S3/Azure metadata locations, successful payload replacement, headers,
  conditional requests, empty responses and 404 errors are covered offline;
  existing external regressions exercise the SQL-level failure.
- Test results: no generated regression outputs were edited.
- Observability: preserve SDK error diagnostics; no new credential logging.
- Transactions and persistence: no changes to commits, EditLog or persisted data.
- Data writes: POST/create/commit behavior is unchanged.
- FE/BE transport: no new fields or reader changes.
- Performance: one existing delegate call plus existing response adaptation;
  no additional remote request, cache or per-row work.
- Other issues: no additional issue found in the changed production path.
xylaaaaa added a commit to xylaaaaa/doris that referenced this pull request Sep 17, 2026
### What problem does this PR solve?

Issue Number: N/A
Related PR: apache#67470

Problem Summary: Merge master e545b13 into the native Azure branch.
Both branches extend the connector API: this branch adds typed storage access
and master adds OpenCSV scan semantics and freezes the inlined scan property
keys. Preserve both API surfaces, both compatibility tests and the recent
Iceberg REST response-header fix. Use connector API 12.0 for the combined
contract rather than reusing either parent's version; explicitly reject
pre-merge API 11 plugins that lack the OpenCSV contract.

### Release note

Connector plugins use API 12.0 for the combined native Azure and OpenCSV
contract. Plugins built against older connector API versions must be rebuilt.

### Check List (For Author)

- Test: Unit Test / Manual test
    - ./run-fe-ut.sh: 363 initial targeted tests passed, including REST GET,
      storage binding, Iceberg scans, Hive CSV and plugin API version checks
    - ./run-fe-ut.sh: all 148 connector SPI tests and 13 FE CSV property tests
      passed (436 distinct tests across both runs)
    - ./build.sh --fe passed, including Checkstyle
    - Resolved-file git diff --check and C++ check-format.sh passed
    - Packaged connector manifests and FE version gate both declare API 12.0
    - Full external regression and BE suites were not rerun locally
- Behavior changed: Yes (API 12 rejects plugins predating the merged contract)
- Does this need documentation: No

### Merge self-review

- Goal: resolve four API/test baseline conflicts while retaining both branches;
  both frozen metadata/surface contracts and plugin version tests pass.
- Scope: manual resolutions are confined to the four conflicted files.
- Concurrency: no new production threads, shared mutable state or locks.
- Lifecycle: plugin registry test fixtures retain before/after cleanup; no
  scanner, FileIO or authentication-session lifecycle changes.
- Configuration: no user environment files are committed; use the existing
  build-time plugin API property, not a new runtime configuration option.
- Compatibility: API 12 prevents API 8/10/11 admission while current-version
  plugins remain loadable; preserve master scan-key freezing and Azure types.
- Parallel paths: all in-tree connector manifests inherit the same API property.
- Conditions: no new production branches or fallback behavior in resolutions.
- Coverage: all SPI tests, negative plugin admission cases and selected
  Iceberg/Hive paths pass; live external storage validation remains with CI.
- Results: merge existing frozen interface snapshots; no generated regression
  output was manually rewritten.
- Observability: preserve existing version mismatch diagnostics and inventory.
- Transactions/persistence: manual resolutions do not change transaction or
  persisted-state logic.
- Writes: no data write path changes in the manual resolutions.
- FE/BE transport: master OpenCSV field and Azure FileIO expiry field coexist;
  retain their respective producers and consumers.
- Performance: no new query-time work in manual resolutions.
- Other issues: REST response-header production code and tests are unchanged
  from c9c235f; no additional merge-resolution issue found.
@xylaaaaa

Copy link
Copy Markdown
Contributor Author

run buildall

@hello-stephen

Copy link
Copy Markdown
Contributor
TPC-H: Total hot run time: 27627 ms
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/tpch-tools
Tpch sf100 test result on commit d88d302bf446834fd07cf4bfdbe73c8d9e74bbff, data reload: false

------ Round 1 ----------------------------------
============================================
q1	17085	3934	3890	3890
q2	2352	345	289	289
q3	9920	1390	791	791
q4	4683	484	347	347
q5	7614	835	557	557
q6	188	170	133	133
q7	747	792	594	594
q8	9410	1497	1498	1497
q9	5569	4206	4168	4168
q10	6785	1622	1370	1370
q11	431	268	246	246
q12	629	414	289	289
q13	18054	2638	2018	2018
q14	273	255	232	232
q15	q16	754	725	659	659
q17	1880	1118	935	935
q18	6499	5590	5559	5559
q19	1166	1235	1094	1094
q20	488	385	267	267
q21	5592	2607	2401	2401
q22	427	344	291	291
Total cold run time: 100546 ms
Total hot run time: 27627 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	4185	4070	4059	4059
q2	745	574	561	561
q3	4518	4951	4350	4350
q4	2233	2324	1416	1416
q5	4218	4116	4106	4106
q6	226	187	125	125
q7	1711	1619	1424	1424
q8	2161	2251	2152	2152
q9	7607	7531	7690	7531
q10	4366	4427	3882	3882
q11	546	394	374	374
q12	715	764	520	520
q13	2456	2852	2202	2202
q14	299	315	274	274
q15	q16	695	706	649	649
q17	7720	7130	6990	6990
q18	11879	11163	11873	11163
q19	1212	1088	1085	1085
q20	2253	2224	1928	1928
q21	5668	4736	4864	4736
q22	533	472	412	412
Total cold run time: 65946 ms
Total hot run time: 59939 ms

@hello-stephen

Copy link
Copy Markdown
Contributor

FE UT Coverage Report

Increment line coverage 73.00% (146/200) 🎉
Increment coverage report
Complete coverage report

@hello-stephen

Copy link
Copy Markdown
Contributor
TPC-DS: Total hot run time: 153723 ms
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/tpcds-tools
TPC-DS sf100 test result on commit d88d302bf446834fd07cf4bfdbe73c8d9e74bbff, data reload: false

query5	4321	610	463	463
query6	434	188	166	166
query7	4950	519	289	289
query8	320	175	183	175
query9	8767	3962	4020	3962
query10	445	309	256	256
query11	5865	2184	1989	1989
query12	150	98	110	98
query13	1251	592	382	382
query14	6516	4534	4212	4212
query14_1	4018	3966	3967	3966
query15	205	199	173	173
query16	1002	501	383	383
query17	922	697	544	544
query18	2442	483	338	338
query19	220	182	151	151
query20	107	101	107	101
query21	222	139	118	118
query22	13057	12998	13768	12998
query23	16105	14958	14376	14376
query23_1	14398	14192	14030	14030
query24	7420	1706	1224	1224
query24_1	1242	1229	1233	1229
query25	545	459	387	387
query26	1327	323	162	162
query27	2651	554	324	324
query28	4546	1946	1930	1930
query29	1070	599	448	448
query30	310	233	193	193
query31	876	744	630	630
query32	149	93	89	89
query33	490	294	247	247
query34	1202	1117	630	630
query35	739	735	653	653
query36	796	786	685	685
query37	161	100	84	84
query38	1833	1773	1684	1684
query39	705	684	671	671
query39_1	658	653	630	630
query40	214	116	100	100
query41	62	61	62	61
query42	129	85	85	85
query43	341	349	293	293
query44	1408	683	681	681
query45	176	166	165	165
query46	1084	1143	691	691
query47	1482	1508	1378	1378
query48	375	421	289	289
query49	581	414	293	293
query50	972	351	244	244
query51	10558	10434	10415	10415
query52	83	85	77	77
query53	241	256	177	177
query54	244	205	183	183
query55	76	71	71	71
query56	236	212	216	212
query57	1524	1380	1369	1369
query58	241	205	209	205
query59	2018	2053	1826	1826
query60	277	250	229	229
query61	143	150	144	144
query62	405	328	269	269
query63	220	176	172	172
query64	2871	1044	826	826
query65	4003	3929	3933	3929
query66	1789	416	304	304
query67	19825	20661	19691	19691
query68	3145	1507	915	915
query69	396	288	260	260
query70	948	916	885	885
query71	286	238	214	214
query72	2989	2558	2205	2205
query73	841	783	432	432
query74	4608	4508	4300	4300
query75	2338	2273	1961	1961
query76	2279	1159	716	716
query77	369	406	308	308
query78	9101	9061	8522	8522
query79	1410	1268	761	761
query80	632	453	382	382
query81	465	283	239	239
query82	644	171	128	128
query83	358	275	251	251
query84	320	139	112	112
query85	853	484	378	378
query86	364	244	232	232
query87	1982	1964	1835	1835
query88	3694	2732	2719	2719
query89	371	287	241	241
query90	1948	188	183	183
query91	168	157	128	128
query92	105	91	90	90
query93	1554	1513	827	827
query94	553	336	311	311
query95	679	369	334	334
query96	1106	807	319	319
query97	2450	2430	2306	2306
query98	213	190	189	189
query99	749	715	599	599
Total cold run time: 242136 ms
Total hot run time: 153723 ms

@hello-stephen

Copy link
Copy Markdown
Contributor
ClickBench: Total hot run time: 24.1 s
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/clickbench-tools
ClickBench test result on commit d88d302bf446834fd07cf4bfdbe73c8d9e74bbff, data reload: false

query1	0.00	0.00	0.00
query2	0.10	0.05	0.05
query3	0.26	0.14	0.13
query4	1.62	0.15	0.14
query5	0.25	0.25	0.23
query6	1.16	0.93	0.96
query7	0.04	0.00	0.00
query8	0.06	0.04	0.04
query9	0.41	0.34	0.35
query10	0.56	0.59	0.58
query11	0.21	0.14	0.15
query12	0.19	0.16	0.15
query13	0.47	0.46	0.47
query14	0.96	0.94	0.95
query15	0.61	0.59	0.59
query16	0.33	0.34	0.33
query17	1.08	1.08	1.10
query18	0.23	0.21	0.21
query19	1.96	1.95	1.90
query20	0.02	0.01	0.01
query21	15.43	0.23	0.13
query22	4.90	0.06	0.05
query23	16.16	0.31	0.12
query24	2.97	0.41	0.32
query25	0.10	0.05	0.04
query26	0.73	0.20	0.16
query27	0.05	0.04	0.03
query28	3.50	0.76	0.37
query29	12.50	3.96	3.18
query30	0.29	0.16	0.15
query31	2.77	0.59	0.32
query32	3.23	0.58	0.48
query33	3.17	3.25	3.23
query34	15.74	4.01	3.28
query35	3.27	3.23	3.23
query36	0.57	0.44	0.42
query37	0.09	0.06	0.07
query38	0.06	0.04	0.03
query39	0.04	0.03	0.03
query40	0.18	0.15	0.14
query41	0.08	0.03	0.03
query42	0.04	0.02	0.03
query43	0.05	0.04	0.03
Total cold run time: 96.44 s
Total hot run time: 24.1 s

morningman added a commit to morningman/doris that referenced this pull request Sep 17, 2026
…e in S3ClientFactory

Part 1 of the apache#67470 split tracked in apache#68103: the BE consumer side of the
native Azure protocol.

- AzureCredentialOptions models SharedKey / SAS / OAuth2 credential groups
  and S3ClientConf carries it; equality, hash and to_string are per provider.
- S3ClientFactory accepts the native AZURE_* map and the legacy AWS_*
  SharedKey map (convert_legacy_azure_properties), validates the data URI
  against the binding, and keeps Azure clients in a separate bounded cache
  that is pruned by SAS expiry and re-validated on every access.
- AzureAuthFactory builds clients for all three credential types and
  derives the effective SAS expiry from the token and AZURE_SAS_EXPIRY_MS.
- S3URI parses abfs[s]:// and wasb[s]:// authorities and Azure HTTP(S)
  hosts; ABFS/WASB object names stay literal.
- SAS tokens are redacted from SDK logs and client error messages;
  generate_presigned_url signs only under SharedKey and the error-log path
  falls back to the local file when no URL can be signed;
  abort_multipart_upload no longer deletes the blob.

Issue: apache#68103
Related PR: apache#67470
Depends on: nothing

Co-authored-by: xylaaaaa <[email protected]>
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
@hello-stephen

Copy link
Copy Markdown
Contributor

BE Regression && UT Coverage Report

Increment line coverage 86.21% (50/58) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 69.02% (31151/45132)
Line Coverage 53.89% (340597/632014)
Region Coverage 50.36% (284769/565438)
Branch Coverage 51.06% (129855/254332)

1 similar comment
@hello-stephen

Copy link
Copy Markdown
Contributor

BE Regression && UT Coverage Report

Increment line coverage 86.21% (50/58) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 69.02% (31151/45132)
Line Coverage 53.89% (340597/632014)
Region Coverage 50.36% (284769/565438)
Branch Coverage 51.06% (129855/254332)

@hello-stephen

Copy link
Copy Markdown
Contributor

BE Regression && UT Coverage Report

Increment line coverage 86.21% (50/58) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 69.06% (31166/45132)
Line Coverage 53.90% (340643/632014)
Region Coverage 50.34% (284624/565438)
Branch Coverage 51.07% (129878/254332)

morningman added a commit to morningman/doris that referenced this pull request Sep 17, 2026
Review follow-up for apache#68117. Legacy SharedKey producers (old FE property
maps, ObjectStoreInfoPB, TS3StorageParam) hand the endpoint over literally
and the old factory only defaulted the scheme. Two rewrites had leaked into
that path:

- normalize_azure_endpoint()'s bare account-name inference also ran for
  legacy endpoints, so an unschemed single-label host such as
  AWS_ENDPOINT=storage-proxy was redirected to
  https://storage-proxy.blob.core.windows.net.
- import_legacy_azure_shared_key() ran normalize_http_uri(), collapsing
  repeated path separators in custom reverse-proxy base paths.

The native protocol keeps its full normalization where it is parsed
(convert_native_azure_properties). _create_azure_client() now only applies
the transport rule the old factory had: default the scheme and normalize
the endpoint/container join boundary. The persisted endpoint is no longer
rewritten.

Tests cover all three legacy producers with unschemed single-label hosts
and exact custom base paths, asserting both the stored endpoint and the
container base the SDK signs against.

Issue: apache#68103
Related PR: apache#67470

Co-authored-by: xylaaaaa <[email protected]>
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
morningman added a commit to morningman/doris that referenced this pull request Sep 17, 2026
Follow-up for apache#68117. azure_transport_endpoint() was added in the
anonymous namespace without a guard, but its only caller is the
USE_AZURE branch of S3ClientFactory::_create_azure_client(). The
Performance pipeline builds with DISABLE_BUILD_AZURE=ON, so gcc
rejected the file with -Werror=unused-function:

  be/src/util/s3_util.cpp:333:13: error: 'std::string
  doris::{anonymous}::azure_transport_endpoint(std::string)' defined
  but not used [-Werror=unused-function]

Every other pipeline builds with Azure on, which is why only the
Performance job failed. Move the helper under the same USE_AZURE guard
as the other _create_azure_client()-only helpers. Verified locally with
-fsyntax-only for s3_util.cpp, s3_uri.cpp, s3_file_system.cpp and
runtime_state.cpp both with and without -DUSE_AZURE.

Issue: apache#68103
Related PR: apache#67470

Co-authored-by: xylaaaaa <[email protected]>
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
morningman added a commit to morningman/doris that referenced this pull request Sep 18, 2026
…idate_azure_uri

Review follow-up for apache#68117, three defects in the new native Azure URI
contract:

- S3URI::parse() stripped '?' and '#' from ABFS/WASB object paths. Iceberg's
  ADLSLocation ("^(abfss?|wasbs?)://([^/?#]+)(.*)?$") and Hadoop's Path both
  take everything after the authority as the object path, so an object
  named path/a?b#c.parquet was opened as path/a. Query and fragment are now
  only stripped for the S3 and HTTP(S) schemes.
- The OneLake fence compared the raw authority, so an explicit port
  (onelake.dfs.fabric.microsoft.com:443) or a trailing DNS root dot made a
  genuine Fabric location pass the later checks and reach the native client.
  The fence now matches on the DNS host (case-folded, no port, no root dot).
- Azure RA-GRS/RA-GZRS secondary endpoints append "-secondary" to the
  account label while keeping the primary account identity and keys (the SDK
  signs with the credential's account name and only swaps the host). The
  account check compared that label with the credential and rejected valid
  secondary reads. On official Azure hosts the suffix now folds to the
  primary account for the ABFS/WASB endpoint identity and for the credential
  account check; HTTP(S) transport matching stays exact.

Tests: S3URITest.QueryAndFragmentAreLiteralOnlyInAdlsPaths (plus '?'/'#'
names in IcebergAdlsPathsPreserveLiteralPercentSequences),
S3ClientFactoryTest.OneLakeFenceIgnoresPortAndDnsRootDot,
AllowsDocumentedAzureSecondaryEndpoints and
SecondaryFoldingKeepsOtherAccountsApart.

Issue: apache#68103
Related PR: apache#67470

Co-authored-by: xylaaaaa <[email protected]>
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
…port

### What problem does this PR solve?

Related PR: apache#67470

Problem Summary: Keep Azure credential types, authentication factories, URI/endpoint handling, native client caching and their direct unit tests together.

This is a history-only regrouping of the native Azure PR. The final seven-commit
series preserves the exact code tree of azure-native-before-squash-20260913550a886487e.

### Release note

None

### Check List (For Author)

- Test: Manual test / Unit Test
    - Final tree and PR diff are verified identical to the pre-squash snapshot
    - Existing final-snapshot verification: 711 selected FE tests passed
    - Tests were not rerun for this history-only rewrite
- Behavior changed: No (relative to the pre-squash PR snapshot)
- Does this need documentation: No
### What problem does this PR solve?

Related PR: apache#67470

Problem Summary: Keep FILE_S3 compatibility routing, S3 file reader/writer and file-factory integration together with the affected BE fixtures.

This is a history-only regrouping of the native Azure PR. The final seven-commit
series preserves the exact code tree of azure-native-before-squash-20260913550a886487e.

### Release note

None

### Check List (For Author)

- Test: Manual test / Unit Test
    - Final tree and PR diff are verified identical to the pre-squash snapshot
    - Existing final-snapshot verification: 711 selected FE tests passed
    - Tests were not rerun for this history-only rewrite
- Behavior changed: No (relative to the pre-squash PR snapshot)
- Does this need documentation: No
…ties

### What problem does this PR solve?

Related PR: apache#67470

Problem Summary: Keep the filesystem property interfaces, Azure provider, endpoint and vended-credential binding, plugin wiring and focused tests together.

This is a history-only regrouping of the native Azure PR. The final seven-commit
series preserves the exact code tree of azure-native-before-squash-20260913550a886487e.

### Release note

None

### Check List (For Author)

- Test: Manual test / Unit Test
    - Final tree and PR diff are verified identical to the pre-squash snapshot
    - Existing final-snapshot verification: 711 selected FE tests passed
    - Tests were not rerun for this history-only rewrite
- Behavior changed: No (relative to the pre-squash PR snapshot)
- Does this need documentation: No
### What problem does this PR solve?

Related PR: apache#67470

Problem Summary: Keep the Connector Storage SPI and FE engine storage-adapter/context integration together with their tests.

This is a history-only regrouping of the native Azure PR. The final seven-commit
series preserves the exact code tree of azure-native-before-squash-20260913550a886487e.

### Release note

None

### Check List (For Author)

- Test: Manual test / Unit Test
    - Final tree and PR diff are verified identical to the pre-squash snapshot
    - Existing final-snapshot verification: 711 selected FE tests passed
    - Tests were not rerun for this history-only rewrite
- Behavior changed: No (relative to the pre-squash PR snapshot)
- Does this need documentation: No
### What problem does this PR solve?

Related PR: apache#67470

Problem Summary: Keep Iceberg FileIO, scan/write planning, metadata credential selection, the Thrift expiry field and integration tests together.

This is a history-only regrouping of the native Azure PR. The final seven-commit
series preserves the exact code tree of azure-native-before-squash-20260913550a886487e.

### Release note

None

### Check List (For Author)

- Test: Manual test / Unit Test
    - Final tree and PR diff are verified identical to the pre-squash snapshot
    - Existing final-snapshot verification: 711 selected FE tests passed
    - Tests were not rerun for this history-only rewrite
- Behavior changed: No (relative to the pre-squash PR snapshot)
- Does this need documentation: No
### What problem does this PR solve?

Related PR: apache#67470

Problem Summary: Keep the JNI metadata scanner, classloader isolation, native metadata readers and serialization tests together.

This is a history-only regrouping of the native Azure PR. The final seven-commit
series preserves the exact code tree of azure-native-before-squash-20260913550a886487e.

### Release note

None

### Check List (For Author)

- Test: Manual test / Unit Test
    - Final tree and PR diff are verified identical to the pre-squash snapshot
    - Existing final-snapshot verification: 711 selected FE tests passed
    - Tests were not rerun for this history-only rewrite
- Behavior changed: No (relative to the pre-squash PR snapshot)
- Does this need documentation: No
### What problem does this PR solve?

Related PR: apache#67470

Problem Summary: Keep the opt-in Databricks/Unity-Catalog-style native Azure Iceberg acceptance suite in one commit.

This is a history-only regrouping of the native Azure PR. The final seven-commit
series preserves the exact code tree of azure-native-before-squash-20260913550a886487e.

### Release note

None

### Check List (For Author)

- Test: Manual test / Unit Test
    - Final tree and PR diff are verified identical to the pre-squash snapshot
    - Existing final-snapshot verification: 711 selected FE tests passed
    - Tests were not rerun for this history-only rewrite
- Behavior changed: No (relative to the pre-squash PR snapshot)
- Does this need documentation: No
### What problem does this PR solve?

Issue Number: None

Related PR: apache#67470

Problem Summary: FE, BE, Hadoop FileIO, and REST credential paths handled Azure expiry formats, legacy aliases, endpoint scopes, and credential provenance inconsistently. The changes align SAS parsing and access-time validation, preserve old SharedKey wire fields during rolling upgrades, reject conflicting native and legacy groups, retain non-s3 object-store offsets, and add masking, scanner, and external acceptance guardrails. Existing lower-case OAuth2 replay behavior is preserved. No Thrift or storage-format change is introduced.

### Release note

Restore Azure credential compatibility across native, legacy SharedKey, REST FileIO, and Hadoop paths; add explicit rolling-upgrade and acceptance-test documentation.

### Check List (For Author)

- Test: FE targeted tests 401 passed; BE ASAN targeted tests 19 passed; regression fixture dry-run passed without Azure I/O; FE and BE format checks passed. Real Azure regression remains environment-dependent. clang-tidy was attempted but blocked by toolchain stddef.h/NOLINT errors.

- Behavior changed: Yes (legacy compatibility and explicit credential-source validation are restored; native SAS/OAuth2 still require new BEs before rollout).

- Does this need documentation: Yes (docs/azure-native-iceberg-acceptance.md and docs/azure-native-review-resolution.md).
### What problem does this PR solve?

Issue Number: N/A
Related PR: apache#67470

Problem Summary: After merging the Iceberg 1.11 upgrade, RESTSessionCatalog
loads tables through a GET overload with a response-header consumer. The
native Azure FileIO client wrapper did not override it, so even S3-backed
REST catalogs failed with "Returning response headers is not supported"
before sending the table request. Forward this overload to the delegate
while retaining response adaptation, authentication and error handling.

Add local HTTP tests through the real RESTCatalog.loadTable path for S3 and
Azure locations, plus response adaptation/header forwarding, Supplier and
authenticated-client dispatch, HTTP 204/304 and missing-table errors. These
tests need neither cloud credentials nor an external storage environment.

### Release note

Restore Iceberg REST table loading after the Iceberg 1.11 upgrade, including
S3 and Azure-backed catalogs using the native FileIO client wrapper.

### Check List (For Author)

- Test: Unit Test / Manual test
    - Reproduced the original failure with five tests before the fix
    - ./run-fe-ut.sh: 224 targeted tests passed, including six new cases
    - ./build.sh --fe: build and Checkstyle passed
    - Original local HTTP loadTable reproducer passes with the fixed wrapper
    - Full external regression CI was not rerun locally
- Behavior changed: Yes (forward SDK response-header GET instead of throwing)
- Does this need documentation: No

### Self-review

- Goal and evidence: real SDK table loads now reach HTTP and construct the
  adapted FileIO; pre-fix failure and post-fix success were both observed.
- Scope: one missing forwarding overload, its null-response comment and tests.
- Concurrency: no new shared state, threads or locks in production.
- Lifecycle: existing auth-session wrappers and delegate ownership are unchanged;
  test HTTP servers and clients are closed after each case.
- Configuration: no new options or environment changes are committed.
- Compatibility: implements the existing SDK contract; no Doris SPI or persistent
  format changes and no plugin API version bump is required.
- Parallel paths: Map and inherited Supplier dispatch are covered, including
  withAuthSession; other GET and POST overloads are unchanged.
- Conditional handling: reuse null-response adaptation for HTTP 204/304;
  delegate errors propagate without adapting failed responses.
- Coverage: S3/Azure metadata locations, successful payload replacement, headers,
  conditional requests, empty responses and 404 errors are covered offline;
  existing external regressions exercise the SQL-level failure.
- Test results: no generated regression outputs were edited.
- Observability: preserve SDK error diagnostics; no new credential logging.
- Transactions and persistence: no changes to commits, EditLog or persisted data.
- Data writes: POST/create/commit behavior is unchanged.
- FE/BE transport: no new fields or reader changes.
- Performance: one existing delegate call plus existing response adaptation;
  no additional remote request, cache or per-row work.
- Other issues: no additional issue found in the changed production path.
### What problem does this PR solve?

Related PR: apache#67470

Problem Summary: Existing commit-oriented notes do not explain the original
Databricks Azure Iceberg access requirement as a coherent development goal.
Document the problem, scope, end-to-end design, storage credential boundaries,
shared-layer compatibility requirements, and acceptance criteria independently
of commit history. Separate design goals from verified product support.

### Release note

None

### Check List (For Author)

- Test: Manual test: verify six local documentation links, Markdown code fences,
  absence of conflict markers, and git diff --check. No runtime tests needed
  for this documentation-only change.
- Behavior changed: No
- Does this need documentation: Yes (included)
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.

3 participants