diff --git a/google-cloud-bigtable/clirr-ignored-differences.xml b/google-cloud-bigtable/clirr-ignored-differences.xml
index 4052e1b4a7..83a97c27e8 100644
--- a/google-cloud-bigtable/clirr-ignored-differences.xml
+++ b/google-cloud-bigtable/clirr-ignored-differences.xml
@@ -308,4 +308,10 @@
See {@link com.google.cloud.bigtable.admin.v2.models.MaterializedView} for more details about + * an materialized view. + */ +@AutoValue +public abstract class MaterializedViewId implements TargetId { + /** Constructs a new MaterializedViewId object from the specified materializedViewId. */ + public static MaterializedViewId of(String materializedViewId) { + Preconditions.checkNotNull(materializedViewId, "materialized view id can't be null."); + return new AutoValue_MaterializedViewId(materializedViewId); + } + + abstract String getMaterializedViewId(); + + @Override + @InternalApi + public String toResourceName(String projectId, String instanceId) { + return NameUtil.formatMaterializedViewName(projectId, instanceId, getMaterializedViewId()); + } + + @Override + @InternalApi + public boolean scopedForAuthorizedView() { + return false; + } + + @Override + @InternalApi + public boolean scopedForMaterializedView() { + return true; + } +} diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/models/Query.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/models/Query.java index 1b4cb8d680..63ec9c1316 100644 --- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/models/Query.java +++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/models/Query.java @@ -62,6 +62,7 @@ public static Query create(String tableId) { * com.google.cloud.bigtable.data.v2.BigtableDataSettings}. * * @see AuthorizedViewId + * @see MaterializedViewId * @see TableId */ public static Query create(TargetId targetId) { @@ -317,7 +318,9 @@ public ByteStringRange getBound() { public ReadRowsRequest toProto(RequestContext requestContext) { String resourceName = targetId.toResourceName(requestContext.getProjectId(), requestContext.getInstanceId()); - if (targetId.scopedForAuthorizedView()) { + if (targetId.scopedForMaterializedView()) { + builder.setMaterializedViewName(resourceName); + } else if (targetId.scopedForAuthorizedView()) { builder.setAuthorizedViewName(resourceName); } else { builder.setTableName(resourceName); @@ -335,8 +338,10 @@ public static Query fromProto(@Nonnull ReadRowsRequest request) { Preconditions.checkArgument(request != null, "ReadRowsRequest must not be null"); String tableName = request.getTableName(); String authorizedViewName = request.getAuthorizedViewName(); + String materializedViewName = request.getMaterializedViewName(); - Query query = new Query(NameUtil.extractTargetId(tableName, authorizedViewName)); + Query query = + new Query(NameUtil.extractTargetId(tableName, authorizedViewName, materializedViewName)); query.builder = request.toBuilder(); return query; diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/models/SampleRowKeysRequest.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/models/SampleRowKeysRequest.java index 08d9a3ca23..d2a9dcb6a7 100644 --- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/models/SampleRowKeysRequest.java +++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/models/SampleRowKeysRequest.java @@ -44,7 +44,9 @@ public com.google.bigtable.v2.SampleRowKeysRequest toProto(RequestContext reques com.google.bigtable.v2.SampleRowKeysRequest.newBuilder(); String resourceName = targetId.toResourceName(requestContext.getProjectId(), requestContext.getInstanceId()); - if (targetId.scopedForAuthorizedView()) { + if (targetId.scopedForMaterializedView()) { + builder.setMaterializedViewName(resourceName); + } else if (targetId.scopedForAuthorizedView()) { builder.setAuthorizedViewName(resourceName); } else { builder.setTableName(resourceName); @@ -55,17 +57,19 @@ public com.google.bigtable.v2.SampleRowKeysRequest toProto(RequestContext reques /** * Wraps the protobuf {@link com.google.bigtable.v2.SampleRowKeysRequest}. * - *
WARNING: Please note that the project id & instance id in the table/authorized view name - * will be overwritten by the configuration in the BigtableDataClient. + *
WARNING: Please note that the project id & instance id in the table/authorized + * view/materialized view name will be overwritten by the configuration in the BigtableDataClient. */ @InternalApi public static SampleRowKeysRequest fromProto( @Nonnull com.google.bigtable.v2.SampleRowKeysRequest request) { String tableName = request.getTableName(); String authorizedViewName = request.getAuthorizedViewName(); + String materializedViewName = request.getMaterializedViewName(); SampleRowKeysRequest sampleRowKeysRequest = - SampleRowKeysRequest.create(NameUtil.extractTargetId(tableName, authorizedViewName)); + SampleRowKeysRequest.create( + NameUtil.extractTargetId(tableName, authorizedViewName, materializedViewName)); return sampleRowKeysRequest; } diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/models/TableId.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/models/TableId.java index 15b2cd9d95..1b19e75d69 100644 --- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/models/TableId.java +++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/models/TableId.java @@ -44,4 +44,10 @@ public String toResourceName(String projectId, String instanceId) { public boolean scopedForAuthorizedView() { return false; } + + @Override + @InternalApi + public boolean scopedForMaterializedView() { + return false; + } } diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/models/TargetId.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/models/TargetId.java index ae5be23598..73860dc1d8 100644 --- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/models/TargetId.java +++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/models/TargetId.java @@ -40,8 +40,15 @@ public interface TargetId extends Serializable { /** * Returns true if this TargetId object represents id for an authorized view (rather than a - * table). + * table/materialized view). */ @InternalApi boolean scopedForAuthorizedView(); + + /** + * Returns true if this TargetId object represents id for an materialized view (rather than a + * table/authorized view). + */ + @InternalApi + boolean scopedForMaterializedView(); } diff --git a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/admin/v2/internal/NameUtilTest.java b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/admin/v2/internal/NameUtilTest.java index 7622ce5dfa..b21aa463c2 100644 --- a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/admin/v2/internal/NameUtilTest.java +++ b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/admin/v2/internal/NameUtilTest.java @@ -18,6 +18,7 @@ import static com.google.common.truth.Truth.assertThat; import com.google.cloud.bigtable.data.v2.models.AuthorizedViewId; +import com.google.cloud.bigtable.data.v2.models.MaterializedViewId; import com.google.cloud.bigtable.data.v2.models.TableId; import org.junit.Rule; import org.junit.Test; @@ -102,23 +103,64 @@ public void extractTableNameFromAuthorizedViewNameTest() { } @Test - public void testExtractTargetId() { + public void testExtractTargetId2() { String testTableName = "projects/my-project/instances/my-instance/tables/my-table"; String testAuthorizedViewName = "projects/my-project/instances/my-instance/tables/my-table/authorizedViews/my-authorized-view"; assertThat( - com.google.cloud.bigtable.data.v2.internal.NameUtil.extractTargetId(testTableName, "")) + com.google.cloud.bigtable.data.v2.internal.NameUtil.extractTargetId( + testTableName, "", "")) .isEqualTo(TableId.of("my-table")); assertThat( com.google.cloud.bigtable.data.v2.internal.NameUtil.extractTargetId( - "", testAuthorizedViewName)) + "", testAuthorizedViewName, "")) .isEqualTo(AuthorizedViewId.of("my-table", "my-authorized-view")); + // No name is provided exception.expect(IllegalArgumentException.class); com.google.cloud.bigtable.data.v2.internal.NameUtil.extractTargetId("", ""); + // Multiple names are provided exception.expect(IllegalArgumentException.class); com.google.cloud.bigtable.data.v2.internal.NameUtil.extractTargetId( testTableName, testAuthorizedViewName); } + + @Test + public void testExtractTargetId3() { + String testTableName = "projects/my-project/instances/my-instance/tables/my-table"; + String testAuthorizedViewName = + "projects/my-project/instances/my-instance/tables/my-table/authorizedViews/my-authorized-view"; + String testMaterializedViewName = + "projects/my-project/instances/my-instance/materializedViews/my-materialized-view"; + assertThat( + com.google.cloud.bigtable.data.v2.internal.NameUtil.extractTargetId( + testTableName, "", "")) + .isEqualTo(TableId.of("my-table")); + assertThat( + com.google.cloud.bigtable.data.v2.internal.NameUtil.extractTargetId( + "", testAuthorizedViewName, "")) + .isEqualTo(AuthorizedViewId.of("my-table", "my-authorized-view")); + assertThat( + com.google.cloud.bigtable.data.v2.internal.NameUtil.extractTargetId( + "", "", testMaterializedViewName)) + .isEqualTo(MaterializedViewId.of("my-materialized-view")); + + // No name is provided + exception.expect(IllegalArgumentException.class); + com.google.cloud.bigtable.data.v2.internal.NameUtil.extractTargetId("", "", ""); + + // Multiple names are provided + exception.expect(IllegalArgumentException.class); + com.google.cloud.bigtable.data.v2.internal.NameUtil.extractTargetId( + testTableName, testAuthorizedViewName, ""); + + exception.expect(IllegalArgumentException.class); + com.google.cloud.bigtable.data.v2.internal.NameUtil.extractTargetId( + testTableName, "", testMaterializedViewName); + + exception.expect(IllegalArgumentException.class); + com.google.cloud.bigtable.data.v2.internal.NameUtil.extractTargetId( + "", testAuthorizedViewName, testMaterializedViewName); + } } diff --git a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/models/MaterializedViewIdTest.java b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/models/MaterializedViewIdTest.java new file mode 100644 index 0000000000..8978f8ff99 --- /dev/null +++ b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/models/MaterializedViewIdTest.java @@ -0,0 +1,68 @@ +/* + * Copyright 2024 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 + * + * https://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.bigtable.data.v2.models; + +import static com.google.common.truth.Truth.assertThat; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +@RunWith(JUnit4.class) +public class MaterializedViewIdTest { + private static final String PROJECT_ID = "my-project"; + private static final String INSTANCE_ID = "my-instance"; + private static final String TABLE_ID = "my-table"; + private static final String MATERIALIZED_VIEW_ID = "my-materialized-view"; + + @Test + public void testToResourceName() { + MaterializedViewId authorizedViewId = MaterializedViewId.of(MATERIALIZED_VIEW_ID); + + assertThat(authorizedViewId.toResourceName(PROJECT_ID, INSTANCE_ID)) + .isEqualTo( + "projects/my-project/instances/my-instance/materializedViews/my-materialized-view"); + } + + @Test + public void testEquality() { + MaterializedViewId authorizedViewId = MaterializedViewId.of(MATERIALIZED_VIEW_ID); + + assertThat(authorizedViewId).isEqualTo(MaterializedViewId.of(MATERIALIZED_VIEW_ID)); + assertThat(authorizedViewId).isNotEqualTo(MaterializedViewId.of("another-materialized-view")); + assertThat(authorizedViewId).isNotEqualTo(TableId.of(TABLE_ID)); + } + + @Test + public void testHashCode() { + MaterializedViewId authorizedViewId = MaterializedViewId.of(MATERIALIZED_VIEW_ID); + + assertThat(authorizedViewId.hashCode()) + .isEqualTo(MaterializedViewId.of(MATERIALIZED_VIEW_ID).hashCode()); + assertThat(authorizedViewId.hashCode()) + .isNotEqualTo(MaterializedViewId.of("another-materialized-view").hashCode()); + assertThat(authorizedViewId.hashCode()).isNotEqualTo(TableId.of(TABLE_ID).hashCode()); + } + + @Test + public void testToString() { + MaterializedViewId authorizedViewId = MaterializedViewId.of(MATERIALIZED_VIEW_ID); + + assertThat(authorizedViewId.toString()) + .isEqualTo("MaterializedViewId{materializedViewId=my-materialized-view}"); + } +}