-
Notifications
You must be signed in to change notification settings - Fork 1.1k
[Data Validation] Add table configuration #4188
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
aasthabharill
wants to merge
21
commits into
main
Choose a base branch
from
dv-table-config
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
21 commits
Select commit
Hold shift + click to select a range
8993921
initial working changes
aasthabharill fe4c7c4
draft 2
aasthabharill 6ad5f6a
testing
aasthabharill f3d9f70
clean
aasthabharill 81b0ab4
TableSelectionConfig
aasthabharill 95eb279
final changes
aasthabharill ce1ebfe
gemini-review
aasthabharill 4df885a
codecov
aasthabharill 8cafb62
it change
aasthabharill 5c07e13
it change
aasthabharill c323e79
it change
aasthabharill 8f0b959
json changes+rename
aasthabharill 6956647
remove readme changes
aasthabharill 9323e2f
terraform + rename
aasthabharill 9892048
final touches
aasthabharill b352d66
merge
aasthabharill a5a6f91
Merge branch 'main' into dv-table-config
aasthabharill f21411b
json changes + fix tests
aasthabharill b5d9828
merge
aasthabharill ccf36e8
Merge branch 'main' into dv-table-config
aasthabharill c004f0f
SourceReaderTransform change
aasthabharill File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
152 changes: 152 additions & 0 deletions
152
v2/gcs-spanner-dv/src/main/java/com/google/cloud/teleport/v2/config/TableConfiguration.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,152 @@ | ||
| /* | ||
| * Copyright (C) 2026 Google LLC | ||
| * | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); you may not | ||
| * use this file except in compliance with the License. You may obtain a copy of | ||
| * the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
| * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
| * License for the specific language governing permissions and limitations under | ||
| * the License. | ||
| */ | ||
| package com.google.cloud.teleport.v2.config; | ||
|
|
||
| import com.google.cloud.teleport.v2.options.GCSSpannerDVOptions; | ||
| import com.google.cloud.teleport.v2.spanner.migrations.schema.ISchemaMapper; | ||
| import com.google.gson.Gson; | ||
| import java.io.InputStream; | ||
| import java.io.Serializable; | ||
| import java.nio.channels.Channels; | ||
| import java.nio.charset.StandardCharsets; | ||
| import java.util.Collections; | ||
| import java.util.HashSet; | ||
| import java.util.NoSuchElementException; | ||
| import java.util.Set; | ||
| import org.apache.beam.sdk.io.FileSystems; | ||
| import org.apache.beam.sdk.io.fs.ResourceId; | ||
| import org.apache.commons.io.IOUtils; | ||
| import org.slf4j.Logger; | ||
| import org.slf4j.LoggerFactory; | ||
|
|
||
| /** | ||
| * Configuration class for table-based filtering in Data Validation pipeline. Encapsulates parsing, | ||
| * matching, and validation of source and Spanner tables. | ||
| */ | ||
| public class TableConfiguration implements Serializable { | ||
|
|
||
| private static final Logger LOG = LoggerFactory.getLogger(TableConfiguration.class); | ||
|
|
||
| private final Set<String> configuredSourceTables; | ||
|
|
||
| private TableConfiguration(Set<String> configuredSourceTables) { | ||
| this.configuredSourceTables = Collections.unmodifiableSet(configuredSourceTables); | ||
| } | ||
|
|
||
| /** Creates an empty configuration with no filters. Useful for testing. */ | ||
| public static TableConfiguration empty() { | ||
| return new TableConfiguration(new HashSet<>()); | ||
| } | ||
|
|
||
| /** | ||
| * Parses and validates table configuration from pipeline options. | ||
| * | ||
| * @param options The pipeline options. | ||
| * @return A TableConfiguration instance containing the configured source tables. | ||
| */ | ||
| public static TableConfiguration parseFromOptions(GCSSpannerDVOptions options) { | ||
| String tablesConfig = options.getTables(); | ||
| String tableConfigurationFilePath = options.getTableConfigurationFilePath(); | ||
| boolean hasTablesConfig = tablesConfig != null && !tablesConfig.trim().isEmpty(); | ||
| boolean hasTableConfigFile = | ||
| tableConfigurationFilePath != null && !tableConfigurationFilePath.trim().isEmpty(); | ||
|
|
||
| if (hasTablesConfig && hasTableConfigFile) { | ||
| throw new IllegalArgumentException( | ||
| "Both --tables and --tableConfigurationFilePath are provided. Please configure only one of these parameters at a time."); | ||
| } | ||
|
|
||
| Set<String> configuredTables = new HashSet<>(); | ||
|
|
||
| if (hasTablesConfig) { | ||
| for (String table : tablesConfig.split(",")) { | ||
| String trimmed = table.trim(); | ||
| if (!trimmed.isEmpty()) { | ||
| configuredTables.add(trimmed); | ||
| } | ||
| } | ||
| } else if (hasTableConfigFile) { | ||
| try { | ||
| ResourceId resourceId = FileSystems.matchNewResource(tableConfigurationFilePath, false); | ||
| try (InputStream stream = Channels.newInputStream(FileSystems.open(resourceId))) { | ||
| String result = IOUtils.toString(stream, StandardCharsets.UTF_8); | ||
| Gson gson = new Gson(); | ||
| TableConfigurationFile fileConfig = gson.fromJson(result, TableConfigurationFile.class); | ||
|
|
||
| if (fileConfig != null && fileConfig.getTableNames() != null) { | ||
| for (String table : fileConfig.getTableNames()) { | ||
| String trimmed = table.trim(); | ||
| if (!trimmed.isEmpty()) { | ||
| configuredTables.add(trimmed); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } catch (Exception e) { | ||
| throw new RuntimeException( | ||
| "Failed to read JSON tableConfigurationFilePath: " + tableConfigurationFilePath, e); | ||
| } | ||
| } | ||
|
|
||
| TableConfiguration config = new TableConfiguration(configuredTables); | ||
|
|
||
| return config; | ||
| } | ||
|
|
||
| public boolean hasFilters() { | ||
| return configuredSourceTables != null && !configuredSourceTables.isEmpty(); | ||
| } | ||
|
|
||
| public Set<String> getSourceTables() { | ||
| return configuredSourceTables; | ||
| } | ||
|
|
||
| /** | ||
| * Checks if a source table is allowed by the configuration. | ||
| * | ||
| * @param sourceTableName The source table name. | ||
| * @return true if allowed or no filters are configured, false otherwise. | ||
| */ | ||
| public boolean isSourceTableAllowed(String sourceTableName) { | ||
| if (!hasFilters()) { | ||
| return true; | ||
| } | ||
| return configuredSourceTables.contains(sourceTableName); | ||
| } | ||
|
|
||
| /** | ||
| * Checks if a Spanner table is allowed by the configuration. Translates the Spanner table name to | ||
| * its source table counterpart using the schema mapper. | ||
| * | ||
| * @param spannerTableName The Spanner table name. | ||
| * @param schemaMapper The schema mapper to translate the table name. | ||
| * @return true if allowed or no filters are configured, false otherwise. | ||
| */ | ||
| public boolean isSpannerTableAllowed(String spannerTableName, ISchemaMapper schemaMapper) { | ||
|
manitgupta marked this conversation as resolved.
|
||
| if (!hasFilters()) { | ||
| return true; | ||
| } | ||
| try { | ||
| String sourceTable = schemaMapper.getSourceTableName("", spannerTableName); | ||
| return configuredSourceTables.contains(sourceTable); | ||
|
aasthabharill marked this conversation as resolved.
|
||
| } catch (NoSuchElementException e) { | ||
| LOG.warn( | ||
| "Could not map Spanner table '{}' back to a source table. Skipping validation.", | ||
| spannerTableName); | ||
| return false; | ||
| } | ||
| } | ||
| } | ||
52 changes: 52 additions & 0 deletions
52
...-spanner-dv/src/main/java/com/google/cloud/teleport/v2/config/TableConfigurationFile.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| /* | ||
| * Copyright (C) 2026 Google LLC | ||
| * | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); you may not | ||
| * use this file except in compliance with the License. You may obtain a copy of | ||
| * the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
| * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
| * License for the specific language governing permissions and limitations under | ||
| * the License. | ||
| */ | ||
| package com.google.cloud.teleport.v2.config; | ||
|
|
||
| import java.io.Serializable; | ||
| import java.util.List; | ||
| import java.util.Map; | ||
|
|
||
| /** POJO representing the table configuration JSON file. */ | ||
| public class TableConfigurationFile implements Serializable { | ||
|
|
||
| private final List<String> tableNames; | ||
|
|
||
| /** | ||
| * Future Extensibility: Map of Source Table Name -> Table-specific configuration. | ||
| * | ||
| * <p>Note: The `tableNames` list remains the absolute source of truth for the exhaustive list of | ||
| * tables to be validated. This map is strictly for providing advanced configurations (e.g., | ||
| * column filtering, sampling) for a subset of those tables. Tables cannot be implicitly included | ||
| * for validation by solely appearing in this map; they MUST be explicitly listed in `tableNames`. | ||
| * | ||
| * <p>This is currently a placeholder and is not yet processed by the pipeline logic. | ||
| */ | ||
| private final Map<String, TableLevelConfig> optionalConfigurations; | ||
|
|
||
| public TableConfigurationFile( | ||
| List<String> tableNames, Map<String, TableLevelConfig> optionalConfigurations) { | ||
| this.tableNames = tableNames; | ||
| this.optionalConfigurations = optionalConfigurations; | ||
| } | ||
|
|
||
| public List<String> getTableNames() { | ||
| return tableNames; | ||
| } | ||
|
|
||
| public Map<String, TableLevelConfig> getOptionalConfigurations() { | ||
| return optionalConfigurations; | ||
| } | ||
| } |
34 changes: 34 additions & 0 deletions
34
v2/gcs-spanner-dv/src/main/java/com/google/cloud/teleport/v2/config/TableLevelConfig.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| /* | ||
| * Copyright (C) 2026 Google LLC | ||
| * | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); you may not | ||
| * use this file except in compliance with the License. You may obtain a copy of | ||
| * the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
| * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
| * License for the specific language governing permissions and limitations under | ||
| * the License. | ||
| */ | ||
| package com.google.cloud.teleport.v2.config; | ||
|
|
||
| import java.io.Serializable; | ||
|
|
||
| /** | ||
| * Placeholder POJO representing future advanced configurations for a specific table. | ||
| * | ||
| * <p>This is intended to support features like column-level validation or deterministic sampling in | ||
| * the future. | ||
| */ | ||
| public class TableLevelConfig implements Serializable { | ||
|
|
||
| // Intentionally left empty for now. | ||
| // | ||
| // Example future fields: | ||
| // private List<String> columnsToValidate; | ||
| // private SamplingConfig sampling; | ||
|
|
||
| } |
18 changes: 18 additions & 0 deletions
18
v2/gcs-spanner-dv/src/main/java/com/google/cloud/teleport/v2/config/package-info.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| /* | ||
| * Copyright (C) 2026 Google LLC | ||
| * | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); you may not | ||
| * use this file except in compliance with the License. You may obtain a copy of | ||
| * the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
| * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
| * License for the specific language governing permissions and limitations under | ||
| * the License. | ||
| */ | ||
|
|
||
| /** Configuration classes for Data Validation pipeline. */ | ||
| package com.google.cloud.teleport.v2.config; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.