Skip to content

Migrate Data Catalog to Dataplex Knowledge Catalog for CDC templates#3927

Open
stankiewicz wants to merge 25 commits into
GoogleCloudPlatform:mainfrom
stankiewicz:fix_data_catalog_usage
Open

Migrate Data Catalog to Dataplex Knowledge Catalog for CDC templates#3927
stankiewicz wants to merge 25 commits into
GoogleCloudPlatform:mainfrom
stankiewicz:fix_data_catalog_usage

Conversation

@stankiewicz

Copy link
Copy Markdown
Contributor

This PR resolves the INVALID_ARGUMENT write operation failure (Project is not allowed to perform write operations due to Data Catalog deprecation) caused by the deprecation of the legacy Google Cloud Data Catalog API.

It migrates the Debezium-to-PubSub CDC pipeline's schema publishing and schema retrieval logic to use the new Dataplex Knowledge Catalog API (com.google.cloud.dataplex.v1.CatalogServiceClient).

Key Changes

  • Dependency Update: Replaced google-cloud-datacatalog with google-cloud-dataplex (v1.90.0) in cdc-common.
  • Schema Aspect Migration: Refactored SchemaUtils.java to convert Apache Beam Schema objects into Dataplex technical schema aspects (represented as google.protobuf.Struct following the system-defined dataplex-types.global.schema format).
  • API Client Update:
    • Replaced all usages of the legacy DataCatalogClient with CatalogServiceClient inside DataCatalogSchemaUtils.java.
    • Migrated createEntryGroup to utilize createEntryGroupAsync as required by the Dataplex SDK for long-running operations.
  • Metadata Restoration: Preserved userSpecifiedSystem and userSpecifiedType logic by mapping them appropriately to the new Dataplex EntrySource object (system field and user_specified_type label).

@gemini-code-assist

Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request addresses a critical failure in the CDC pipeline caused by the deprecation of the legacy Google Cloud Data Catalog API. By migrating the schema publishing and retrieval logic to the Dataplex Knowledge Catalog API, the pipeline maintains compatibility with current Google Cloud infrastructure standards. The changes ensure that metadata, including system types and labels, is correctly preserved and mapped to the new Dataplex entry structures.

Highlights

  • API Migration: Migrated the CDC pipeline's schema management from the deprecated Google Cloud Data Catalog API to the new Dataplex Knowledge Catalog API.
  • Dependency Update: Replaced the google-cloud-datacatalog dependency with google-cloud-dataplex (v1.90.0) in the cdc-common module.
  • Schema Refactoring: Updated SchemaUtils to convert Apache Beam schemas into Dataplex technical schema aspects using protobuf Structs.
  • Asynchronous Operations: Refactored entry group creation to use asynchronous operations as required by the Dataplex SDK.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize the Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counterproductive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request migrates the CDC parent and connector modules from Google Cloud Data Catalog to Google Cloud Dataplex Catalog, updating dependencies, client initializations, and schema mapping utilities to use Dataplex's aspect-based schema model. The review feedback identifies several critical issues, including resource leaks from unclosed CatalogServiceClient instances, an N+1 query performance bottleneck when retrieving entry schemas, improper handling of InterruptedException, and potential NullPointerException risks when parsing protobuf Struct fields without defensive checks.

@stankiewicz stankiewicz added improvement Making existing code better bug-fix labels Jun 17, 2026

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request migrates the CDC common library from Google Cloud Data Catalog to Google Cloud Dataplex Catalog, updating dependencies, clients, and schema mapping utilities to use Dataplex aspects. Feedback on these changes suggests propagating exceptions during asynchronous entry group creation to avoid invalid states, filtering search results in lookupPubSubEntry to verify they belong to the @pubsub entry group, and normalizing data types to lowercase in SchemaUtils to ensure robust, case-insensitive type mapping.

@codecov

codecov Bot commented Jun 17, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 0% with 258 lines in your changes missing coverage. Please review.
✅ Project coverage is 55.58%. Comparing base (65d422a) to head (a0cb578).
⚠️ Report is 22 commits behind head on main.

Files with missing lines Patch % Lines
...ud/dataflow/cdc/common/DataCatalogSchemaUtils.java 0.00% 127 Missing ⚠️
.../google/cloud/dataflow/cdc/common/SchemaUtils.java 0.00% 94 Missing ⚠️
.../dataflow/cdc/applier/CdcPCollectionsFetchers.java 0.00% 34 Missing ⚠️
...google/cloud/dataflow/cdc/applier/PubsubUtils.java 0.00% 2 Missing ⚠️
...d/dataflow/cdc/connector/PubSubChangeConsumer.java 0.00% 1 Missing ⚠️

❌ Your patch check has failed because the patch coverage (0.00%) is below the target coverage (80.00%). You can increase the patch coverage or adjust the target coverage.

Additional details and impacted files
@@             Coverage Diff              @@
##               main    #3927      +/-   ##
============================================
- Coverage     55.59%   55.58%   -0.01%     
+ Complexity     7052     6731     -321     
============================================
  Files          1103     1116      +13     
  Lines         67681    68378     +697     
  Branches       7603     7707     +104     
============================================
+ Hits          37625    38008     +383     
- Misses        27636    27900     +264     
- Partials       2420     2470      +50     
Components Coverage Δ
spanner-templates 87.66% <ø> (-0.84%) ⬇️
spanner-import-export 68.70% <ø> (-0.01%) ⬇️
spanner-live-forward-migration 89.84% <ø> (-0.41%) ⬇️
spanner-live-reverse-replication 83.33% <ø> (-1.11%) ⬇️
spanner-bulk-migration 92.58% <ø> (-0.05%) ⬇️
gcs-spanner-dv 88.88% <ø> (-0.02%) ⬇️
Files with missing lines Coverage Δ
...d/dataflow/cdc/connector/PubSubChangeConsumer.java 0.00% <0.00%> (ø)
...google/cloud/dataflow/cdc/applier/PubsubUtils.java 0.00% <0.00%> (ø)
.../dataflow/cdc/applier/CdcPCollectionsFetchers.java 0.00% <0.00%> (ø)
.../google/cloud/dataflow/cdc/common/SchemaUtils.java 0.00% <0.00%> (ø)
...ud/dataflow/cdc/common/DataCatalogSchemaUtils.java 0.00% <0.00%> (ø)

... and 65 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@derrickaw

Copy link
Copy Markdown
Contributor

Fixes: #3921

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request migrates the CDC application from Google Cloud Data Catalog to Google Cloud Dataplex Catalog, updating dependencies, client implementations, and schema conversion utilities to use Dataplex aspects. The review feedback highlights several critical issues: a resource leak due to an unclosed CatalogServiceClient in DataCatalogSchemaManager, swallowed exceptions in getSchemasForEntryGroup and createEntryGroup that hinder debugging, a potential thread hang from calling .get() without a timeout, misleading error handling during JSON parsing, and a lack of string trimming when parsing comma-separated topics or subscriptions.

@stankiewicz

Copy link
Copy Markdown
Contributor Author

/gemini review

@stankiewicz stankiewicz requested a review from damccorm June 29, 2026 11:50

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request migrates the CDC schema management from Google Cloud Data Catalog to Google Cloud Dataplex, updating dependencies, client implementations, and schema conversion utilities to work with Dataplex Entry and EntryGroup APIs. Key feedback points include addressing a potential resource leak in PubsubUtils where SubscriptionAdminClient is repeatedly instantiated, optimizing getSchemasForEntryGroup by setting EntryView.ALL on the list request to avoid O(N) network roundtrips, and resolving a lossy integer type mapping in SchemaUtils that could cause runtime ClassCastExceptions.

Comment on lines 33 to 35
private static void setupSubscriptionClient() throws IOException {
subscriptionAdminClient = SubscriptionAdminClient.create();
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

Every time getPubSubTopicFromSubscription is called, setupSubscriptionClient() unconditionally instantiates a new SubscriptionAdminClient and overwrites the static variable subscriptionAdminClient without closing the previous one. This leaks the underlying gRPC channels and threads. Only instantiate the client if it is currently null.

  private static void setupSubscriptionClient() throws IOException {
    if (subscriptionAdminClient == null) {
      subscriptionAdminClient = SubscriptionAdminClient.create();
    }
  }

Comment on lines +106 to +117
com.google.cloud.dataplex.v1.ListEntriesRequest request =
com.google.cloud.dataplex.v1.ListEntriesRequest.newBuilder()
.setParent(formattedParent)
.build();
CatalogServiceClient.ListEntriesPagedResponse response = client.listEntries(request);
for (Entry entry : response.iterateAll()) {
entry =
client.getEntry(
GetEntryRequest.newBuilder()
.setName(entry.getName())
.setView(EntryView.ALL)
.build());

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

In getSchemasForEntryGroup, calling client.getEntry in a loop for every entry results in $O(N)$ network roundtrips, which can significantly slow down pipeline startup. By setting setView(EntryView.ALL) on the ListEntriesRequest, the returned entries will already contain all aspects, completely eliminating the need for individual getEntry calls.

Suggested change
com.google.cloud.dataplex.v1.ListEntriesRequest request =
com.google.cloud.dataplex.v1.ListEntriesRequest.newBuilder()
.setParent(formattedParent)
.build();
CatalogServiceClient.ListEntriesPagedResponse response = client.listEntries(request);
for (Entry entry : response.iterateAll()) {
entry =
client.getEntry(
GetEntryRequest.newBuilder()
.setName(entry.getName())
.setView(EntryView.ALL)
.build());
com.google.cloud.dataplex.v1.ListEntriesRequest request =
com.google.cloud.dataplex.v1.ListEntriesRequest.newBuilder()
.setParent(formattedParent)
.setView(EntryView.ALL)
.build();
CatalogServiceClient.ListEntriesPagedResponse response = client.listEntries(request);
for (Entry entry : response.iterateAll()) {

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.

invalid suggestion

@stankiewicz

Copy link
Copy Markdown
Contributor Author

@damccorm , IT tests are passing, which means that Debezium is able to persist schema and Dataflow template is able to read the schema.

it would be great to add to release notes some details about data catalog deprecation when new release is scheduled.

List<String> subscriptionList;

List<TopicSubscriptionSchema> readSourceSchemas =
buildTopicSubscriptionSchemas(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Is there a reason we're moving this out of PubSubUtils in this PR? It seems like we're mixing functional and non-functional changes, which makes it harder to review/understand what is happening, and I'd prefer to avoid that if possible.

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.

Ack, will move what is below to pubsubutils.


DebeziumToPubSubDataSender dataSender;
try {
TimeUnit.SECONDS.sleep(30);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why are we introducing a sleep here?

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.

It takes some time for dataplex to ingest data after pubsub topic create. Will remove it as final version is based on custom entrygroup, not pubsub resource.

pipelineOperator()
.waitForConditionsAndFinish(
createConfig(info),
createConfig(info, java.time.Duration.ofMinutes(5)),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Is there a reason for the short timeout?

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.

45 minutes didn't make sense and is bad experience in troubleshooting if you need to wait to test completion to see the logs.

"A problem occurred when communicating with Cloud Data Catalog");
"A problem occurred when communicating with Knowledge Catalog");
} else {
LOG.info("New entry {}", result);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Do we need this logging?


LookupEntryRequest request =
LookupEntryRequest.newBuilder().setLinkedResource(linkedResource).build();
public abstract static class DataCatalogSchemaManager implements AutoCloseable {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Should we still be naming things DataCatalog<thing>?

import org.slf4j.LoggerFactory;

/** Set of utilities to convert Beam Schemas to Data Catalog schemas. */
/** Set of utilities to convert Beam Schemas to Dataplex schema aspects. */

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Dataplex should be Knowledge Catalog (here and elsewhere)

@stankiewicz stankiewicz left a comment

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.

Will apply changes after 18th of July

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug-fix improvement Making existing code better size/XL

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants