New feature: Add Salesforce Data360 database and pipeline connectors - #31918
New feature: Add Salesforce Data360 database and pipeline connectors#31918rahulcodewiz wants to merge 28 commits into
Conversation
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
# Conflicts: # openmetadata-spec/src/main/resources/json/schema/entity/services/databaseService.json # openmetadata-spec/src/main/resources/json/schema/entity/services/pipelineService.json # openmetadata-ui/src/main/resources/ui/src/constants/ServiceType.constant.ts # openmetadata-ui/src/main/resources/ui/src/generated/api/services/createDatabaseService.ts # openmetadata-ui/src/main/resources/ui/src/generated/entity/services/databaseService.ts # openmetadata-ui/src/main/resources/ui/src/utils/DatabaseServiceUtils.tsx # openmetadata-ui/src/main/resources/ui/src/utils/ServiceIconUtils.ts
…equired-field blockers in Data360 connectors Salesforce API errors other than "resource not found" (auth failure, expired session, refused/malformed request) were silently swallowed and returned as None, indistinguishable from a genuine empty result. get_metadata_by_type also fetched only a single page, silently dropping data beyond the first page. Pipeline lineage resolved file/S3/SFTP source containers with a wildcard service_name="*", matching containers across every storage service instead of just the mapped one. data360DbServiceName was required for every pipeline workflow (metadata/lineage/operational) even though only lineage extraction needs it. Also fixes a broken import (metadata.ingestion.source.pipeline.informatica.exceptions) that referenced a nonexistent module, which made the pipeline lineage and operational sources unimportable since they were first added. Adds unit test coverage for the Data360 database and pipeline connectors. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
❌ PR checklist incompleteThis PR cannot be merged until the following are addressed on its linked issue:
The fields live on the linked issue in the Shipping project (open the issue → right sidebar → Projects). After you set them, re-run this check (or push a commit) — issue/project changes do not re-trigger it automatically. Maintainers can bypass this check by adding the |
|
Hi there 👋 Thanks for your contribution! The OpenMetadata team will review the PR shortly! Once it has been labeled as Let us know if you need any help! |
|
Hi there 👋 Thanks for your contribution! The OpenMetadata team will review the PR shortly! Once it has been labeled as Let us know if you need any help! |
|
The Python checkstyle failed. Please run You can install the pre-commit hooks with |
|
…ed with items present PaginatedPage.from_payload currently raises Data360ResponseError any time totalSize is absent, even when the items field is present (e.g. empty). Verified against the live Salesforce Data 360 ssot/metadata endpoint: it omits totalSize entirely, rather than returning 0, when a dataspace/entity-type combination has no matching items. That legitimate empty response was being reported as malformed and aborting the whole listing. Only raise when both totalSize and the items field are absent from the body; otherwise derive total_size from len(items). Confirmed via three live ingestion runs against a real Data 360 org with the schema that previously reproduced this (10k+ tables) that the paginator no longer raises spuriously.
Under real-org-scale ingestion (10k+ tables) the single-container local dev stack's default 1g ES heap contributed to Elasticsearch being OOM-killed by the host, causing es_mixin search warnings on otherwise-unrelated searchByField lookups during ingestion.
|
Hi there 👋 Thanks for your contribution! The OpenMetadata team will review the PR shortly! Once it has been labeled as Let us know if you need any help! |
This reverts commit 108340c.
|
Hi there 👋 Thanks for your contribution! The OpenMetadata team will review the PR shortly! Once it has been labeled as Let us know if you need any help! |
|
@pmbrull thanks for the thorough pass on issues( pydantic-model paginator, the lastRunsLimit/regex/logging fixes, the BaseConnection refactor, and the setup.py dedup) what I had. One regression I ran into: PaginatedPage.from_payload still raises unconditionally when totalSize is missing, even when items is present: total_size = body.get(paging.total_size_field) and it's locked in by test_run_paginator_raises_when_total_size_is_missing. I hit this against a real Salesforce Data 360 org (10k+ tables): the live ssot/metadata endpoint omits totalSize entirely not 0 for a legitimate empty result, e.g. {"metadata": []} with no totalSize key at I've pushed a fix on top of your work in 3476abf (fix(ingestion): don't fail Data360 pagination when totalSize is omitted with items present): it only raises when both totalSize and the items field are absent from the body, and otherwise derives total_size from len(items). Updated/replaced the test accordingly and verified against 3 live ingestion runs against the real org with zero recurrence, all 121 tests passing across the Data360 unit + topology suites. Let me know if you'd rather approach it differently |
|
Hi there 👋 Thanks for your contribution! The OpenMetadata team will review the PR shortly! Once it has been labeled as Let us know if you need any help! |
Code Review
|
| Compact |
|
Was this helpful? React with 👍 / 👎 | Powered by Gitar — free for open source
|
|
|
Regarding the SapBw4Hana loader entry Bot's comment- checked the diff and DatabaseServicePureUtils.ts only adds the Data360 entry here (2 lines), nothing is removed from there. The only other SapBw4Hana-related diff in this PR is in the generated workflow.json, where sapBw4HanaType's oneOf index shifts from 56 -> 57 I think that's the expected so no fix needed here |
|
@rahulcodewiz yes bot hallucinated, i think there was some past code I cleaned and stayed stuck |



Describe your changes:
Adds a new Salesforce Data360 (formerly known as Data cloud) data warehouse connector and a Data360 pipeline connector, since Data360 is not currently supported as a metadata source in OpenMetadata.
This adds:
ingestion/src/metadata/ingestion/source/database/data360/— database source (client, connection, metadata, utils)ingestion/src/metadata/ingestion/source/pipeline/data360pipeline/— pipeline source (connection, lineage, metadata, models, operational, exceptions)data360Connection.json,data360PipelineConnection.json) and registration indatabaseService.json/pipelineService.jsonget_metadata_by_typeonly fetched a single page of DataCloud objects, silently dropping data past the first page. It now paginates fully, following the same limit/offset/totalSize convention as the otherssot/*endpoints in this client.Type of change:
High-level design:
docs/design-patterns.md).client.pywraps the Data360 REST API (viasimple_salesforce),connection.pybuilds the connection,metadata.pyimplements the ingestion source,utils.py/constant.pyhold helpers/constants.lineage.py), and operational status (operational.py).data360pipeline/exceptions.pyholds the connector-local exceptions used by lineage/operational.openmetadata-spec/, thendatabaseService.json/pipelineService.jsonupdated to reference them; generated TS/Java types picked up via the normal codegen step.Tests:
Unit tests
ingestion/tests/unit/source/database/data360/test_client.py,test_utils.pyingestion/tests/unit/topology/database/test_data360.pyingestion/tests/unit/topology/pipeline/test_data360pipeline.pypython -m pytest ingestion/tests/unit/topology/database/test_data360.py ingestion/tests/unit/source/database/data360/ ingestion/tests/unit/topology/pipeline/test_data360pipeline.py -q→ 68 passed.Checklist:
Reviews (1): Last reviewed commit: "fix(ingestion): fix error masking, pagin..." | Re-trigger Greptile
Context used (3)
Greptile Summary
The PR adds Salesforce Data360 database and pipeline connectors across ingestion, shared schemas, generated models, and UI registration.
Confidence Score: 4/5
The PR is not yet safe to merge because omitted optional Data360 run timestamps can still abort operational-status extraction.
DataTransform, Calculated Insight, and DataStream timestamp fields are optional, but the operational extractors still substitute
0and pass it to ISO-8601 parsing, causing an exception and dropping the affected pipeline status.Files Needing Attention: ingestion/src/metadata/ingestion/source/pipeline/data360pipeline/operational.py, ingestion/src/metadata/ingestion/source/pipeline/data360pipeline/metadata.py
Important Files Changed
0and can drop status records.Flowchart
%%{init: {'theme': 'neutral'}}%% flowchart LR D360[Salesforce Data360 APIs] --> DB[Data360 database source] D360 --> PL[Data360 pipeline source] DB --> Tables[Databases, schemas, tables, columns and tags] PL --> Pipelines[Pipelines, lineage and run status] Tables --> Sink[OpenMetadata sink] Pipelines --> Sink Schemas[Connection JSON schemas] --> DB Schemas --> PL Schemas --> UI[Server and UI service registration]Reviews (11): Last reviewed commit: "fix(ingestion): resolve ruff checkstyle ..." | Re-trigger Greptile
Context used (3)