diff --git a/.github/scripts/update_generation_config.sh b/.github/scripts/update_generation_config.sh index 24d97abee3..f448fafd7d 100644 --- a/.github/scripts/update_generation_config.sh +++ b/.github/scripts/update_generation_config.sh @@ -48,13 +48,14 @@ function update_config() { } # Update an action to a new version in GitHub action. +# the second argument must have the git tag (including "v"). function update_action() { local key_word=$1 local new_value=$2 local file=$3 echo "Update ${key_word} to ${new_value} in ${file}" # use a different delimiter because the key_word contains "/". - sed -i -e "s|${key_word}@v.*$|${key_word}@v${new_value}|" "${file}" + sed -i -e "s|${key_word}@[^ ]*$|${key_word}@${new_value}|" "${file}" } # The parameters of this script is: @@ -143,12 +144,16 @@ rm -rf tmp-googleapis update_config "googleapis_commitish" "${latest_commit}" "${generation_config}" # Update gapic-generator-java version to the latest -latest_version=$(get_latest_released_version "com.google.api" "gapic-generator-java") -update_config "gapic_generator_version" "${latest_version}" "${generation_config}" - -# Update composite action version to latest gapic-generator-java version +latest_gapic_generator_version=$(get_latest_released_version "com.google.api" "gapic-generator-java") +update_config "gapic_generator_version" "${latest_gapic_generator_version}" "${generation_config}" + +# Update the GitHub Actions reference to the latest. +# After the google-cloud-java monorepo migration of sdk-platform-java, +# we cannot rely on the gapic-generator-java version tag. Let's use +# the gapic-libraries-bom version +latest_gapic_libraries_bom_version=$(get_latest_released_version "com.google.cloud" "gapic-libraries-bom") update_action "googleapis/google-cloud-java/sdk-platform-java/.github/scripts" \ - "${latest_version}" \ + "v${latest_gapic_libraries_bom_version}" \ "${workflow}" # Update libraries-bom version to the latest diff --git a/.github/workflows/renovate_config_check.yaml b/.github/workflows/renovate_config_check.yaml index 47b9e87c98..8c922936b9 100644 --- a/.github/workflows/renovate_config_check.yaml +++ b/.github/workflows/renovate_config_check.yaml @@ -4,6 +4,7 @@ on: pull_request: paths: - 'renovate.json' + - '.github/workflows/renovate_config_check.yaml' jobs: renovate_bot_config_validation: @@ -18,8 +19,6 @@ jobs: with: node-version: '22' - - name: Install Renovate and Config Validator + - name: Run Renovate Config Validator run: | - npm install -g npm@latest - npm install --global renovate - renovate-config-validator + npx --package renovate@43.136.0 renovate-config-validator diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/admin/v2/models/ConsistencyRequest.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/admin/v2/models/ConsistencyRequest.java index f338776503..16e30acc96 100644 --- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/admin/v2/models/ConsistencyRequest.java +++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/admin/v2/models/ConsistencyRequest.java @@ -43,9 +43,11 @@ public abstract class ConsistencyRequest { @Nullable public abstract String getConsistencyToken(); + protected abstract boolean isFullyQualified(); + public static ConsistencyRequest forReplication(String tableId) { return new AutoValue_ConsistencyRequest( - tableId, CheckConsistencyRequest.ModeCase.STANDARD_READ_REMOTE_WRITES, null); + tableId, CheckConsistencyRequest.ModeCase.STANDARD_READ_REMOTE_WRITES, null, false); } /** @@ -59,20 +61,37 @@ public static ConsistencyRequest forReplication(String tableId, String consisten Preconditions.checkNotNull(consistencyToken, "consistencyToken must not be null"); return new AutoValue_ConsistencyRequest( - tableId, CheckConsistencyRequest.ModeCase.STANDARD_READ_REMOTE_WRITES, consistencyToken); + tableId, + CheckConsistencyRequest.ModeCase.STANDARD_READ_REMOTE_WRITES, + consistencyToken, + false); } public static ConsistencyRequest forDataBoost(String tableId) { return new AutoValue_ConsistencyRequest( - tableId, CheckConsistencyRequest.ModeCase.DATA_BOOST_READ_LOCAL_WRITES, null); + tableId, CheckConsistencyRequest.ModeCase.DATA_BOOST_READ_LOCAL_WRITES, null, false); } @InternalApi - public CheckConsistencyRequest toCheckConsistencyProto( - TableAdminRequestContext requestContext, String token) { + public static ConsistencyRequest forReplicationFromTableName(String tableName) { + return new AutoValue_ConsistencyRequest( + tableName, CheckConsistencyRequest.ModeCase.STANDARD_READ_REMOTE_WRITES, null, true); + } + + @InternalApi + public static ConsistencyRequest forReplicationFromTableName( + String tableName, String consistencyToken) { + Preconditions.checkNotNull(consistencyToken, "consistencyToken must not be null"); + + return new AutoValue_ConsistencyRequest( + tableName, + CheckConsistencyRequest.ModeCase.STANDARD_READ_REMOTE_WRITES, + consistencyToken, + true); + } + + private CheckConsistencyRequest.Builder buildBaseRequest(String name, String token) { CheckConsistencyRequest.Builder builder = CheckConsistencyRequest.newBuilder(); - TableName tableName = - TableName.of(requestContext.getProjectId(), requestContext.getInstanceId(), getTableId()); if (getMode().equals(CheckConsistencyRequest.ModeCase.STANDARD_READ_REMOTE_WRITES)) { builder.setStandardReadRemoteWrites(StandardReadRemoteWrites.newBuilder().build()); @@ -80,16 +99,68 @@ public CheckConsistencyRequest toCheckConsistencyProto( builder.setDataBoostReadLocalWrites(DataBoostReadLocalWrites.newBuilder().build()); } - return builder.setName(tableName.toString()).setConsistencyToken(token).build(); + return builder.setName(name).setConsistencyToken(token); + } + + /** + * Creates a CheckConsistencyRequest proto. This variant is used when the ConsistencyRequest was + * initialized with a short table ID, relying on the TableAdminRequestContext to construct the + * fully qualified table name. + */ + @InternalApi + public CheckConsistencyRequest toCheckConsistencyProto( + TableAdminRequestContext requestContext, String token) { + Preconditions.checkState( + !isFullyQualified(), + "Use toCheckConsistencyProto(String token) for fully qualified table names."); + TableName tableName = + TableName.of(requestContext.getProjectId(), requestContext.getInstanceId(), getTableId()); + + return buildBaseRequest(tableName.toString(), token).build(); } + /** + * Creates a CheckConsistencyRequest proto. This variant is used when the ConsistencyRequest was + * initialized with a fully qualified table name, eliminating the need for a request context. + */ + @InternalApi + public CheckConsistencyRequest toCheckConsistencyProto(String token) { + Preconditions.checkState( + isFullyQualified(), + "Use toCheckConsistencyProto(TableAdminRequestContext, String) for non-qualified table" + + " names."); + + return buildBaseRequest(getTableId(), token).build(); + } + + /** + * Creates a GenerateConsistencyTokenRequest proto. This variant is used when the + * ConsistencyRequest was initialized with a short table ID, relying on the + * TableAdminRequestContext to construct the fully qualified table name. + */ @InternalApi public GenerateConsistencyTokenRequest toGenerateTokenProto( TableAdminRequestContext requestContext) { + Preconditions.checkState( + !isFullyQualified(), "Use toGenerateTokenProto() for fully qualified table names."); GenerateConsistencyTokenRequest.Builder builder = GenerateConsistencyTokenRequest.newBuilder(); TableName tableName = TableName.of(requestContext.getProjectId(), requestContext.getInstanceId(), getTableId()); return builder.setName(tableName.toString()).build(); } + + /** + * Creates a GenerateConsistencyTokenRequest proto. This variant is used when the + * ConsistencyRequest was initialized with a fully qualified table name, eliminating the need for + * a request context. + */ + @InternalApi + public GenerateConsistencyTokenRequest toGenerateTokenProto() { + Preconditions.checkState( + isFullyQualified(), + "Use toGenerateTokenProto(TableAdminRequestContext) for non-qualified table names."); + GenerateConsistencyTokenRequest.Builder builder = GenerateConsistencyTokenRequest.newBuilder(); + return builder.setName(getTableId()).build(); + } } diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/admin/v2/stub/AwaitConsistencyCallable.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/admin/v2/stub/AwaitConsistencyCallable.java index b4e42e2354..a8ccdd9704 100644 --- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/admin/v2/stub/AwaitConsistencyCallable.java +++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/admin/v2/stub/AwaitConsistencyCallable.java @@ -42,6 +42,7 @@ import com.google.common.util.concurrent.MoreExecutors; import java.util.concurrent.Callable; import java.util.concurrent.CancellationException; +import javax.annotation.Nullable; /** * Callable that waits until either replication or Data Boost has caught up to the point it was @@ -56,7 +57,7 @@ class AwaitConsistencyCallable extends UnaryCallable { private final UnaryCallable checkCallable; private final RetryingExecutor executor; - private final TableAdminRequestContext requestContext; + @Nullable private final TableAdminRequestContext requestContext; static AwaitConsistencyCallable create( UnaryCallable @@ -64,7 +65,7 @@ static AwaitConsistencyCallable create( UnaryCallable checkCallable, ClientContext clientContext, RetrySettings pollingSettings, - TableAdminRequestContext requestContext) { + @Nullable TableAdminRequestContext requestContext) { RetryAlgorithm retryAlgorithm = new RetryAlgorithm<>( @@ -78,13 +79,22 @@ static AwaitConsistencyCallable create( generateCallable, checkCallable, retryingExecutor, requestContext); } + static AwaitConsistencyCallable create( + UnaryCallable + generateCallable, + UnaryCallable checkCallable, + ClientContext clientContext, + RetrySettings pollingSettings) { + return create(generateCallable, checkCallable, clientContext, pollingSettings, null); + } + @VisibleForTesting AwaitConsistencyCallable( UnaryCallable generateCallable, UnaryCallable checkCallable, RetryingExecutor executor, - TableAdminRequestContext requestContext) { + @Nullable TableAdminRequestContext requestContext) { this.generateCallable = generateCallable; this.checkCallable = checkCallable; this.executor = executor; @@ -98,13 +108,19 @@ public ApiFuture futureCall( // If the token is already provided, skip generation and poll directly. if (consistencyRequest.getConsistencyToken() != null) { CheckConsistencyRequest request = - consistencyRequest.toCheckConsistencyProto( - requestContext, consistencyRequest.getConsistencyToken()); + requestContext == null + ? consistencyRequest.toCheckConsistencyProto(consistencyRequest.getConsistencyToken()) + : consistencyRequest.toCheckConsistencyProto( + requestContext, consistencyRequest.getConsistencyToken()); return pollToken(request, apiCallContext); } ApiFuture tokenFuture = - generateToken(consistencyRequest.toGenerateTokenProto(requestContext), apiCallContext); + generateToken( + requestContext == null + ? consistencyRequest.toGenerateTokenProto() + : consistencyRequest.toGenerateTokenProto(requestContext), + apiCallContext); return ApiFutures.transformAsync( tokenFuture, @@ -112,8 +128,10 @@ public ApiFuture futureCall( @Override public ApiFuture apply(GenerateConsistencyTokenResponse input) { CheckConsistencyRequest request = - consistencyRequest.toCheckConsistencyProto( - requestContext, input.getConsistencyToken()); + requestContext == null + ? consistencyRequest.toCheckConsistencyProto(input.getConsistencyToken()) + : consistencyRequest.toCheckConsistencyProto( + requestContext, input.getConsistencyToken()); return pollToken(request, apiCallContext); } }, diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/admin/v2/stub/EnhancedBigtableTableAdminStub.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/admin/v2/stub/EnhancedBigtableTableAdminStub.java index e68cafca54..38fb42e293 100644 --- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/admin/v2/stub/EnhancedBigtableTableAdminStub.java +++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/admin/v2/stub/EnhancedBigtableTableAdminStub.java @@ -54,7 +54,7 @@ public class EnhancedBigtableTableAdminStub extends GrpcBigtableTableAdminStub { private final BigtableTableAdminStubSettings settings; private final ClientContext clientContext; - private final TableAdminRequestContext requestContext; + @javax.annotation.Nullable private final TableAdminRequestContext requestContext; @Deprecated private final AwaitReplicationCallable awaitReplicationCallable; @@ -62,6 +62,20 @@ public class EnhancedBigtableTableAdminStub extends GrpcBigtableTableAdminStub { private final OperationCallable optimizeRestoredTableOperationBaseCallable; + /** + * Creates an instance of {@link EnhancedBigtableTableAdminStub} using the provided settings. This + * variant is used by the V2 client stack which relies on fully qualified table names and + * therefore does not require a {@link TableAdminRequestContext}. + * + * @param settings The settings used to configure the stub. + * @return A new instance of {@code EnhancedBigtableTableAdminStub}. + * @throws IOException If there are errors creating the underlying client context. + */ + public static EnhancedBigtableTableAdminStub createEnhanced( + BigtableTableAdminStubSettings settings) throws IOException { + return new EnhancedBigtableTableAdminStub(settings, ClientContext.create(settings), null); + } + public static EnhancedBigtableTableAdminStub createEnhanced( BigtableTableAdminStubSettings settings, TableAdminRequestContext requestContext) throws IOException { @@ -72,7 +86,7 @@ public static EnhancedBigtableTableAdminStub createEnhanced( private EnhancedBigtableTableAdminStub( BigtableTableAdminStubSettings settings, ClientContext clientContext, - TableAdminRequestContext requestContext) + @javax.annotation.Nullable TableAdminRequestContext requestContext) throws IOException { super(settings, clientContext); diff --git a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/admin/v2/models/ConsistencyRequestTest.java b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/admin/v2/models/ConsistencyRequestTest.java index c3b99a4e68..9cfdb28170 100644 --- a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/admin/v2/models/ConsistencyRequestTest.java +++ b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/admin/v2/models/ConsistencyRequestTest.java @@ -97,4 +97,45 @@ public void testToCheckConsistencyProtoWithToken() { assertThat(checkConsistencyRequest.getModeCase()) .isEqualTo(CheckConsistencyRequest.ModeCase.STANDARD_READ_REMOTE_WRITES); } + + @Test + public void testToCheckConsistencyProtoFromTableName() { + String fullTableName = NameUtil.formatTableName(PROJECT_ID, INSTANCE_ID, TABLE_ID); + ConsistencyRequest consistencyRequest = + ConsistencyRequest.forReplicationFromTableName(fullTableName); + + CheckConsistencyRequest checkConsistencyRequest = + consistencyRequest.toCheckConsistencyProto(CONSISTENCY_TOKEN); + + assertThat(checkConsistencyRequest.getName()).isEqualTo(fullTableName); + assertThat(checkConsistencyRequest.getConsistencyToken()).isEqualTo(CONSISTENCY_TOKEN); + assertThat(checkConsistencyRequest.getModeCase()) + .isEqualTo(CheckConsistencyRequest.ModeCase.STANDARD_READ_REMOTE_WRITES); + } + + @Test + public void testToCheckConsistencyProtoFromTableNameWithToken() { + String fullTableName = NameUtil.formatTableName(PROJECT_ID, INSTANCE_ID, TABLE_ID); + ConsistencyRequest consistencyRequest = + ConsistencyRequest.forReplicationFromTableName(fullTableName, CONSISTENCY_TOKEN); + + CheckConsistencyRequest checkConsistencyRequest = + consistencyRequest.toCheckConsistencyProto(CONSISTENCY_TOKEN); + + assertThat(checkConsistencyRequest.getName()).isEqualTo(fullTableName); + assertThat(checkConsistencyRequest.getConsistencyToken()).isEqualTo(CONSISTENCY_TOKEN); + assertThat(checkConsistencyRequest.getModeCase()) + .isEqualTo(CheckConsistencyRequest.ModeCase.STANDARD_READ_REMOTE_WRITES); + } + + @Test + public void testToGenerateTokenProtoFromTableName() { + String fullTableName = NameUtil.formatTableName(PROJECT_ID, INSTANCE_ID, TABLE_ID); + ConsistencyRequest consistencyRequest = + ConsistencyRequest.forReplicationFromTableName(fullTableName); + + GenerateConsistencyTokenRequest generateRequest = consistencyRequest.toGenerateTokenProto(); + + assertThat(generateRequest.getName()).isEqualTo(fullTableName); + } }