From 4e4bab2b86ef613ec42b26a6019f39bb349212e8 Mon Sep 17 00:00:00 2001 From: elisheva-qlogic Date: Wed, 21 Nov 2018 14:38:38 -0500 Subject: [PATCH 1/7] readRow methods added with Query as argument --- .../bigtable/data/v2/BigtableDataClient.java | 81 ++++++++++++++++++- 1 file changed, 77 insertions(+), 4 deletions(-) diff --git a/google-cloud-clients/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/BigtableDataClient.java b/google-cloud-clients/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/BigtableDataClient.java index 6e9d085178b7..1696ce42d670 100644 --- a/google-cloud-clients/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/BigtableDataClient.java +++ b/google-cloud-clients/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/BigtableDataClient.java @@ -143,7 +143,7 @@ public static BigtableDataClient create(BigtableDataSettings settings) throws IO * *

Sample code: * - *

{code
+   * 
{@code
    * InstanceName instanceName = InstanceName.of("[PROJECT]", "[INSTANCE]");
    * try (BigtableDataClient bigtableDataClient = BigtableDataClient.create(instanceName)) {
    *   String tableId = "[TABLE]";
@@ -153,7 +153,8 @@ public static BigtableDataClient create(BigtableDataSettings settings) throws IO
    *   if(row != null) {
    *     System.out.println(row.getKey().toStringUtf8());
    *     for(RowCell cell : row.getCells()) {
-   *       System.out.println("Family: " + cell.getFamily() + "   Qualifier: " + cell.getQualifier().toStringUtf8() + "   Value: " + cell.getValue().toStringUtf8());
+   *        System.out.printf("Family: %s   Qualifier: %s   Value: %s", cell.getFamily(),
+   *           cell.getQualifier().toStringUtf8(), cell.getValue().toStringUtf8());
    *     }
    *   }
    * } catch(ApiException e) {
@@ -173,7 +174,7 @@ public Row readRow(String tableId, ByteString rowKey) {
    *
    * 

Sample code: * - *

{code
+   * 
{@code
    * InstanceName instanceName = InstanceName.of("[PROJECT]", "[INSTANCE]");
    * try (BigtableDataClient bigtableDataClient = BigtableDataClient.create(instanceName)) {
    *   String tableId = "[TABLE]";
@@ -183,7 +184,8 @@ public Row readRow(String tableId, ByteString rowKey) {
    *   if(row != null) {
    *     System.out.println(row.getKey().toStringUtf8());
    *      for(RowCell cell : row.getCells()) {
-   *        System.out.println("Family: " + cell.getFamily() + "   Qualifier: " + cell.getQualifier().toStringUtf8() + "   Value: " + cell.getValue().toStringUtf8());
+   *        System.out.printf("Family: %s   Qualifier: %s   Value: %s", cell.getFamily(),
+   *           cell.getQualifier().toStringUtf8(), cell.getValue().toStringUtf8());
    *      }
    *   }
    * } catch(ApiException e) {
@@ -197,6 +199,40 @@ public Row readRow(String tableId, String rowKey) {
     return ApiExceptions.callAndTranslateApiException(readRowAsync(tableId, rowKey));
   }
 
+  /**
+   * Convenience method for synchronously reading a single row. If the row does not exist, the
+   * value will be null.
+   *
+   * 

Sample code: + * + *

{@code
+   * InstanceName instanceName = InstanceName.of("[PROJECT]", "[INSTANCE]");
+   * try (BigtableDataClient bigtableDataClient = BigtableDataClient.create(instanceName)) {
+   *   String tableId = "[TABLE]";
+   *
+   * Query query = Query.create(tableId)
+   *         .rowKey("key");
+   *
+   *   Row row = bigtableDataClient.readRow(query);
+   *   // Do something with row, for example, display all cells
+   *   if(row != null) {
+   *     System.out.println(row.getKey().toStringUtf8());
+   *      for(RowCell cell : row.getCells()) {
+   *        System.out.printf("Family: %s   Qualifier: %s   Value: %s", cell.getFamily(),
+   *           cell.getQualifier().toStringUtf8(), cell.getValue().toStringUtf8());
+   *      }
+   *   }
+   * } catch(ApiException e) {
+   *   e.printStackTrace();
+   * }
+   * }
+ * + * @throws com.google.api.gax.rpc.ApiException when a serverside error occurs + */ + public Row ReadRow(Query query) { + return ApiExceptions.callAndTranslateApiException(readRowAsync(query)); + } + /** * Convenience method for asynchronously reading a single row. If the row does not exist, the * future's value will be null. @@ -265,6 +301,43 @@ public ApiFuture readRowAsync(String tableId, ByteString rowKey) { return readRowsCallable().first().futureCall(Query.create(tableId).rowKey(rowKey)); } + /** + * Convenience method for asynchronously reading a single row. If the row does not exist, the + * future's value will be null. + * + *

Sample code: + * + *

{@code
+   * InstanceName instanceName = InstanceName.of("[PROJECT]", "[INSTANCE]");
+   * try (BigtableDataClient bigtableDataClient = BigtableDataClient.create(instanceName)) {
+   *   String tableId = "[TABLE]";
+   *
+   *   Query query = Query.create(tableId)
+   *          .rowKey("key");
+   *
+   *   ApiFuture futureResult = bigtableDataClient.readRowAsync(query);
+   *
+   *   ApiFutures.addCallback(futureResult, new ApiFutureCallback() {
+   *     public void onFailure(Throwable t) {
+   *       if (t instanceof NotFoundException) {
+   *         System.out.println("Tried to read a non-existent table");
+   *       } else {
+   *         t.printStackTrace();
+   *       }
+   *     }
+   *     public void onSuccess(Row row) {
+   *       if (result != null) {
+   *          System.out.println("Got row: " + result);
+   *       }
+   *     }
+   *   }, MoreExecutors.directExecutor());
+   * }
+   * }
+ */ + public ApiFuture readRowAsync(Query query) { + return readRowsCallable().first().futureCall(query); + } + /** * Convenience method for synchronous streaming the results of a {@link Query}. * From cd171cb7d0ba2fc13f0e880019a123c72253b991 Mon Sep 17 00:00:00 2001 From: elisheva-qlogic Date: Wed, 21 Nov 2018 15:08:51 -0500 Subject: [PATCH 2/7] tests --- .../bigtable/data/v2/BigtableDataClient.java | 2 +- .../data/v2/BigtableDataClientTest.java | 42 +++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/google-cloud-clients/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/BigtableDataClient.java b/google-cloud-clients/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/BigtableDataClient.java index 1696ce42d670..1a8520795e61 100644 --- a/google-cloud-clients/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/BigtableDataClient.java +++ b/google-cloud-clients/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/BigtableDataClient.java @@ -229,7 +229,7 @@ public Row readRow(String tableId, String rowKey) { * * @throws com.google.api.gax.rpc.ApiException when a serverside error occurs */ - public Row ReadRow(Query query) { + public Row readRow(Query query) { return ApiExceptions.callAndTranslateApiException(readRowAsync(query)); } diff --git a/google-cloud-clients/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/BigtableDataClientTest.java b/google-cloud-clients/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/BigtableDataClientTest.java index 622c8f308263..7afca6ed929a 100644 --- a/google-cloud-clients/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/BigtableDataClientTest.java +++ b/google-cloud-clients/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/BigtableDataClientTest.java @@ -137,6 +137,25 @@ public void proxyReadRowStrAsyncTest() { .build()); } + @Test + public void readRowQueryAsyncTest() { + Query query = Query.create("fake-table").rowKey("fake-row-key"); + bigtableDataClient.readRowAsync(query); + ArgumentCaptor requestCaptor = ArgumentCaptor.forClass(Query.class); + Mockito.verify(mockReadRowsCallable.first()).futureCall(requestCaptor.capture()); + + RequestContext ctx = + RequestContext.create(InstanceName.of("fake-project", "fake-instance"), "fake-profile"); + // NOTE: limit(1) is added by the mocked first() call, so it's not tested here + assertThat(requestCaptor.getValue().toProto(ctx)) + .isEqualTo( + ReadRowsRequest.newBuilder() + .setTableName("projects/fake-project/instances/fake-instance/tables/fake-table") + .setAppProfileId("fake-profile") + .setRows(RowSet.newBuilder().addRowKeys(ByteString.copyFromUtf8("fake-row-key"))) + .build()); + } + @Test public void readRowTest() { Mockito.when(mockReadRowsCallable.first().futureCall(any(Query.class))) @@ -185,6 +204,29 @@ public void readRowStrTest() { .build()); } + @Test + public void readRowQueryTest() { + Query query = Query.create("fake-table").rowKey("fake-row-key"); + Mockito.when(mockReadRowsCallable.first().futureCall(any(Query.class))) + .thenReturn(ApiFutures.immediateFuture( + Row.create(ByteString.copyFromUtf8("fake-row-key"), Collections.emptyList()))); + bigtableDataClient.readRow(query); + + ArgumentCaptor requestCaptor = ArgumentCaptor.forClass(Query.class); + Mockito.verify(mockReadRowsCallable.first()).futureCall(requestCaptor.capture()); + + RequestContext ctx = + RequestContext.create(InstanceName.of("fake-project", "fake-instance"), "fake-profile"); + // NOTE: limit(1) is added by the mocked first() call, so it's not tested here + assertThat(requestCaptor.getValue().toProto(ctx)) + .isEqualTo( + ReadRowsRequest.newBuilder() + .setTableName("projects/fake-project/instances/fake-instance/tables/fake-table") + .setAppProfileId("fake-profile") + .setRows(RowSet.newBuilder().addRowKeys(ByteString.copyFromUtf8("fake-row-key"))) + .build()); + } + @Test public void proxyReadRowsSyncTest() { Query query = Query.create("fake-table"); From 5cf8142266c58a6f5f4c21e0425cb7e35dbdb25a Mon Sep 17 00:00:00 2001 From: elisheva-qlogic Date: Thu, 29 Nov 2018 16:10:07 -0500 Subject: [PATCH 3/7] readRow with filter as parameter --- .../bigtable/data/v2/BigtableDataClient.java | 104 ++++++++++++++++-- .../data/v2/BigtableDataClientTest.java | 92 ++++++++++++---- 2 files changed, 163 insertions(+), 33 deletions(-) diff --git a/google-cloud-clients/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/BigtableDataClient.java b/google-cloud-clients/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/BigtableDataClient.java index 1a8520795e61..90a6ae0a4fc9 100644 --- a/google-cloud-clients/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/BigtableDataClient.java +++ b/google-cloud-clients/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/BigtableDataClient.java @@ -24,9 +24,10 @@ import com.google.api.gax.rpc.ServerStreamingCallable; import com.google.api.gax.rpc.UnaryCallable; import com.google.cloud.bigtable.data.v2.models.BulkMutation; +import com.google.cloud.bigtable.data.v2.models.Filters.Filter; +import com.google.cloud.bigtable.data.v2.models.InstanceName; import com.google.cloud.bigtable.data.v2.models.BulkMutationBatcher; import com.google.cloud.bigtable.data.v2.models.ConditionalRowMutation; -import com.google.cloud.bigtable.data.v2.models.InstanceName; import com.google.cloud.bigtable.data.v2.models.KeyOffset; import com.google.cloud.bigtable.data.v2.models.Query; import com.google.cloud.bigtable.data.v2.models.ReadModifyWriteRow; @@ -37,6 +38,7 @@ import com.google.protobuf.ByteString; import java.io.IOException; import java.util.List; +import javax.annotation.Nullable; /** * Client for reading from and writing to existing Bigtable tables. @@ -210,10 +212,12 @@ public Row readRow(String tableId, String rowKey) { * try (BigtableDataClient bigtableDataClient = BigtableDataClient.create(instanceName)) { * String tableId = "[TABLE]"; * - * Query query = Query.create(tableId) - * .rowKey("key"); + * // Build the filter expression + * Filter filter = FILTERS.chain() + * .filter(FILTERS.qualifier().regex("prefix.*")) + * .filter(FILTERS.limit().cellsPerRow(10)); * - * Row row = bigtableDataClient.readRow(query); + * Row row = bigtableDataClient.readRow(tableId, "key", filter); * // Do something with row, for example, display all cells * if(row != null) { * System.out.println(row.getKey().toStringUtf8()); @@ -229,8 +233,44 @@ public Row readRow(String tableId, String rowKey) { * * @throws com.google.api.gax.rpc.ApiException when a serverside error occurs */ - public Row readRow(Query query) { - return ApiExceptions.callAndTranslateApiException(readRowAsync(query)); + public Row readRow(String tableId, String rowKey, @Nullable Filter filter) { + return readRow(tableId, ByteString.copyFromUtf8(rowKey), filter); + } + + /** + * Convenience method for synchronously reading a single row. If the row does not exist, the + * value will be null. + * + *

Sample code: + * + *

{@code
+   * InstanceName instanceName = InstanceName.of("[PROJECT]", "[INSTANCE]");
+   * try (BigtableDataClient bigtableDataClient = BigtableDataClient.create(instanceName)) {
+   *   String tableId = "[TABLE]";
+   *
+   *  // Build the filter expression
+   *  Filter filter = FILTERS.chain()
+   *         .filter(FILTERS.qualifier().regex("prefix.*"))
+   *         .filter(FILTERS.limit().cellsPerRow(10));
+   *
+   *   Row row = bigtableDataClient.readRow(tableId, ByteString.copyFromUtf8("key"), filter);
+   *   // Do something with row, for example, display all cells
+   *   if(row != null) {
+   *     System.out.println(row.getKey().toStringUtf8());
+   *      for(RowCell cell : row.getCells()) {
+   *        System.out.printf("Family: %s   Qualifier: %s   Value: %s", cell.getFamily(),
+   *           cell.getQualifier().toStringUtf8(), cell.getValue().toStringUtf8());
+   *      }
+   *   }
+   * } catch(ApiException e) {
+   *   e.printStackTrace();
+   * }
+   * }
+ * + * @throws com.google.api.gax.rpc.ApiException when a serverside error occurs + */ + public Row readRow(String tableId, ByteString rowKey, @Nullable Filter filter) { + return ApiExceptions.callAndTranslateApiException(readRowAsync(tableId, rowKey, filter)); } /** @@ -312,10 +352,12 @@ public ApiFuture readRowAsync(String tableId, ByteString rowKey) { * try (BigtableDataClient bigtableDataClient = BigtableDataClient.create(instanceName)) { * String tableId = "[TABLE]"; * - * Query query = Query.create(tableId) - * .rowKey("key"); + * // Build the filter expression + * Filters.Filter filter = FILTERS.chain() + * .filter(FILTERS.qualifier().regex("prefix.*")) + * .filter(FILTERS.limit().cellsPerRow(10)); * - * ApiFuture futureResult = bigtableDataClient.readRowAsync(query); + * ApiFuture futureResult = bigtableDataClient.readRowAsync(tableId, "key", filter); * * ApiFutures.addCallback(futureResult, new ApiFutureCallback() { * public void onFailure(Throwable t) { @@ -334,10 +376,50 @@ public ApiFuture readRowAsync(String tableId, ByteString rowKey) { * } * }
*/ - public ApiFuture readRowAsync(Query query) { - return readRowsCallable().first().futureCall(query); + public ApiFuture readRowAsync(String tableId, String rowKey, @Nullable Filter filter) { + return readRowAsync(tableId, ByteString.copyFromUtf8(rowKey), filter); } + /** + * Convenience method for asynchronously reading a single row. If the row does not exist, the + * future's value will be null. + * + *

Sample code: + * + *

{@code
+   * InstanceName instanceName = InstanceName.of("[PROJECT]", "[INSTANCE]");
+   * try (BigtableDataClient bigtableDataClient = BigtableDataClient.create(instanceName)) {
+   *   String tableId = "[TABLE]";
+   *
+   *  // Build the filter expression
+   *  Filters.Filter filter = FILTERS.chain()
+   *         .filter(FILTERS.qualifier().regex("prefix.*"))
+   *         .filter(FILTERS.limit().cellsPerRow(10));
+   *
+   *   ApiFuture futureResult = bigtableDataClient.readRowAsync(tableId, ByteString.copyFromUtf8("key"), filter);
+   *
+   *   ApiFutures.addCallback(futureResult, new ApiFutureCallback() {
+   *     public void onFailure(Throwable t) {
+   *       if (t instanceof NotFoundException) {
+   *         System.out.println("Tried to read a non-existent table");
+   *       } else {
+   *         t.printStackTrace();
+   *       }
+   *     }
+   *     public void onSuccess(Row row) {
+   *       if (result != null) {
+   *          System.out.println("Got row: " + result);
+   *       }
+   *     }
+   *   }, MoreExecutors.directExecutor());
+   * }
+   * }
+ */ + public ApiFuture readRowAsync(String tableId, ByteString rowKey, @Nullable Filter filter) { + return readRowsCallable().first().futureCall(Query.create(tableId).rowKey(rowKey).filter(filter)); + } + + /** * Convenience method for synchronous streaming the results of a {@link Query}. * diff --git a/google-cloud-clients/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/BigtableDataClientTest.java b/google-cloud-clients/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/BigtableDataClientTest.java index 7afca6ed929a..bff139800b2b 100644 --- a/google-cloud-clients/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/BigtableDataClientTest.java +++ b/google-cloud-clients/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/BigtableDataClientTest.java @@ -15,6 +15,7 @@ */ package com.google.cloud.bigtable.data.v2; +import static com.google.cloud.bigtable.data.v2.models.Filters.FILTERS; import static com.google.common.truth.Truth.assertThat; import static org.mockito.Matchers.any; @@ -33,6 +34,7 @@ import com.google.cloud.bigtable.data.v2.models.BulkMutationBatcher; import com.google.cloud.bigtable.data.v2.models.BulkMutationBatcher.BulkMutationFailure; import com.google.cloud.bigtable.data.v2.models.ConditionalRowMutation; +import com.google.cloud.bigtable.data.v2.models.Filters.Filter; import com.google.cloud.bigtable.data.v2.models.InstanceName; import com.google.cloud.bigtable.data.v2.models.KeyOffset; import com.google.cloud.bigtable.data.v2.models.Mutation; @@ -138,22 +140,43 @@ public void proxyReadRowStrAsyncTest() { } @Test - public void readRowQueryAsyncTest() { - Query query = Query.create("fake-table").rowKey("fake-row-key"); - bigtableDataClient.readRowAsync(query); + public void readRowFilterAsyncTest() { + // Build the filter expression + Filter filter = FILTERS.chain().filter(FILTERS.qualifier().regex("prefix.*")) + .filter(FILTERS.limit().cellsPerRow(10)); + bigtableDataClient.readRowAsync("fake-table", ByteString.copyFromUtf8("fake-row-key"), filter); ArgumentCaptor requestCaptor = ArgumentCaptor.forClass(Query.class); Mockito.verify(mockReadRowsCallable.first()).futureCall(requestCaptor.capture()); RequestContext ctx = RequestContext.create(InstanceName.of("fake-project", "fake-instance"), "fake-profile"); // NOTE: limit(1) is added by the mocked first() call, so it's not tested here - assertThat(requestCaptor.getValue().toProto(ctx)) - .isEqualTo( - ReadRowsRequest.newBuilder() - .setTableName("projects/fake-project/instances/fake-instance/tables/fake-table") - .setAppProfileId("fake-profile") - .setRows(RowSet.newBuilder().addRowKeys(ByteString.copyFromUtf8("fake-row-key"))) - .build()); + assertThat(requestCaptor.getValue().toProto(ctx)).isEqualTo(ReadRowsRequest.newBuilder() + .setTableName("projects/fake-project/instances/fake-instance/tables/fake-table") + .setAppProfileId("fake-profile") + .setRows(RowSet.newBuilder().addRowKeys(ByteString.copyFromUtf8("fake-row-key"))).setFilter( + FILTERS.chain().filter(FILTERS.qualifier().regex("prefix.*")) + .filter(FILTERS.limit().cellsPerRow(10)).toProto()).build()); + } + + @Test + public void readRowFilterStrAsyncTest() { + // Build the filter expression + Filter filter = FILTERS.chain().filter(FILTERS.qualifier().regex("prefix.*")) + .filter(FILTERS.limit().cellsPerRow(10)); + bigtableDataClient.readRowAsync("fake-table", "fake-row-key", filter); + ArgumentCaptor requestCaptor = ArgumentCaptor.forClass(Query.class); + Mockito.verify(mockReadRowsCallable.first()).futureCall(requestCaptor.capture()); + + RequestContext ctx = + RequestContext.create(InstanceName.of("fake-project", "fake-instance"), "fake-profile"); + // NOTE: limit(1) is added by the mocked first() call, so it's not tested here + assertThat(requestCaptor.getValue().toProto(ctx)).isEqualTo(ReadRowsRequest.newBuilder() + .setTableName("projects/fake-project/instances/fake-instance/tables/fake-table") + .setAppProfileId("fake-profile") + .setRows(RowSet.newBuilder().addRowKeys(ByteString.copyFromUtf8("fake-row-key"))).setFilter( + FILTERS.chain().filter(FILTERS.qualifier().regex("prefix.*")) + .filter(FILTERS.limit().cellsPerRow(10)).toProto()).build()); } @Test @@ -205,12 +228,14 @@ public void readRowStrTest() { } @Test - public void readRowQueryTest() { - Query query = Query.create("fake-table").rowKey("fake-row-key"); - Mockito.when(mockReadRowsCallable.first().futureCall(any(Query.class))) - .thenReturn(ApiFutures.immediateFuture( + public void readRowFilterTest() { + // Build the filter expression + Filter filter = FILTERS.chain().filter(FILTERS.qualifier().regex("prefix.*")) + .filter(FILTERS.limit().cellsPerRow(10)); + Mockito.when(mockReadRowsCallable.first().futureCall(any(Query.class))).thenReturn(ApiFutures + .immediateFuture( Row.create(ByteString.copyFromUtf8("fake-row-key"), Collections.emptyList()))); - bigtableDataClient.readRow(query); + bigtableDataClient.readRow("fake-table", ByteString.copyFromUtf8("fake-row-key"), filter); ArgumentCaptor requestCaptor = ArgumentCaptor.forClass(Query.class); Mockito.verify(mockReadRowsCallable.first()).futureCall(requestCaptor.capture()); @@ -218,13 +243,36 @@ public void readRowQueryTest() { RequestContext ctx = RequestContext.create(InstanceName.of("fake-project", "fake-instance"), "fake-profile"); // NOTE: limit(1) is added by the mocked first() call, so it's not tested here - assertThat(requestCaptor.getValue().toProto(ctx)) - .isEqualTo( - ReadRowsRequest.newBuilder() - .setTableName("projects/fake-project/instances/fake-instance/tables/fake-table") - .setAppProfileId("fake-profile") - .setRows(RowSet.newBuilder().addRowKeys(ByteString.copyFromUtf8("fake-row-key"))) - .build()); + assertThat(requestCaptor.getValue().toProto(ctx)).isEqualTo(ReadRowsRequest.newBuilder() + .setTableName("projects/fake-project/instances/fake-instance/tables/fake-table") + .setAppProfileId("fake-profile") + .setRows(RowSet.newBuilder().addRowKeys(ByteString.copyFromUtf8("fake-row-key"))).setFilter( + FILTERS.chain().filter(FILTERS.qualifier().regex("prefix.*")) + .filter(FILTERS.limit().cellsPerRow(10)).toProto()).build()); + } + + @Test + public void readRowStrFilterTest() { + // Build the filter expression + Filter filter = FILTERS.chain().filter(FILTERS.qualifier().regex("prefix.*")) + .filter(FILTERS.limit().cellsPerRow(10)); + Mockito.when(mockReadRowsCallable.first().futureCall(any(Query.class))).thenReturn(ApiFutures + .immediateFuture( + Row.create(ByteString.copyFromUtf8("fake-row-key"), Collections.emptyList()))); + bigtableDataClient.readRow("fake-table", "fake-row-key", filter); + + ArgumentCaptor requestCaptor = ArgumentCaptor.forClass(Query.class); + Mockito.verify(mockReadRowsCallable.first()).futureCall(requestCaptor.capture()); + + RequestContext ctx = + RequestContext.create(InstanceName.of("fake-project", "fake-instance"), "fake-profile"); + // NOTE: limit(1) is added by the mocked first() call, so it's not tested here + assertThat(requestCaptor.getValue().toProto(ctx)).isEqualTo(ReadRowsRequest.newBuilder() + .setTableName("projects/fake-project/instances/fake-instance/tables/fake-table") + .setAppProfileId("fake-profile") + .setRows(RowSet.newBuilder().addRowKeys(ByteString.copyFromUtf8("fake-row-key"))).setFilter( + FILTERS.chain().filter(FILTERS.qualifier().regex("prefix.*")) + .filter(FILTERS.limit().cellsPerRow(10)).toProto()).build()); } @Test From bcadd48df69205c74430847d88a623452d3874d1 Mon Sep 17 00:00:00 2001 From: elisheva-qlogic Date: Wed, 5 Dec 2018 11:20:12 -0500 Subject: [PATCH 4/7] code format fix --- .../bigtable/data/v2/BigtableDataClient.java | 17 +-- .../data/v2/BigtableDataClientTest.java | 120 ++++++++++++------ 2 files changed, 91 insertions(+), 46 deletions(-) diff --git a/google-cloud-clients/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/BigtableDataClient.java b/google-cloud-clients/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/BigtableDataClient.java index 90a6ae0a4fc9..f55ab9adc33a 100644 --- a/google-cloud-clients/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/BigtableDataClient.java +++ b/google-cloud-clients/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/BigtableDataClient.java @@ -24,10 +24,10 @@ import com.google.api.gax.rpc.ServerStreamingCallable; import com.google.api.gax.rpc.UnaryCallable; import com.google.cloud.bigtable.data.v2.models.BulkMutation; -import com.google.cloud.bigtable.data.v2.models.Filters.Filter; -import com.google.cloud.bigtable.data.v2.models.InstanceName; import com.google.cloud.bigtable.data.v2.models.BulkMutationBatcher; import com.google.cloud.bigtable.data.v2.models.ConditionalRowMutation; +import com.google.cloud.bigtable.data.v2.models.Filters.Filter; +import com.google.cloud.bigtable.data.v2.models.InstanceName; import com.google.cloud.bigtable.data.v2.models.KeyOffset; import com.google.cloud.bigtable.data.v2.models.Query; import com.google.cloud.bigtable.data.v2.models.ReadModifyWriteRow; @@ -202,8 +202,8 @@ public Row readRow(String tableId, String rowKey) { } /** - * Convenience method for synchronously reading a single row. If the row does not exist, the - * value will be null. + * Convenience method for synchronously reading a single row. If the row does not exist, the value + * will be null. * *

Sample code: * @@ -238,8 +238,8 @@ public Row readRow(String tableId, String rowKey, @Nullable Filter filter) { } /** - * Convenience method for synchronously reading a single row. If the row does not exist, the - * value will be null. + * Convenience method for synchronously reading a single row. If the row does not exist, the value + * will be null. * *

Sample code: * @@ -416,10 +416,11 @@ public ApiFuture readRowAsync(String tableId, String rowKey, @Nullable Filt * }

*/ public ApiFuture readRowAsync(String tableId, ByteString rowKey, @Nullable Filter filter) { - return readRowsCallable().first().futureCall(Query.create(tableId).rowKey(rowKey).filter(filter)); + return readRowsCallable() + .first() + .futureCall(Query.create(tableId).rowKey(rowKey).filter(filter)); } - /** * Convenience method for synchronous streaming the results of a {@link Query}. * diff --git a/google-cloud-clients/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/BigtableDataClientTest.java b/google-cloud-clients/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/BigtableDataClientTest.java index bff139800b2b..be6cb2b965c5 100644 --- a/google-cloud-clients/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/BigtableDataClientTest.java +++ b/google-cloud-clients/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/BigtableDataClientTest.java @@ -142,8 +142,11 @@ public void proxyReadRowStrAsyncTest() { @Test public void readRowFilterAsyncTest() { // Build the filter expression - Filter filter = FILTERS.chain().filter(FILTERS.qualifier().regex("prefix.*")) - .filter(FILTERS.limit().cellsPerRow(10)); + Filter filter = + FILTERS + .chain() + .filter(FILTERS.qualifier().regex("prefix.*")) + .filter(FILTERS.limit().cellsPerRow(10)); bigtableDataClient.readRowAsync("fake-table", ByteString.copyFromUtf8("fake-row-key"), filter); ArgumentCaptor requestCaptor = ArgumentCaptor.forClass(Query.class); Mockito.verify(mockReadRowsCallable.first()).futureCall(requestCaptor.capture()); @@ -151,19 +154,29 @@ public void readRowFilterAsyncTest() { RequestContext ctx = RequestContext.create(InstanceName.of("fake-project", "fake-instance"), "fake-profile"); // NOTE: limit(1) is added by the mocked first() call, so it's not tested here - assertThat(requestCaptor.getValue().toProto(ctx)).isEqualTo(ReadRowsRequest.newBuilder() - .setTableName("projects/fake-project/instances/fake-instance/tables/fake-table") - .setAppProfileId("fake-profile") - .setRows(RowSet.newBuilder().addRowKeys(ByteString.copyFromUtf8("fake-row-key"))).setFilter( - FILTERS.chain().filter(FILTERS.qualifier().regex("prefix.*")) - .filter(FILTERS.limit().cellsPerRow(10)).toProto()).build()); + assertThat(requestCaptor.getValue().toProto(ctx)) + .isEqualTo( + ReadRowsRequest.newBuilder() + .setTableName("projects/fake-project/instances/fake-instance/tables/fake-table") + .setAppProfileId("fake-profile") + .setRows(RowSet.newBuilder().addRowKeys(ByteString.copyFromUtf8("fake-row-key"))) + .setFilter( + FILTERS + .chain() + .filter(FILTERS.qualifier().regex("prefix.*")) + .filter(FILTERS.limit().cellsPerRow(10)) + .toProto()) + .build()); } @Test public void readRowFilterStrAsyncTest() { // Build the filter expression - Filter filter = FILTERS.chain().filter(FILTERS.qualifier().regex("prefix.*")) - .filter(FILTERS.limit().cellsPerRow(10)); + Filter filter = + FILTERS + .chain() + .filter(FILTERS.qualifier().regex("prefix.*")) + .filter(FILTERS.limit().cellsPerRow(10)); bigtableDataClient.readRowAsync("fake-table", "fake-row-key", filter); ArgumentCaptor requestCaptor = ArgumentCaptor.forClass(Query.class); Mockito.verify(mockReadRowsCallable.first()).futureCall(requestCaptor.capture()); @@ -171,12 +184,19 @@ public void readRowFilterStrAsyncTest() { RequestContext ctx = RequestContext.create(InstanceName.of("fake-project", "fake-instance"), "fake-profile"); // NOTE: limit(1) is added by the mocked first() call, so it's not tested here - assertThat(requestCaptor.getValue().toProto(ctx)).isEqualTo(ReadRowsRequest.newBuilder() - .setTableName("projects/fake-project/instances/fake-instance/tables/fake-table") - .setAppProfileId("fake-profile") - .setRows(RowSet.newBuilder().addRowKeys(ByteString.copyFromUtf8("fake-row-key"))).setFilter( - FILTERS.chain().filter(FILTERS.qualifier().regex("prefix.*")) - .filter(FILTERS.limit().cellsPerRow(10)).toProto()).build()); + assertThat(requestCaptor.getValue().toProto(ctx)) + .isEqualTo( + ReadRowsRequest.newBuilder() + .setTableName("projects/fake-project/instances/fake-instance/tables/fake-table") + .setAppProfileId("fake-profile") + .setRows(RowSet.newBuilder().addRowKeys(ByteString.copyFromUtf8("fake-row-key"))) + .setFilter( + FILTERS + .chain() + .filter(FILTERS.qualifier().regex("prefix.*")) + .filter(FILTERS.limit().cellsPerRow(10)) + .toProto()) + .build()); } @Test @@ -230,11 +250,16 @@ public void readRowStrTest() { @Test public void readRowFilterTest() { // Build the filter expression - Filter filter = FILTERS.chain().filter(FILTERS.qualifier().regex("prefix.*")) - .filter(FILTERS.limit().cellsPerRow(10)); - Mockito.when(mockReadRowsCallable.first().futureCall(any(Query.class))).thenReturn(ApiFutures - .immediateFuture( - Row.create(ByteString.copyFromUtf8("fake-row-key"), Collections.emptyList()))); + Filter filter = + FILTERS + .chain() + .filter(FILTERS.qualifier().regex("prefix.*")) + .filter(FILTERS.limit().cellsPerRow(10)); + Mockito.when(mockReadRowsCallable.first().futureCall(any(Query.class))) + .thenReturn( + ApiFutures.immediateFuture( + Row.create( + ByteString.copyFromUtf8("fake-row-key"), Collections.emptyList()))); bigtableDataClient.readRow("fake-table", ByteString.copyFromUtf8("fake-row-key"), filter); ArgumentCaptor requestCaptor = ArgumentCaptor.forClass(Query.class); @@ -243,22 +268,34 @@ public void readRowFilterTest() { RequestContext ctx = RequestContext.create(InstanceName.of("fake-project", "fake-instance"), "fake-profile"); // NOTE: limit(1) is added by the mocked first() call, so it's not tested here - assertThat(requestCaptor.getValue().toProto(ctx)).isEqualTo(ReadRowsRequest.newBuilder() - .setTableName("projects/fake-project/instances/fake-instance/tables/fake-table") - .setAppProfileId("fake-profile") - .setRows(RowSet.newBuilder().addRowKeys(ByteString.copyFromUtf8("fake-row-key"))).setFilter( - FILTERS.chain().filter(FILTERS.qualifier().regex("prefix.*")) - .filter(FILTERS.limit().cellsPerRow(10)).toProto()).build()); + assertThat(requestCaptor.getValue().toProto(ctx)) + .isEqualTo( + ReadRowsRequest.newBuilder() + .setTableName("projects/fake-project/instances/fake-instance/tables/fake-table") + .setAppProfileId("fake-profile") + .setRows(RowSet.newBuilder().addRowKeys(ByteString.copyFromUtf8("fake-row-key"))) + .setFilter( + FILTERS + .chain() + .filter(FILTERS.qualifier().regex("prefix.*")) + .filter(FILTERS.limit().cellsPerRow(10)) + .toProto()) + .build()); } @Test public void readRowStrFilterTest() { // Build the filter expression - Filter filter = FILTERS.chain().filter(FILTERS.qualifier().regex("prefix.*")) - .filter(FILTERS.limit().cellsPerRow(10)); - Mockito.when(mockReadRowsCallable.first().futureCall(any(Query.class))).thenReturn(ApiFutures - .immediateFuture( - Row.create(ByteString.copyFromUtf8("fake-row-key"), Collections.emptyList()))); + Filter filter = + FILTERS + .chain() + .filter(FILTERS.qualifier().regex("prefix.*")) + .filter(FILTERS.limit().cellsPerRow(10)); + Mockito.when(mockReadRowsCallable.first().futureCall(any(Query.class))) + .thenReturn( + ApiFutures.immediateFuture( + Row.create( + ByteString.copyFromUtf8("fake-row-key"), Collections.emptyList()))); bigtableDataClient.readRow("fake-table", "fake-row-key", filter); ArgumentCaptor requestCaptor = ArgumentCaptor.forClass(Query.class); @@ -267,12 +304,19 @@ public void readRowStrFilterTest() { RequestContext ctx = RequestContext.create(InstanceName.of("fake-project", "fake-instance"), "fake-profile"); // NOTE: limit(1) is added by the mocked first() call, so it's not tested here - assertThat(requestCaptor.getValue().toProto(ctx)).isEqualTo(ReadRowsRequest.newBuilder() - .setTableName("projects/fake-project/instances/fake-instance/tables/fake-table") - .setAppProfileId("fake-profile") - .setRows(RowSet.newBuilder().addRowKeys(ByteString.copyFromUtf8("fake-row-key"))).setFilter( - FILTERS.chain().filter(FILTERS.qualifier().regex("prefix.*")) - .filter(FILTERS.limit().cellsPerRow(10)).toProto()).build()); + assertThat(requestCaptor.getValue().toProto(ctx)) + .isEqualTo( + ReadRowsRequest.newBuilder() + .setTableName("projects/fake-project/instances/fake-instance/tables/fake-table") + .setAppProfileId("fake-profile") + .setRows(RowSet.newBuilder().addRowKeys(ByteString.copyFromUtf8("fake-row-key"))) + .setFilter( + FILTERS + .chain() + .filter(FILTERS.qualifier().regex("prefix.*")) + .filter(FILTERS.limit().cellsPerRow(10)) + .toProto()) + .build()); } @Test From a63ed12cf2bac66111d2c117223f460aed947b19 Mon Sep 17 00:00:00 2001 From: elisheva-qlogic Date: Fri, 7 Dec 2018 11:42:05 -0500 Subject: [PATCH 5/7] readRow methods null parameter --- .../bigtable/data/v2/BigtableDataClient.java | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/google-cloud-clients/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/BigtableDataClient.java b/google-cloud-clients/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/BigtableDataClient.java index f55ab9adc33a..902a24b9438b 100644 --- a/google-cloud-clients/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/BigtableDataClient.java +++ b/google-cloud-clients/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/BigtableDataClient.java @@ -167,7 +167,7 @@ public static BigtableDataClient create(BigtableDataSettings settings) throws IO * @throws com.google.api.gax.rpc.ApiException when a serverside error occurs */ public Row readRow(String tableId, ByteString rowKey) { - return ApiExceptions.callAndTranslateApiException(readRowAsync(tableId, rowKey)); + return ApiExceptions.callAndTranslateApiException(readRowAsync(tableId, rowKey, null)); } /** @@ -198,7 +198,8 @@ public Row readRow(String tableId, ByteString rowKey) { * @throws com.google.api.gax.rpc.ApiException when a serverside error occurs */ public Row readRow(String tableId, String rowKey) { - return ApiExceptions.callAndTranslateApiException(readRowAsync(tableId, rowKey)); + return ApiExceptions.callAndTranslateApiException( + readRowAsync(tableId, ByteString.copyFromUtf8(rowKey), null)); } /** @@ -234,7 +235,8 @@ public Row readRow(String tableId, String rowKey) { * @throws com.google.api.gax.rpc.ApiException when a serverside error occurs */ public Row readRow(String tableId, String rowKey, @Nullable Filter filter) { - return readRow(tableId, ByteString.copyFromUtf8(rowKey), filter); + return ApiExceptions.callAndTranslateApiException( + readRowAsync(tableId, ByteString.copyFromUtf8(rowKey), filter)); } /** @@ -304,7 +306,7 @@ public Row readRow(String tableId, ByteString rowKey, @Nullable Filter filter) { * }
*/ public ApiFuture readRowAsync(String tableId, String rowKey) { - return readRowAsync(tableId, ByteString.copyFromUtf8(rowKey)); + return readRowAsync(tableId, ByteString.copyFromUtf8(rowKey), null); } /** @@ -338,7 +340,7 @@ public ApiFuture readRowAsync(String tableId, String rowKey) { * }
*/ public ApiFuture readRowAsync(String tableId, ByteString rowKey) { - return readRowsCallable().first().futureCall(Query.create(tableId).rowKey(rowKey)); + return readRowAsync(tableId, rowKey, null); } /** @@ -416,9 +418,9 @@ public ApiFuture readRowAsync(String tableId, String rowKey, @Nullable Filt * } */ public ApiFuture readRowAsync(String tableId, ByteString rowKey, @Nullable Filter filter) { - return readRowsCallable() - .first() - .futureCall(Query.create(tableId).rowKey(rowKey).filter(filter)); + Query baseQuery = Query.create(tableId).rowKey(rowKey); + Query query = (filter != null) ? baseQuery.filter(filter) : baseQuery; + return readRowsCallable().first().futureCall(query); } /** From a96ee6d0255558376a83d433acfbe1538dba7cbb Mon Sep 17 00:00:00 2001 From: elisheva-qlogic Date: Mon, 10 Dec 2018 10:10:05 -0500 Subject: [PATCH 6/7] comment update --- .../com/google/cloud/bigtable/data/v2/BigtableDataClient.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/google-cloud-clients/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/BigtableDataClient.java b/google-cloud-clients/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/BigtableDataClient.java index 902a24b9438b..21a8d8936e0c 100644 --- a/google-cloud-clients/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/BigtableDataClient.java +++ b/google-cloud-clients/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/BigtableDataClient.java @@ -424,7 +424,7 @@ public ApiFuture readRowAsync(String tableId, ByteString rowKey, @Nullable } /** - * Convenience method for synchronous streaming the results of a {@link Query}. + * Convenience method for synchronously streaming the results of a {@link Query}. * *

Sample code: * @@ -462,7 +462,7 @@ public ServerStream readRows(Query query) { } /** - * Convenience method for asynchronous streaming the results of a {@link Query}. + * Convenience method for asynchronously streaming the results of a {@link Query}. * *

Sample code: * From d01618041556ee1bdf9e728d944c59b5e2b4f687 Mon Sep 17 00:00:00 2001 From: elisheva-qlogic Date: Mon, 10 Dec 2018 16:02:25 -0500 Subject: [PATCH 7/7] using if statement --- .../google/cloud/bigtable/data/v2/BigtableDataClient.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/google-cloud-clients/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/BigtableDataClient.java b/google-cloud-clients/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/BigtableDataClient.java index 21a8d8936e0c..d1061ac74d11 100644 --- a/google-cloud-clients/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/BigtableDataClient.java +++ b/google-cloud-clients/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/BigtableDataClient.java @@ -418,8 +418,10 @@ public ApiFuture readRowAsync(String tableId, String rowKey, @Nullable Filt * } */ public ApiFuture readRowAsync(String tableId, ByteString rowKey, @Nullable Filter filter) { - Query baseQuery = Query.create(tableId).rowKey(rowKey); - Query query = (filter != null) ? baseQuery.filter(filter) : baseQuery; + Query query = Query.create(tableId).rowKey(rowKey); + if (filter != null) { + query = query.filter(filter); + } return readRowsCallable().first().futureCall(query); }