From 3cefb4f3971d53546b554f9dc5a078179e8e52d3 Mon Sep 17 00:00:00 2001 From: Igor Bernstein Date: Thu, 6 Sep 2018 13:37:02 -0400 Subject: [PATCH] Bigtable: table model improvements (#3640) * Flatten cluster * expose column families as list only * use relative ids for tables & families --- .../admin/v2/models/ClusterState.java | 76 -------- .../admin/v2/models/ColumnFamily.java | 7 +- .../bigtable/admin/v2/models/GCRules.java | 4 +- .../cloud/bigtable/admin/v2/models/Table.java | 89 +++------ .../v2/it/BigtableTableAdminClientIT.java | 43 ++-- .../bigtable/admin/v2/models/TableTest.java | 183 +++--------------- 6 files changed, 90 insertions(+), 312 deletions(-) delete mode 100644 google-cloud-clients/google-cloud-bigtable-admin/src/main/java/com/google/cloud/bigtable/admin/v2/models/ClusterState.java diff --git a/google-cloud-clients/google-cloud-bigtable-admin/src/main/java/com/google/cloud/bigtable/admin/v2/models/ClusterState.java b/google-cloud-clients/google-cloud-bigtable-admin/src/main/java/com/google/cloud/bigtable/admin/v2/models/ClusterState.java deleted file mode 100644 index 674294771ef3..000000000000 --- a/google-cloud-clients/google-cloud-bigtable-admin/src/main/java/com/google/cloud/bigtable/admin/v2/models/ClusterState.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright 2018 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.admin.v2.models; - -import com.google.bigtable.admin.v2.Table.ClusterState.ReplicationState; -import com.google.common.base.MoreObjects; -import com.google.common.base.Objects; - -// TODO(igorbernstein2): remove this class and promote Replication State to Table. -/** Wrapper for {@link ClusterState} protocol buffer object */ -public final class ClusterState { - private final String id; - private final ReplicationState replicationState; - - public static ClusterState fromProto(String clusterId, com.google.bigtable.admin.v2.Table.ClusterState proto) { - return new ClusterState(clusterId, proto.getReplicationState()); - } - - private ClusterState(String id, ReplicationState replicationState) { - this.id = id; - this.replicationState = replicationState; - } - - /** - * Gets the cluster Id - */ - public String getId() { - return id; - } - - /** - * Gets the ReplicationState of this cluster - */ - public ReplicationState getReplicationState() { - return replicationState; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - ClusterState that = (ClusterState) o; - return Objects.equal(id, that.id) && - replicationState == that.replicationState; - } - - @Override - public int hashCode() { - return Objects.hashCode(id, replicationState); - } - - @Override - public String toString() { - return MoreObjects.toStringHelper(this) - .add("id", id) - .add("replicationState", replicationState) - .toString(); - } -} diff --git a/google-cloud-clients/google-cloud-bigtable-admin/src/main/java/com/google/cloud/bigtable/admin/v2/models/ColumnFamily.java b/google-cloud-clients/google-cloud-bigtable-admin/src/main/java/com/google/cloud/bigtable/admin/v2/models/ColumnFamily.java index bebe94d9a858..483668d15908 100644 --- a/google-cloud-clients/google-cloud-bigtable-admin/src/main/java/com/google/cloud/bigtable/admin/v2/models/ColumnFamily.java +++ b/google-cloud-clients/google-cloud-bigtable-admin/src/main/java/com/google/cloud/bigtable/admin/v2/models/ColumnFamily.java @@ -26,7 +26,6 @@ /** Wrapper for {@link ColumnFamily} protocol buffer object */ public final class ColumnFamily { - // TODO(igorbernstein2): rename this to `name` private final String id; private final GCRule rule; @@ -44,21 +43,21 @@ private ColumnFamily(String id, GCRule rule) { } /** - * Gets the columnfamily name + * Gets the column family's id. */ public String getId() { return id; } /** - * Get's the GCRule configured for the columnfamily + * Get's the GCRule configured for the column family. */ public GCRule getGCRule() { return rule; } /** - * Returns true if a GCRule has been configured for the family + * Returns true if a GCRule has been configured for the family. */ public boolean hasGCRule() { return !RuleCase.RULE_NOT_SET.equals(rule.toProto().getRuleCase()); diff --git a/google-cloud-clients/google-cloud-bigtable-admin/src/main/java/com/google/cloud/bigtable/admin/v2/models/GCRules.java b/google-cloud-clients/google-cloud-bigtable-admin/src/main/java/com/google/cloud/bigtable/admin/v2/models/GCRules.java index 5c80559991e5..e5d33ce54b30 100644 --- a/google-cloud-clients/google-cloud-bigtable-admin/src/main/java/com/google/cloud/bigtable/admin/v2/models/GCRules.java +++ b/google-cloud-clients/google-cloud-bigtable-admin/src/main/java/com/google/cloud/bigtable/admin/v2/models/GCRules.java @@ -277,7 +277,7 @@ public boolean equals(Object o) { return false; } VersionRule that = (VersionRule) o; - return Objects.equal(builder, that.builder); + return Objects.equal(builder.build(), that.builder.build()); } @Override @@ -324,7 +324,7 @@ public boolean equals(Object o) { return false; } DurationRule that = (DurationRule) o; - return Objects.equal(builder, that.builder); + return Objects.equal(builder.build(), that.builder.build()); } @Override diff --git a/google-cloud-clients/google-cloud-bigtable-admin/src/main/java/com/google/cloud/bigtable/admin/v2/models/Table.java b/google-cloud-clients/google-cloud-bigtable-admin/src/main/java/com/google/cloud/bigtable/admin/v2/models/Table.java index be1ee7408711..0a9733c32c51 100644 --- a/google-cloud-clients/google-cloud-bigtable-admin/src/main/java/com/google/cloud/bigtable/admin/v2/models/Table.java +++ b/google-cloud-clients/google-cloud-bigtable-admin/src/main/java/com/google/cloud/bigtable/admin/v2/models/Table.java @@ -16,86 +16,68 @@ package com.google.cloud.bigtable.admin.v2.models; import com.google.api.core.InternalApi; +import com.google.bigtable.admin.v2.Table.ClusterState.ReplicationState; import com.google.bigtable.admin.v2.TableName; -import com.google.common.base.MoreObjects; import com.google.common.base.Objects; +import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; -import java.util.Collection; +import java.util.List; import java.util.Map; import java.util.Map.Entry; import javax.annotation.Nonnull; /** Wrapper for {@link Table} protocol buffer object */ public final class Table { - private final TableName tableName; - // TODO(igorbernstein2): avoid duplication of id as keys and embedded in the models - private final Map clusterStates; - private final Map columnFamilies; + private final String id; + private final String instanceId; + private final Map replicationStatesByClusterId; + private final List columnFamilies; @InternalApi public static Table fromProto(@Nonnull com.google.bigtable.admin.v2.Table proto) { - ImmutableMap.Builder clusterStates = ImmutableMap.builder(); + ImmutableMap.Builder replicationStates = ImmutableMap.builder(); for (Entry entry : proto.getClusterStatesMap().entrySet()) { - clusterStates.put(entry.getKey(), ClusterState.fromProto(entry.getKey(), entry.getValue())); + replicationStates.put(entry.getKey(), entry.getValue().getReplicationState()); } - ImmutableMap.Builder columnFamilies = ImmutableMap.builder(); + ImmutableList.Builder columnFamilies = ImmutableList.builder(); for (Entry entry : proto.getColumnFamiliesMap().entrySet()) { - columnFamilies.put(entry.getKey(), ColumnFamily.fromProto(entry.getKey(), entry.getValue())); + columnFamilies.add(ColumnFamily.fromProto(entry.getKey(), entry.getValue())); } return new Table( TableName.parse(proto.getName()), - clusterStates.build(), + replicationStates.build(), columnFamilies.build()); } private Table(TableName tableName, - Map clusterStates, - Map columnFamilies) { - this.tableName = tableName; - this.clusterStates = clusterStates; + Map replicationStatesByClusterId, + List columnFamilies) { + this.instanceId = tableName.getInstance(); + this.id = tableName.getTable(); + this.replicationStatesByClusterId = replicationStatesByClusterId; this.columnFamilies = columnFamilies; } - /** - * Gets the unique name of the table in the format: - * projects/{project}/instances/{instance}/tables/{tableId} - */ - public TableName getTableName() { - return tableName; + /** Gets the table's id. */ + public String getId() { + return id; } - // TODO(igorbernstein2): don't expose the objects as both maps & lists - /** - * Returns state of the table by clusters in the instance as map of clusterId and {@link - * ClusterState} - */ - public Map getClusterStatesMap() { - return clusterStates; + /** Gets the id of the instance that owns this Table. */ + public String getInstanceId() { + return instanceId; } - /** - * Returns a map of columfamilies in the table keyed by columnfamily and name - */ - public Map getColumnFamiliesMap() { - return columnFamilies; - } - - /** - * Returns state of the table by clusters in the instance as a Collection - */ - public Collection getClusterStates() { - return clusterStates.values(); + public Map getReplicationStatesByClusterId() { + return replicationStatesByClusterId; } - /** - * Returns all columnfamilies in the table as a Collection - */ - public Collection getColumnFamiles() { - return columnFamilies.values(); + public List getColumnFamilies() { + return columnFamilies; } @Override @@ -107,22 +89,15 @@ public boolean equals(Object o) { return false; } Table table = (Table) o; - return Objects.equal(tableName, table.tableName) && - Objects.equal(clusterStates, table.clusterStates) && + return Objects.equal(id, table.id) && + Objects.equal(instanceId, table.instanceId) && + Objects + .equal(replicationStatesByClusterId, table.replicationStatesByClusterId) && Objects.equal(columnFamilies, table.columnFamilies); } @Override public int hashCode() { - return Objects.hashCode(tableName, clusterStates, columnFamilies); - } - - @Override - public String toString() { - return MoreObjects.toStringHelper(this) - .add("tableName", tableName) - .add("clusterStates", getClusterStates()) - .add("columnFamiles", getColumnFamiles()) - .toString(); + return Objects.hashCode(id, instanceId, replicationStatesByClusterId, columnFamilies); } } diff --git a/google-cloud-clients/google-cloud-bigtable-admin/src/test/java/com/google/cloud/bigtable/admin/v2/it/BigtableTableAdminClientIT.java b/google-cloud-clients/google-cloud-bigtable-admin/src/test/java/com/google/cloud/bigtable/admin/v2/it/BigtableTableAdminClientIT.java index c5c578aece41..63bc060bb1f6 100644 --- a/google-cloud-clients/google-cloud-bigtable-admin/src/test/java/com/google/cloud/bigtable/admin/v2/it/BigtableTableAdminClientIT.java +++ b/google-cloud-clients/google-cloud-bigtable-admin/src/test/java/com/google/cloud/bigtable/admin/v2/it/BigtableTableAdminClientIT.java @@ -24,6 +24,7 @@ import com.google.bigtable.admin.v2.InstanceName; import com.google.bigtable.admin.v2.TableName; import com.google.cloud.bigtable.admin.v2.BigtableTableAdminClient; +import com.google.cloud.bigtable.admin.v2.models.ColumnFamily; import com.google.cloud.bigtable.admin.v2.models.GCRules.DurationRule; import com.google.cloud.bigtable.admin.v2.models.GCRules.IntersectionRule; import com.google.cloud.bigtable.admin.v2.models.GCRules.UnionRule; @@ -32,9 +33,11 @@ import com.google.cloud.bigtable.admin.v2.models.ModifyColumnFamiliesRequest; import com.google.cloud.bigtable.admin.v2.models.ConsistencyToken; import com.google.cloud.bigtable.admin.v2.models.Table; +import com.google.common.collect.Maps; import com.google.protobuf.ByteString; import java.io.IOException; import java.util.List; +import java.util.Map; import org.junit.AfterClass; import org.junit.AssumptionViolatedException; import org.junit.Before; @@ -88,13 +91,18 @@ public void createTable() { try { Table tableResponse = tableAdmin.createTable(createTableReq); assertNotNull(tableResponse); - assertEquals(tableId, tableResponse.getTableName().getTable()); - assertEquals(2, tableResponse.getColumnFamiles().size()); - assertFalse(tableResponse.getColumnFamiliesMap().get("cf1").hasGCRule()); - assertTrue(tableResponse.getColumnFamiliesMap().get("cf2").hasGCRule()); + assertEquals(tableId, tableResponse.getId()); + + Map columnFamilyById = Maps.newHashMap(); + for (ColumnFamily columnFamily : tableResponse.getColumnFamilies()) { + columnFamilyById.put(columnFamily.getId(), columnFamily); + } + assertEquals(2, tableResponse.getColumnFamilies().size()); + assertFalse(columnFamilyById.get("cf1").hasGCRule()); + assertTrue(columnFamilyById.get("cf2").hasGCRule()); assertEquals( 10, - ((VersionRule) tableResponse.getColumnFamiliesMap().get("cf2").getGCRule()) + ((VersionRule) columnFamilyById.get("cf2").getGCRule()) .getMaxVersions()); } finally { tableAdmin.deleteTable(tableId); @@ -131,35 +139,40 @@ public void modifyFamilies() { try { tableAdmin.createTable(CreateTableRequest.of(tableId)); Table tableResponse = tableAdmin.modifyFamilies(modifyFamiliesReq); - assertEquals(5, tableResponse.getColumnFamiles().size()); - assertNotNull(tableResponse.getColumnFamiliesMap().get("mf1")); - assertNotNull(tableResponse.getColumnFamiliesMap().get("mf2")); + + Map columnFamilyById = Maps.newHashMap(); + for (ColumnFamily columnFamily : tableResponse.getColumnFamilies()) { + columnFamilyById.put(columnFamily.getId(), columnFamily); + } + assertEquals(5, columnFamilyById.size()); + assertNotNull(columnFamilyById.get("mf1")); + assertNotNull(columnFamilyById.get("mf2")); assertEquals( 2, - ((UnionRule) tableResponse.getColumnFamiliesMap().get("mf1").getGCRule()) + ((UnionRule) columnFamilyById.get("mf1").getGCRule()) .getRulesList() .size()); assertEquals( 1000, - ((DurationRule) tableResponse.getColumnFamiliesMap().get("mf2").getGCRule()) + ((DurationRule) columnFamilyById.get("mf2").getGCRule()) .getMaxAge() .getSeconds()); assertEquals( 20000, - ((DurationRule) tableResponse.getColumnFamiliesMap().get("mf2").getGCRule()) + ((DurationRule) columnFamilyById.get("mf2").getGCRule()) .getMaxAge() .getNano()); assertEquals( 2, - ((IntersectionRule) tableResponse.getColumnFamiliesMap().get("mf3").getGCRule()) + ((IntersectionRule) columnFamilyById.get("mf3").getGCRule()) .getRulesList() .size()); assertEquals( 360, - ((DurationRule) tableResponse.getColumnFamiliesMap().get("mf4").getGCRule()) + ((DurationRule) columnFamilyById.get("mf4").getGCRule()) .getMaxAge() .getSeconds()); - assertNotNull(tableResponse.getColumnFamiliesMap().get("mf7")); + assertNotNull(columnFamilyById.get("mf7")); } finally { tableAdmin.deleteTable(tableId); } @@ -180,7 +193,7 @@ public void getTable() { tableAdmin.createTable(CreateTableRequest.of(tableId)); Table tableResponse = tableAdmin.getTable(tableId); assertNotNull(tableResponse); - assertEquals(tableId, tableResponse.getTableName().getTable()); + assertEquals(tableId, tableResponse.getId()); } finally { tableAdmin.deleteTable(tableId); } diff --git a/google-cloud-clients/google-cloud-bigtable-admin/src/test/java/com/google/cloud/bigtable/admin/v2/models/TableTest.java b/google-cloud-clients/google-cloud-bigtable-admin/src/test/java/com/google/cloud/bigtable/admin/v2/models/TableTest.java index b2f33b073a1c..3ebe004f51d4 100644 --- a/google-cloud-clients/google-cloud-bigtable-admin/src/test/java/com/google/cloud/bigtable/admin/v2/models/TableTest.java +++ b/google-cloud-clients/google-cloud-bigtable-admin/src/test/java/com/google/cloud/bigtable/admin/v2/models/TableTest.java @@ -15,42 +15,33 @@ */ package com.google.cloud.bigtable.admin.v2.models; -import static org.junit.Assert.*; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; -import org.threeten.bp.Duration; import com.google.bigtable.admin.v2.ColumnFamily; import com.google.bigtable.admin.v2.GcRule; import com.google.bigtable.admin.v2.Table.ClusterState; import com.google.bigtable.admin.v2.Table.ClusterState.ReplicationState; import com.google.bigtable.admin.v2.Table.TimestampGranularity; import com.google.bigtable.admin.v2.TableName; -import com.google.cloud.bigtable.admin.v2.models.GCRules.DurationRule; -import com.google.cloud.bigtable.admin.v2.models.GCRules.IntersectionRule; -import com.google.cloud.bigtable.admin.v2.models.GCRules.UnionRule; -import com.google.cloud.bigtable.admin.v2.models.GCRules.VersionRule; -import com.google.bigtable.admin.v2.GcRule.Intersection; -import com.google.bigtable.admin.v2.GcRule.Union; -import com.google.bigtable.admin.v2.GenerateConsistencyTokenResponse; -import static com.google.cloud.bigtable.admin.v2.models.GCRules.GCRULES; -import static com.google.common.truth.Truth.assertThat; +import com.google.common.truth.Truth; +import java.util.Map.Entry; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; @RunWith(JUnit4.class) public class TableTest { @Test - public void convertTable() { - TableName testName = TableName.of("p", "i", "testTable"); - com.google.bigtable.admin.v2.Table table = + public void testFromProto() { + TableName testName = TableName.of("my-project", "my-instance", "my-table"); + com.google.bigtable.admin.v2.Table proto = com.google.bigtable.admin.v2.Table.newBuilder() .setName(testName.toString()) .setGranularity(TimestampGranularity.MILLIS) .putClusterStates( - "test", + "cluster1", ClusterState.newBuilder().setReplicationState(ReplicationState.READY).build()) .putClusterStates( - "prod", + "cluster2", ClusterState.newBuilder() .setReplicationState(ReplicationState.INITIALIZING) .build()) @@ -72,144 +63,20 @@ public void convertTable() { .build()) .build(); - Table tableResponse = Table.fromProto(table); - assertNotNull(tableResponse); - assertEquals(testName, tableResponse.getTableName()); - assertEquals(2, tableResponse.getClusterStates().size()); - assertEquals( - ReplicationState.READY, - tableResponse.getClusterStatesMap().get("test").getReplicationState()); - assertEquals( - ReplicationState.INITIALIZING, - tableResponse.getClusterStatesMap().get("prod").getReplicationState()); - assertEquals(3, tableResponse.getColumnFamiles().size()); - assertNotNull("cf1", tableResponse.getColumnFamiliesMap().get("cf1").getId()); - assertFalse(tableResponse.getColumnFamiliesMap().get("cf1").hasGCRule()); - - assertThat(GCRULES.defaultRule().toProto()) - .isEqualTo(tableResponse.getColumnFamiliesMap().get("cf1").getGCRule().toProto()); - assertThat(GCRULES.maxVersions(1).toProto()) - .isEqualTo(tableResponse.getColumnFamiliesMap().get("cf2").getGCRule().toProto()); - assertThat(GCRULES.maxAge(Duration.ofSeconds(1, 99)).toProto()) - .isEqualTo(tableResponse.getColumnFamiliesMap().get("cf3").getGCRule().toProto()); - } - - @Test - public void convertTableUnionOfIntersections() { - GcRule expected = - GcRule.newBuilder() - .setUnion( - Union.newBuilder() - .addRules( - GcRule.newBuilder() - .setIntersection( - Intersection.newBuilder() - .addRules(GCRulesTest.buildVersionsRule(1)) - .addRules(GCRulesTest.buildAgeRule(1, 0)))) - .addRules( - GcRule.newBuilder() - .setIntersection( - Intersection.newBuilder() - .addRules(GCRulesTest.buildVersionsRule(1)) - .addRules(GCRulesTest.buildAgeRule(1, 0))))) - .build(); - - GcRule actual = - GCRULES - .union() - .rule( - GCRULES - .intersection() - .rule(GCRULES.maxVersions(1)) - .rule(GCRULES.maxAge(Duration.ofSeconds(1)))) - .rule( - GCRULES - .intersection() - .rule(GCRULES.maxVersions(1)) - .rule(GCRULES.maxAge(Duration.ofSeconds(1)))) - .toProto(); - - com.google.bigtable.admin.v2.Table table = - com.google.bigtable.admin.v2.Table.newBuilder() - .putColumnFamilies("cf3", ColumnFamily.newBuilder().setGcRule(expected).build()) - .build(); - - Table tableResponse = Table.fromProto(table); - assertThat(actual) - .isEqualTo(tableResponse.getColumnFamiliesMap().get("cf3").getGCRule().toProto()); - assertTrue(tableResponse.getColumnFamiliesMap().get("cf3").hasGCRule()); - - UnionRule parentUnion = - ((UnionRule) tableResponse.getColumnFamiliesMap().get("cf3").getGCRule()); - assertEquals(2, parentUnion.getRulesList().size()); - - IntersectionRule intersectionRule = ((IntersectionRule) parentUnion.getRulesList().get(0)); - assertEquals(2, intersectionRule.getRulesList().size()); - assertEquals(1, ((VersionRule) intersectionRule.getRulesList().get(0)).getMaxVersions()); - assertEquals( - Duration.ofSeconds(1, 0), - ((DurationRule) intersectionRule.getRulesList().get(1)).getMaxAge()); - - intersectionRule = ((IntersectionRule) parentUnion.getRulesList().get(1)); - assertEquals(2, intersectionRule.getRulesList().size()); - assertEquals(1, ((VersionRule) intersectionRule.getRulesList().get(0)).getMaxVersions()); - assertEquals( - Duration.ofSeconds(1, 0), - ((DurationRule) intersectionRule.getRulesList().get(1)).getMaxAge()); - } - - @Test - public void convertTableIntersectionOfUnions() { - GcRule actual = - GcRule.newBuilder() - .setIntersection( - Intersection.newBuilder() - .addRules( - GcRule.newBuilder() - .setUnion( - Union.newBuilder() - .addRules(GCRulesTest.buildVersionsRule(1)) - .addRules(GCRulesTest.buildAgeRule(1, 0)))) - .addRules( - GcRule.newBuilder() - .setUnion( - Union.newBuilder() - .addRules(GCRulesTest.buildVersionsRule(1)) - .addRules(GCRulesTest.buildAgeRule(1, 0))))) - .build(); - - GcRule expected = - GCRULES - .intersection() - .rule( - GCRULES - .union() - .rule(GCRULES.maxVersions(1)) - .rule(GCRULES.maxAge(Duration.ofSeconds(1)))) - .rule( - GCRULES - .union() - .rule(GCRULES.maxVersions(1)) - .rule(GCRULES.maxAge(Duration.ofSeconds(1)))) - .toProto(); - - com.google.bigtable.admin.v2.Table table = - com.google.bigtable.admin.v2.Table.newBuilder() - .putColumnFamilies("cf3", ColumnFamily.newBuilder().setGcRule(expected).build()) - .build(); - - Table tableResponse = Table.fromProto(table); - assertThat(actual) - .isEqualTo(tableResponse.getColumnFamiliesMap().get("cf3").getGCRule().toProto()); - } - - @Test - public void convertTableEmpty() { - Table tableResponse = - Table.fromProto(com.google.bigtable.admin.v2.Table.newBuilder().build()); - - assertNotNull(tableResponse); - assertEquals(0, tableResponse.getClusterStates().size()); - assertEquals(0, tableResponse.getColumnFamiles().size()); + Table result = Table.fromProto(proto); + + Truth.assertThat(result.getInstanceId()).isEqualTo("my-instance"); + Truth.assertThat(result.getId()).isEqualTo("my-table"); + Truth.assertThat(result.getReplicationStatesByClusterId()).containsExactly( + "cluster1", ReplicationState.READY, + "cluster2", ReplicationState.INITIALIZING + ); + Truth.assertThat(result.getColumnFamilies()).hasSize(3); + + for (Entry entry : proto.getColumnFamiliesMap().entrySet()) { + Truth.assertThat(result.getColumnFamilies()).contains( + com.google.cloud.bigtable.admin.v2.models.ColumnFamily.fromProto(entry.getKey(), entry.getValue()) + ); + } } }