diff --git a/bigtable/snippets/pom.xml b/bigtable/snippets/pom.xml index 9b603e26fcc..e035cadc183 100644 --- a/bigtable/snippets/pom.xml +++ b/bigtable/snippets/pom.xml @@ -37,6 +37,12 @@ 4.13-beta-3 test + + com.google.truth + truth + 1.0 + test + com.google.cloud diff --git a/bigtable/snippets/src/main/java/com/example/bigtable/Filters.java b/bigtable/snippets/src/main/java/com/example/bigtable/Filters.java new file mode 100644 index 00000000000..93367eeace7 --- /dev/null +++ b/bigtable/snippets/src/main/java/com/example/bigtable/Filters.java @@ -0,0 +1,459 @@ +/* + * Copyright 2019 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.bigtable; + +import static com.google.cloud.bigtable.data.v2.models.Filters.FILTERS; +// [START bigtable_filters_limit_row_sample] +// [START bigtable_filters_limit_row_regex] +// [START bigtable_filters_limit_cells_per_col] +// [START bigtable_filters_limit_cells_per_row] +// [START bigtable_filters_limit_cells_per_row_offset] +// [START bigtable_filters_limit_col_family_regex] +// [START bigtable_filters_limit_col_qualifier_regex] +// [START bigtable_filters_limit_col_range] +// [START bigtable_filters_limit_value_range] +// [START bigtable_filters_limit_value_regex] +// [START bigtable_filters_limit_timestamp_range] +// [START bigtable_filters_limit_block_all] +// [START bigtable_filters_limit_pass_all] +// [START bigtable_filters_modify_strip_value] +// [START bigtable_filters_modify_apply_label] +// [START bigtable_filters_composing_chain] +// [START bigtable_filters_composing_interleave] +// [START bigtable_filters_composing_condition] +import com.google.api.gax.rpc.ServerStream; +import com.google.cloud.bigtable.data.v2.BigtableDataClient; +import com.google.cloud.bigtable.data.v2.models.Filters.Filter; +import com.google.cloud.bigtable.data.v2.models.Query; +import com.google.cloud.bigtable.data.v2.models.Row; +import com.google.cloud.bigtable.data.v2.models.RowCell; +import java.io.IOException; +import java.time.Instant; +import java.time.temporal.ChronoUnit; + +public class Filters { + // [END bigtable_filters_limit_row_sample] + // [END bigtable_filters_limit_row_regex] + // [END bigtable_filters_limit_cells_per_col] + // [END bigtable_filters_limit_cells_per_row] + // [END bigtable_filters_limit_cells_per_row_offset] + // [END bigtable_filters_limit_col_family_regex] + // [END bigtable_filters_limit_col_qualifier_regex] + // [END bigtable_filters_limit_col_range] + // [END bigtable_filters_limit_value_range] + // [END bigtable_filters_limit_value_regex] + // [END bigtable_filters_limit_timestamp_range] + // [END bigtable_filters_limit_block_all] + // [END bigtable_filters_limit_pass_all] + // [END bigtable_filters_modify_strip_value] + // [END bigtable_filters_modify_apply_label] + // [END bigtable_filters_composing_chain] + // [END bigtable_filters_composing_interleave] + // [END bigtable_filters_composing_condition] + + // [START bigtable_filters_limit_row_sample] + public static void filterLimitRowSample() { + // TODO(developer): Replace these variables before running the sample. + String projectId = "my-project-id"; + String instanceId = "my-instance-id"; + String tableId = "mobile-time-series"; + filterLimitRowSample(projectId, instanceId, tableId); + } + + public static void filterLimitRowSample(String projectId, String instanceId, String tableId) { + // A filter that matches cells from a row with probability .5 + Filter filter = FILTERS.key().sample(.5); + readFilter(projectId, instanceId, tableId, filter); + } + // [END bigtable_filters_limit_row_sample] + + // [START bigtable_filters_limit_row_regex] + public static void filterLimitRowRegex() { + // TODO(developer): Replace these variables before running the sample. + String projectId = "my-project-id"; + String instanceId = "my-instance-id"; + String tableId = "mobile-time-series"; + filterLimitRowRegex(projectId, instanceId, tableId); + } + + public static void filterLimitRowRegex(String projectId, String instanceId, String tableId) { + // A filter that matches cells from rows whose keys satisfy the given regex + Filter filter = FILTERS.key().regex(".*#20190501$"); + readFilter(projectId, instanceId, tableId, filter); + } + // [END bigtable_filters_limit_row_regex] + + // [START bigtable_filters_limit_cells_per_col] + public static void filterLimitCellsPerCol() { + // TODO(developer): Replace these variables before running the sample. + String projectId = "my-project-id"; + String instanceId = "my-instance-id"; + String tableId = "mobile-time-series"; + filterLimitCellsPerCol(projectId, instanceId, tableId); + } + + public static void filterLimitCellsPerCol(String projectId, String instanceId, String tableId) { + // A filter that matches only the most recent 2 cells within each column + Filter filter = FILTERS.limit().cellsPerColumn(2); + readFilter(projectId, instanceId, tableId, filter); + } + // [END bigtable_filters_limit_cells_per_col] + + // [START bigtable_filters_limit_cells_per_row] + public static void filterLimitCellsPerRow() { + // TODO(developer): Replace these variables before running the sample. + String projectId = "my-project-id"; + String instanceId = "my-instance-id"; + String tableId = "mobile-time-series"; + filterLimitCellsPerRow(projectId, instanceId, tableId); + } + + public static void filterLimitCellsPerRow(String projectId, String instanceId, String tableId) { + // A filter that matches the first 2 cells of each row + Filter filter = FILTERS.limit().cellsPerRow(2); + readFilter(projectId, instanceId, tableId, filter); + } + // [END bigtable_filters_limit_cells_per_row] + + // [START bigtable_filters_limit_cells_per_row_offset] + public static void filterLimitCellsPerRowOffset() { + // TODO(developer): Replace these variables before running the sample. + String projectId = "my-project-id"; + String instanceId = "my-instance-id"; + String tableId = "mobile-time-series"; + filterLimitCellsPerRowOffset(projectId, instanceId, tableId); + } + + public static void filterLimitCellsPerRowOffset( + String projectId, String instanceId, String tableId) { + // A filter that skips the first 2 cells per row + Filter filter = FILTERS.offset().cellsPerRow(2); + readFilter(projectId, instanceId, tableId, filter); + } + // [END bigtable_filters_limit_cells_per_row_offset] + + // [START bigtable_filters_limit_col_family_regex] + public static void filterLimitColFamilyRegex() { + // TODO(developer): Replace these variables before running the sample. + String projectId = "my-project-id"; + String instanceId = "my-instance-id"; + String tableId = "mobile-time-series"; + filterLimitColFamilyRegex(projectId, instanceId, tableId); + } + + public static void filterLimitColFamilyRegex( + String projectId, String instanceId, String tableId) { + // A filter that matches cells whose column family satisfies the given regex + Filter filter = FILTERS.family().regex("stats_.*$"); + readFilter(projectId, instanceId, tableId, filter); + } + // [END bigtable_filters_limit_col_family_regex] + + // [START bigtable_filters_limit_col_qualifier_regex] + public static void filterLimitColQualifierRegex() { + // TODO(developer): Replace these variables before running the sample. + String projectId = "my-project-id"; + String instanceId = "my-instance-id"; + String tableId = "mobile-time-series"; + filterLimitColQualifierRegex(projectId, instanceId, tableId); + } + + public static void filterLimitColQualifierRegex( + String projectId, String instanceId, String tableId) { + // A filter that matches cells whose column qualifier satisfies the given regex + Filter filter = FILTERS.qualifier().regex("connected_.*$"); + readFilter(projectId, instanceId, tableId, filter); + } + // [END bigtable_filters_limit_col_qualifier_regex] + + // [START bigtable_filters_limit_col_range] + public static void filterLimitColRange() { + // TODO(developer): Replace these variables before running the sample. + String projectId = "my-project-id"; + String instanceId = "my-instance-id"; + String tableId = "mobile-time-series"; + filterLimitColRange(projectId, instanceId, tableId); + } + + public static void filterLimitColRange(String projectId, String instanceId, String tableId) { + // A filter that matches cells whose column qualifiers are between data_plan_01gb and + // data_plan_10gb in the column family cell_plan + Filter filter = + FILTERS + .qualifier() + .rangeWithinFamily("cell_plan") + .startClosed("data_plan_01gb") + .endOpen("data_plan_10gb"); + readFilter(projectId, instanceId, tableId, filter); + } + // [END bigtable_filters_limit_col_range] + + // [START bigtable_filters_limit_value_range] + public static void filterLimitValueRange() { + // TODO(developer): Replace these variables before running the sample. + String projectId = "my-project-id"; + String instanceId = "my-instance-id"; + String tableId = "mobile-time-series"; + filterLimitValueRange(projectId, instanceId, tableId); + } + + public static void filterLimitValueRange(String projectId, String instanceId, String tableId) { + // A filter that matches cells whose values are between the given values + Filter filter = FILTERS.value().range().startClosed("PQ2A.190405").endClosed("PQ2A.190406"); + readFilter(projectId, instanceId, tableId, filter); + } + // [END bigtable_filters_limit_value_range] + + // [START bigtable_filters_limit_value_regex] + public static void filterLimitValueRegex() { + // TODO(developer): Replace these variables before running the sample. + String projectId = "my-project-id"; + String instanceId = "my-instance-id"; + String tableId = "mobile-time-series"; + filterLimitValueRegex(projectId, instanceId, tableId); + } + + public static void filterLimitValueRegex(String projectId, String instanceId, String tableId) { + // A filter that matches cells whose value satisfies the given regex + Filter filter = FILTERS.value().regex("PQ2A.*$"); + readFilter(projectId, instanceId, tableId, filter); + } + // [END bigtable_filters_limit_value_regex] + + // [START bigtable_filters_limit_timestamp_range] + public static void filterLimitTimestampRange() { + // TODO(developer): Replace these variables before running the sample. + String projectId = "my-project-id"; + String instanceId = "my-instance-id"; + String tableId = "mobile-time-series"; + filterLimitTimestampRange(projectId, instanceId, tableId); + } + + public static void filterLimitTimestampRange( + String projectId, String instanceId, String tableId) { + // Get a time representing one hour ago + long timestamp = Instant.now().minus(1, ChronoUnit.HOURS).toEpochMilli() * 1000; + + // A filter that matches cells whose timestamp is from an hour ago or earlier + Filter filter = FILTERS.timestamp().range().startClosed(0L).endOpen(timestamp); + readFilter(projectId, instanceId, tableId, filter); + } + // [END bigtable_filters_limit_timestamp_range] + + // [START bigtable_filters_limit_block_all] + public static void filterLimitBlockAll() { + // TODO(developer): Replace these variables before running the sample. + String projectId = "my-project-id"; + String instanceId = "my-instance-id"; + String tableId = "mobile-time-series"; + filterLimitBlockAll(projectId, instanceId, tableId); + } + + public static void filterLimitBlockAll(String projectId, String instanceId, String tableId) { + // A filter that does not match any cells + Filter filter = FILTERS.block(); + readFilter(projectId, instanceId, tableId, filter); + } + // [END bigtable_filters_limit_block_all] + + // [START bigtable_filters_limit_pass_all] + public static void filterLimitPassAll() { + // TODO(developer): Replace these variables before running the sample. + String projectId = "my-project-id"; + String instanceId = "my-instance-id"; + String tableId = "mobile-time-series"; + filterLimitPassAll(projectId, instanceId, tableId); + } + + public static void filterLimitPassAll(String projectId, String instanceId, String tableId) { + // A filter that matches all cells + Filter filter = FILTERS.pass(); + readFilter(projectId, instanceId, tableId, filter); + } + // [END bigtable_filters_limit_pass_all] + + // [START bigtable_filters_modify_strip_value] + public static void filterModifyStripValue() { + // TODO(developer): Replace these variables before running the sample. + String projectId = "my-project-id"; + String instanceId = "my-instance-id"; + String tableId = "mobile-time-series"; + filterModifyStripValue(projectId, instanceId, tableId); + } + + public static void filterModifyStripValue(String projectId, String instanceId, String tableId) { + // A filter that replaces the outputted cell value with the empty string + Filter filter = FILTERS.value().strip(); + readFilter(projectId, instanceId, tableId, filter); + } + // [END bigtable_filters_modify_strip_value] + + // [START bigtable_filters_modify_apply_label] + public static void filterModifyApplyLabel() { + // TODO(developer): Replace these variables before running the sample. + String projectId = "my-project-id"; + String instanceId = "my-instance-id"; + String tableId = "mobile-time-series"; + filterModifyApplyLabel(projectId, instanceId, tableId); + } + + public static void filterModifyApplyLabel(String projectId, String instanceId, String tableId) { + // A filter that applies the given label to the outputted cell + Filter filter = FILTERS.label("labelled"); + readFilter(projectId, instanceId, tableId, filter); + } + // [END bigtable_filters_modify_apply_label] + + // [START bigtable_filters_composing_chain] + public static void filterComposingChain() { + // TODO(developer): Replace these variables before running the sample. + String projectId = "my-project-id"; + String instanceId = "my-instance-id"; + String tableId = "mobile-time-series"; + filterComposingChain(projectId, instanceId, tableId); + } + + public static void filterComposingChain(String projectId, String instanceId, String tableId) { + // A filter that selects one cell per column AND within the column family cell_plan + Filter filter = + FILTERS + .chain() + .filter(FILTERS.limit().cellsPerColumn(1)) + .filter(FILTERS.family().exactMatch("cell_plan")); + readFilter(projectId, instanceId, tableId, filter); + } + // [END bigtable_filters_composing_chain] + + // [START bigtable_filters_composing_interleave] + public static void filterComposingInterleave() { + // TODO(developer): Replace these variables before running the sample. + String projectId = "my-project-id"; + String instanceId = "my-instance-id"; + String tableId = "mobile-time-series"; + filterComposingInterleave(projectId, instanceId, tableId); + } + + public static void filterComposingInterleave( + String projectId, String instanceId, String tableId) { + // A filter that matches cells with the value true OR with the column qualifier os_build + Filter filter = + FILTERS + .interleave() + .filter(FILTERS.value().exactMatch("true")) + .filter(FILTERS.qualifier().exactMatch("os_build")); + readFilter(projectId, instanceId, tableId, filter); + } + // [END bigtable_filters_composing_interleave] + + // [START bigtable_filters_composing_condition] + public static void filterComposingCondition() { + // TODO(developer): Replace these variables before running the sample. + String projectId = "my-project-id"; + String instanceId = "my-instance-id"; + String tableId = "mobile-time-series"; + filterComposingCondition(projectId, instanceId, tableId); + } + + public static void filterComposingCondition(String projectId, String instanceId, String tableId) { + // A filter that applies the label passed-filter IF the cell has the column qualifier + // data_plan_10gb AND the value true, OTHERWISE applies the label filtered-out + Filter filter = + FILTERS + .condition( + FILTERS + .chain() + .filter(FILTERS.qualifier().exactMatch("data_plan_10gb")) + .filter(FILTERS.value().exactMatch("true"))) + .then(FILTERS.label("passed-filter")) + .otherwise(FILTERS.label("filtered-out")); + readFilter(projectId, instanceId, tableId, filter); + } + // [END bigtable_filters_composing_condition] + + // [START bigtable_filters_limit_row_sample] + // [START bigtable_filters_limit_row_regex] + // [START bigtable_filters_limit_cells_per_col] + // [START bigtable_filters_limit_cells_per_row] + // [START bigtable_filters_limit_cells_per_row_offset] + // [START bigtable_filters_limit_col_family_regex] + // [START bigtable_filters_limit_col_qualifier_regex] + // [START bigtable_filters_limit_col_range] + // [START bigtable_filters_limit_value_range] + // [START bigtable_filters_limit_value_regex] + // [START bigtable_filters_limit_timestamp_range] + // [START bigtable_filters_limit_block_all] + // [START bigtable_filters_limit_pass_all] + // [START bigtable_filters_modify_strip_value] + // [START bigtable_filters_modify_apply_label] + // [START bigtable_filters_composing_chain] + // [START bigtable_filters_composing_interleave] + // [START bigtable_filters_composing_condition] + private static void readFilter( + String projectId, String instanceId, String tableId, Filter filter) { + // Initialize client that will be used to send requests. This client only needs to be created + // once, and can be reused for multiple requests. After completing all of your requests, call + // the "close" method on the client to safely clean up any remaining background resources. + try (BigtableDataClient dataClient = BigtableDataClient.create(projectId, instanceId)) { + Query query = Query.create(tableId).filter(filter); + ServerStream rows = dataClient.readRows(query); + for (Row row : rows) { + printRow(row); + } + } catch (IOException e) { + System.out.println( + "Unable to intailize service client, as a network error occured: \n" + e.toString()); + } + } + + private static void printRow(Row row) { + System.out.printf("Reading data for %s%n", row.getKey().toStringUtf8()); + String colFamily = ""; + for (RowCell cell : row.getCells()) { + if (!cell.getFamily().equals(colFamily)) { + colFamily = cell.getFamily(); + System.out.printf("Column Family %s%n", colFamily); + } + String labels = + cell.getLabels().size() == 0 ? "" : " [" + String.join(",", cell.getLabels()) + "]"; + System.out.printf( + "\t%s: %s @%s%s%n", + cell.getQualifier().toStringUtf8(), + cell.getValue().toStringUtf8(), + cell.getTimestamp(), + labels); + } + System.out.println(); + } +} +// [END bigtable_filters_limit_row_sample] +// [END bigtable_filters_limit_row_regex] +// [END bigtable_filters_limit_cells_per_col] +// [END bigtable_filters_limit_cells_per_row] +// [END bigtable_filters_limit_cells_per_row_offset] +// [END bigtable_filters_limit_col_family_regex] +// [END bigtable_filters_limit_col_qualifier_regex] +// [END bigtable_filters_limit_col_range] +// [END bigtable_filters_limit_value_range] +// [END bigtable_filters_limit_value_regex] +// [END bigtable_filters_limit_timestamp_range] +// [END bigtable_filters_limit_block_all] +// [END bigtable_filters_limit_pass_all] +// [END bigtable_filters_modify_strip_value] +// [END bigtable_filters_modify_apply_label] +// [END bigtable_filters_composing_chain] +// [END bigtable_filters_composing_interleave] +// [END bigtable_filters_composing_condition] diff --git a/bigtable/snippets/src/main/java/com/example/bigtable/Reads.java b/bigtable/snippets/src/main/java/com/example/bigtable/Reads.java new file mode 100644 index 00000000000..1807fc2f819 --- /dev/null +++ b/bigtable/snippets/src/main/java/com/example/bigtable/Reads.java @@ -0,0 +1,272 @@ +/* + * Copyright 2019 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.bigtable; + +// [START bigtable_reads_row] +// [START bigtable_reads_row_partial] +// [START bigtable_reads_rows] +// [START bigtable_reads_row_range] +// [START bigtable_reads_row_ranges] +// [START bigtable_reads_prefix] +// [START bigtable_reads_filter] + +import static com.google.cloud.bigtable.data.v2.models.Filters.FILTERS; + +import com.google.api.gax.rpc.ServerStream; +import com.google.cloud.bigtable.data.v2.BigtableDataClient; +import com.google.cloud.bigtable.data.v2.models.Filters; +import com.google.cloud.bigtable.data.v2.models.Query; +import com.google.cloud.bigtable.data.v2.models.Row; +import com.google.cloud.bigtable.data.v2.models.RowCell; +import com.google.cloud.bigtable.data.v2.models.RowMutation; +import com.google.protobuf.ByteString; +import java.io.IOException; + +public class Reads { + // [END bigtable_reads_row] + // [END bigtable_reads_row_partial] + // [END bigtable_reads_rows] + // [END bigtable_reads_row_range] + // [END bigtable_reads_row_ranges] + // [END bigtable_reads_prefix] + // [END bigtable_reads_filter] + + // [START bigtable_reads_row] + public static void readRow() { + // TODO(developer): Replace these variables before running the sample. + String projectId = "my-project-id"; + String instanceId = "my-instance-id"; + String tableId = "mobile-time-series"; + readRow(projectId, instanceId, tableId); + } + + public static void readRow(String projectId, String instanceId, String tableId) { + // Initialize client that will be used to send requests. This client only needs to be created + // once, and can be reused for multiple requests. After completing all of your requests, call + // the "close" method on the client to safely clean up any remaining background resources. + try (BigtableDataClient dataClient = BigtableDataClient.create(projectId, instanceId)) { + String rowkey = "phone#4c410523#20190501"; + + Row row = dataClient.readRow(tableId, rowkey); + printRow(row); + + } catch (IOException e) { + System.out.println( + "Unable to intailize service client, as a network error occured: \n" + e.toString()); + } + } + // [END bigtable_reads_row] + + // [START bigtable_reads_row_partial] + public static void readRowPartial() { + // TODO(developer): Replace these variables before running the sample. + String projectId = "my-project-id"; + String instanceId = "my-instance-id"; + String tableId = "mobile-time-series"; + readRowPartial(projectId, instanceId, tableId); + } + + public static void readRowPartial(String projectId, String instanceId, String tableId) { + // Initialize client that will be used to send requests. This client only needs to be created + // once, and can be reused for multiple requests. After completing all of your requests, call + // the "close" method on the client to safely clean up any remaining background resources. + try (BigtableDataClient dataClient = BigtableDataClient.create(projectId, instanceId)) { + String rowkey = "phone#4c410523#20190501"; + Filters.Filter filter = + FILTERS + .chain() + .filter(FILTERS.family().exactMatch("stats_summary")) + .filter(FILTERS.qualifier().exactMatch("os_build")); + + Row row = dataClient.readRow(tableId, rowkey, filter); + printRow(row); + + } catch (IOException e) { + System.out.println( + "Unable to intailize service client, as a network error occured: \n" + e.toString()); + } + } + // [END bigtable_reads_row_partial] + + // [START bigtable_reads_rows] + public static void readRows() { + // TODO(developer): Replace these variables before running the sample. + String projectId = "my-project-id"; + String instanceId = "my-instance-id"; + String tableId = "mobile-time-series"; + readRows(projectId, instanceId, tableId); + } + + public static void readRows(String projectId, String instanceId, String tableId) { + // Initialize client that will be used to send requests. This client only needs to be created + // once, and can be reused for multiple requests. After completing all of your requests, call + // the "close" method on the client to safely clean up any remaining background resources. + try (BigtableDataClient dataClient = BigtableDataClient.create(projectId, instanceId)) { + Query query = + Query.create(tableId).rowKey("phone#4c410523#20190501").rowKey("phone#4c410523#20190502"); + ServerStream rows = dataClient.readRows(query); + for (Row row : rows) { + printRow(row); + } + } catch (IOException e) { + System.out.println( + "Unable to intailize service client, as a network error occured: \n" + e.toString()); + } + } + // [END bigtable_reads_rows] + + // [START bigtable_reads_row_range] + public static void readRowRange() { + // TODO(developer): Replace these variables before running the sample. + String projectId = "my-project-id"; + String instanceId = "my-instance-id"; + String tableId = "mobile-time-series"; + readRowRange(projectId, instanceId, tableId); + } + + public static void readRowRange(String projectId, String instanceId, String tableId) { + String start = "phone#4c410523#20190501"; + String end = "phone#4c410523#201906201"; + + // Initialize client that will be used to send requests. This client only needs to be created + // once, and can be reused for multiple requests. After completing all of your requests, call + // the "close" method on the client to safely clean up any remaining background resources. + try (BigtableDataClient dataClient = BigtableDataClient.create(projectId, instanceId)) { + Query query = Query.create(tableId).range(start, end); + ServerStream rows = dataClient.readRows(query); + for (Row row : rows) { + printRow(row); + } + } catch (IOException e) { + System.out.println( + "Unable to intailize service client, as a network error occured: \n" + e.toString()); + } + } + // [END bigtable_reads_row_range] + + // [START bigtable_reads_row_ranges] + public static void readRowRanges() { + // TODO(developer): Replace these variables before running the sample. + String projectId = "my-project-id"; + String instanceId = "my-instance-id"; + String tableId = "mobile-time-series"; + readRowRanges(projectId, instanceId, tableId); + } + + public static void readRowRanges(String projectId, String instanceId, String tableId) { + // Initialize client that will be used to send requests. This client only needs to be created + // once, and can be reused for multiple requests. After completing all of your requests, call + // the "close" method on the client to safely clean up any remaining background resources. + try (BigtableDataClient dataClient = BigtableDataClient.create(projectId, instanceId)) { + Query query = + Query.create(tableId) + .range("phone#4c410523#20190501", "phone#4c410523#20190601") + .range("phone#5c10102#20190501", "phone#5c10102#20190601"); + ServerStream rows = dataClient.readRows(query); + for (Row row : rows) { + printRow(row); + } + } catch (IOException e) { + System.out.println( + "Unable to intailize service client, as a network error occured: \n" + e.toString()); + } + } + // [END bigtable_reads_row_ranges] + + // [START bigtable_reads_prefix] + public static void readPrefix() { + // TODO(developer): Replace these variables before running the sample. + String projectId = "my-project-id"; + String instanceId = "my-instance-id"; + String tableId = "mobile-time-series"; + readPrefix(projectId, instanceId, tableId); + } + + public static void readPrefix(String projectId, String instanceId, String tableId) { + // Initialize client that will be used to send requests. This client only needs to be created + // once, and can be reused for multiple requests. After completing all of your requests, call + // the "close" method on the client to safely clean up any remaining background resources. + try (BigtableDataClient dataClient = BigtableDataClient.create(projectId, instanceId)) { + Query query = Query.create(tableId).prefix("phone"); + ServerStream rows = dataClient.readRows(query); + for (Row row : rows) { + printRow(row); + } + } catch (IOException e) { + System.out.println( + "Unable to intailize service client, as a network error occured: \n" + e.toString()); + } + } + // [END bigtable_reads_prefix] + + // [START bigtable_reads_filter] + public static void readFilter() { + // TODO(developer): Replace these variables before running the sample. + String projectId = "my-project-id"; + String instanceId = "my-instance-id"; + String tableId = "mobile-time-series"; + readFilter(projectId, instanceId, tableId); + } + + public static void readFilter(String projectId, String instanceId, String tableId) { + Filters.Filter filter = FILTERS.value().regex("PQ2A.*"); + + // Initialize client that will be used to send requests. This client only needs to be created + // once, and can be reused for multiple requests. After completing all of your requests, call + // the "close" method on the client to safely clean up any remaining background resources. + try (BigtableDataClient dataClient = BigtableDataClient.create(projectId, instanceId)) { + Query query = Query.create(tableId).filter(filter); + ServerStream rows = dataClient.readRows(query); + for (Row row : rows) { + printRow(row); + } + } catch (IOException e) { + System.out.println( + "Unable to intailize service client, as a network error occured: \n" + e.toString()); + } + } + // [END bigtable_reads_filter] + + // [START bigtable_reads_row] + // [START bigtable_reads_row_partial] + // [START bigtable_reads_rows] + // [START bigtable_reads_row_range] + // [START bigtable_reads_row_ranges] + // [START bigtable_reads_prefix] + // [START bigtable_reads_filter] + private static void printRow(Row row) { + System.out.printf("Reading data for %s%n", row.getKey().toStringUtf8()); + String colFamily = ""; + for (RowCell cell : row.getCells()) { + if (!cell.getFamily().equals(colFamily)) { + colFamily = cell.getFamily(); + System.out.printf("Column Family %s%n", colFamily); + } + System.out.printf( + "\t%s: %s @%s%n", + cell.getQualifier().toStringUtf8(), cell.getValue().toStringUtf8(), cell.getTimestamp()); + } + System.out.println(); + } +} +// [END bigtable_reads_row] +// [END bigtable_reads_row_partial] +// [END bigtable_reads_rows] +// [END bigtable_reads_row_range] +// [END bigtable_reads_row_ranges] +// [END bigtable_reads_prefix] +// [END bigtable_reads_filter] diff --git a/bigtable/snippets/src/main/java/com/example/bigtable/WriteConditionally.java b/bigtable/snippets/src/main/java/com/example/bigtable/WriteConditionally.java index 7cc8fd22441..ac01cb0c634 100644 --- a/bigtable/snippets/src/main/java/com/example/bigtable/WriteConditionally.java +++ b/bigtable/snippets/src/main/java/com/example/bigtable/WriteConditionally.java @@ -36,7 +36,7 @@ public static void writeConditionally(String projectId, String instanceId, Strin try (BigtableDataClient dataClient = BigtableDataClient.create(projectId, instanceId)) { long timestamp = System.currentTimeMillis() * 1000; - String rowKey = "phone#4c410523#20190501"; + String rowkey = "phone#4c410523#20190501"; Mutation mutation = Mutation.create().setCell(COLUMN_FAMILY_NAME, "os_name", timestamp, "android"); @@ -49,7 +49,7 @@ public static void writeConditionally(String projectId, String instanceId, Strin .filter(FILTERS.value().regex("PQ2A\\..*")); ConditionalRowMutation conditionalRowMutation = - ConditionalRowMutation.create(tableId, rowKey).condition(filter).then(mutation); + ConditionalRowMutation.create(tableId, rowkey).condition(filter).then(mutation); boolean success = dataClient.checkAndMutateRow(conditionalRowMutation); diff --git a/bigtable/snippets/src/main/java/com/example/bigtable/WriteIncrement.java b/bigtable/snippets/src/main/java/com/example/bigtable/WriteIncrement.java index ec6d756b625..0f91a137177 100644 --- a/bigtable/snippets/src/main/java/com/example/bigtable/WriteIncrement.java +++ b/bigtable/snippets/src/main/java/com/example/bigtable/WriteIncrement.java @@ -34,9 +34,9 @@ public static void writeIncrement(String projectId, String instanceId, String ta try (BigtableDataClient dataClient = BigtableDataClient.create(projectId, instanceId)) { // Get an existing row that has a cell with an incrementable value. A value can be incremented // if it is encoded as a 64-bit big-endian signed integer. - String rowKey = "phone#4c410523#20190501"; + String rowkey = "phone#4c410523#20190501"; ReadModifyWriteRow mutation = - ReadModifyWriteRow.create(tableId, rowKey) + ReadModifyWriteRow.create(tableId, rowkey) .increment(COLUMN_FAMILY_NAME, "connected_cell", -1); Row success = dataClient.readModifyWriteRow(mutation); diff --git a/bigtable/snippets/src/main/java/com/example/bigtable/WriteSimple.java b/bigtable/snippets/src/main/java/com/example/bigtable/WriteSimple.java index 50671989218..a782542c3e7 100644 --- a/bigtable/snippets/src/main/java/com/example/bigtable/WriteSimple.java +++ b/bigtable/snippets/src/main/java/com/example/bigtable/WriteSimple.java @@ -33,11 +33,11 @@ public static void writeSimple(String projectId, String instanceId, String table try (BigtableDataClient dataClient = BigtableDataClient.create(projectId, instanceId)) { long timestamp = System.currentTimeMillis() * 1000; - String rowKey = "phone#4c410523#20190501"; + String rowkey = "phone#4c410523#20190501"; ByteString one = ByteString.copyFrom(new byte[] {0, 0, 0, 0, 0, 0, 0, 1}); RowMutation rowMutation = - RowMutation.create(tableId, rowKey) + RowMutation.create(tableId, rowkey) .setCell( COLUMN_FAMILY_NAME, ByteString.copyFrom("connected_cell".getBytes()), @@ -51,7 +51,7 @@ public static void writeSimple(String projectId, String instanceId, String table .setCell(COLUMN_FAMILY_NAME, "os_build", timestamp, "PQ2A.190405.003"); dataClient.mutateRow(rowMutation); - System.out.printf("Successfully wrote row %s", rowKey); + System.out.printf("Successfully wrote row %s", rowkey); } catch (Exception e) { System.out.println("Error during WriteSimple: \n" + e.toString()); diff --git a/bigtable/snippets/src/test/java/com/example/bigtable/FiltersTest.java b/bigtable/snippets/src/test/java/com/example/bigtable/FiltersTest.java new file mode 100644 index 00000000000..ab9c7af6692 --- /dev/null +++ b/bigtable/snippets/src/test/java/com/example/bigtable/FiltersTest.java @@ -0,0 +1,745 @@ +/* + * Copyright 2019 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.bigtable; + +import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.assertNotNull; + +import com.google.cloud.bigtable.admin.v2.BigtableTableAdminClient; +import com.google.cloud.bigtable.admin.v2.models.CreateTableRequest; +import com.google.cloud.bigtable.data.v2.BigtableDataClient; +import com.google.cloud.bigtable.data.v2.models.BulkMutation; +import com.google.cloud.bigtable.data.v2.models.Mutation; +import com.google.protobuf.ByteString; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.PrintStream; +import java.time.Instant; +import java.time.temporal.ChronoUnit; +import java.util.UUID; +import java.util.logging.Filter; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runners.MethodSorters; + +public class FiltersTest { + + private static final String INSTANCE_ENV = "BIGTABLE_TESTING_INSTANCE"; + private static final String TABLE_ID = + "mobile-time-series-" + UUID.randomUUID().toString().substring(0, 20); + private static final String COLUMN_FAMILY_NAME_STATS = "stats_summary"; + private static final String COLUMN_FAMILY_NAME_DATA = "cell_plan"; + private static final Instant CURRENT_TIME = Instant.now(); + private static final long TIMESTAMP = CURRENT_TIME.toEpochMilli() * 1000; + private static final long TIMESTAMP_MINUS_HR = + CURRENT_TIME.minus(1, ChronoUnit.HOURS).toEpochMilli() * 1000; + + private static String projectId; + private static String instanceId; + private ByteArrayOutputStream bout; + + private static String requireEnv(String varName) { + String value = System.getenv(varName); + assertNotNull(String.format("Environment variable '%s' is required to perform these tests.", varName), value); + return value; + } + + @BeforeClass + public static void beforeClass() throws IOException { + projectId = requireEnv("GOOGLE_CLOUD_PROJECT"); + instanceId = requireEnv(INSTANCE_ENV); + + try (BigtableTableAdminClient adminClient = + BigtableTableAdminClient.create(projectId, instanceId)) { + CreateTableRequest createTableRequest = + CreateTableRequest.of(TABLE_ID) + .addFamily(COLUMN_FAMILY_NAME_STATS) + .addFamily(COLUMN_FAMILY_NAME_DATA); + adminClient.createTable(createTableRequest); + + try (BigtableDataClient dataClient = BigtableDataClient.create(projectId, instanceId)) { + BulkMutation bulkMutation = + BulkMutation.create(TABLE_ID) + .add( + "phone#4c410523#20190501", + Mutation.create() + .setCell( + COLUMN_FAMILY_NAME_STATS, + ByteString.copyFrom("connected_cell".getBytes()), + TIMESTAMP, + 1) + .setCell( + COLUMN_FAMILY_NAME_STATS, + ByteString.copyFrom("connected_wifi".getBytes()), + TIMESTAMP, + 1) + .setCell(COLUMN_FAMILY_NAME_STATS, "os_build", TIMESTAMP, "PQ2A.190405.003") + .setCell( + COLUMN_FAMILY_NAME_DATA, "data_plan_01gb", TIMESTAMP_MINUS_HR, "true") + .setCell(COLUMN_FAMILY_NAME_DATA, "data_plan_01gb", TIMESTAMP, "false") + .setCell(COLUMN_FAMILY_NAME_DATA, "data_plan_05gb", TIMESTAMP, "true")) + .add( + "phone#4c410523#20190502", + Mutation.create() + .setCell( + COLUMN_FAMILY_NAME_STATS, + ByteString.copyFrom("connected_cell".getBytes()), + TIMESTAMP, + 1) + .setCell( + COLUMN_FAMILY_NAME_STATS, + ByteString.copyFrom("connected_wifi".getBytes()), + TIMESTAMP, + 1) + .setCell(COLUMN_FAMILY_NAME_STATS, "os_build", TIMESTAMP, "PQ2A.190405.004") + .setCell(COLUMN_FAMILY_NAME_DATA, "data_plan_05gb", TIMESTAMP, "true")) + .add( + "phone#4c410523#20190505", + Mutation.create() + .setCell( + COLUMN_FAMILY_NAME_STATS, + ByteString.copyFrom("connected_cell".getBytes()), + TIMESTAMP, + 0) + .setCell( + COLUMN_FAMILY_NAME_STATS, + ByteString.copyFrom("connected_wifi".getBytes()), + TIMESTAMP, + 1) + .setCell(COLUMN_FAMILY_NAME_STATS, "os_build", TIMESTAMP, "PQ2A.190406.000") + .setCell(COLUMN_FAMILY_NAME_DATA, "data_plan_05gb", TIMESTAMP, "true")) + .add( + "phone#5c10102#20190501", + Mutation.create() + .setCell( + COLUMN_FAMILY_NAME_STATS, + ByteString.copyFrom("connected_cell".getBytes()), + TIMESTAMP, + 1) + .setCell( + COLUMN_FAMILY_NAME_STATS, + ByteString.copyFrom("connected_wifi".getBytes()), + TIMESTAMP, + 1) + .setCell(COLUMN_FAMILY_NAME_STATS, "os_build", TIMESTAMP, "PQ2A.190401.002") + .setCell(COLUMN_FAMILY_NAME_DATA, "data_plan_10gb", TIMESTAMP, "true")) + .add( + "phone#5c10102#20190502", + Mutation.create() + .setCell( + COLUMN_FAMILY_NAME_STATS, + ByteString.copyFrom("connected_cell".getBytes()), + TIMESTAMP, + 1) + .setCell( + COLUMN_FAMILY_NAME_STATS, + ByteString.copyFrom("connected_wifi".getBytes()), + TIMESTAMP, + 0) + .setCell(COLUMN_FAMILY_NAME_STATS, "os_build", TIMESTAMP, "PQ2A.190406.000") + .setCell(COLUMN_FAMILY_NAME_DATA, "data_plan_10gb", TIMESTAMP, "true")); + + dataClient.bulkMutateRows(bulkMutation); + } + } catch (Exception e) { + System.out.println("Error during beforeClass: \n" + e.toString()); + throw (e); + } + } + + @Before + public void setupStream() { + bout = new ByteArrayOutputStream(); + System.setOut(new PrintStream(bout)); + } + + @AfterClass + public static void afterClass() throws IOException { + try (BigtableTableAdminClient adminClient = + BigtableTableAdminClient.create(projectId, instanceId)) { + adminClient.deleteTable(TABLE_ID); + } catch (Exception e) { + System.out.println("Error during afterClass: \n" + e.toString()); + throw (e); + } + } + + @Test + public void testFilterRowSample() { + Filters.filterLimitRowSample(projectId, instanceId, TABLE_ID); + + String output = bout.toString(); + assertThat(output).contains("Reading data for"); + } + + @Test + public void testFilterRowRegex() { + Filters.filterLimitRowRegex(projectId, instanceId, TABLE_ID); + + String output = bout.toString(); + assertThat(output) + .contains( + String.format( + "Reading data for phone#4c410523#20190501\n" + + "Column Family cell_plan\n" + + "\tdata_plan_01gb: false @%1$s\n" + + "\tdata_plan_01gb: true @%2$s\n" + + "\tdata_plan_05gb: true @%1$s\n" + + "Column Family stats_summary\n" + + "\tconnected_cell: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s\n" + + "\tconnected_wifi: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s\n" + + "\tos_build: PQ2A.190405.003 @%1$s\n\n" + + "Reading data for phone#5c10102#20190501\n" + + "Column Family cell_plan\n" + + "\tdata_plan_10gb: true @%1$s\n" + + "Column Family stats_summary\n" + + "\tconnected_cell: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s\n" + + "\tconnected_wifi: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s\n" + + "\tos_build: PQ2A.190401.002 @%1$s", + TIMESTAMP, TIMESTAMP_MINUS_HR)); + } + + @Test + public void testFilterCellsPerCol() { + Filters.filterLimitCellsPerCol(projectId, instanceId, TABLE_ID); + + String output = bout.toString(); + assertThat(output) + .contains( + String.format( + "Reading data for phone#4c410523#20190501\n" + + "Column Family cell_plan\n" + + "\tdata_plan_01gb: false @%1$s\n" + + "\tdata_plan_01gb: true @%2$s\n" + + "\tdata_plan_05gb: true @%1$s\n" + + "Column Family stats_summary\n" + + "\tconnected_cell: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s\n" + + "\tconnected_wifi: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s\n" + + "\tos_build: PQ2A.190405.003 @%1$s\n\n" + + "Reading data for phone#4c410523#20190502\n" + + "Column Family cell_plan\n" + + "\tdata_plan_05gb: true @%1$s\n" + + "Column Family stats_summary\n" + + "\tconnected_cell: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s\n" + + "\tconnected_wifi: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s\n" + + "\tos_build: PQ2A.190405.004 @%1$s\n\n" + + "Reading data for phone#4c410523#20190505\n" + + "Column Family cell_plan\n" + + "\tdata_plan_05gb: true @%1$s\n" + + "Column Family stats_summary\n" + + "\tconnected_cell: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000 @%1$s\n" + + "\tconnected_wifi: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s\n" + + "\tos_build: PQ2A.190406.000 @%1$s\n\n" + + "Reading data for phone#5c10102#20190501\n" + + "Column Family cell_plan\n" + + "\tdata_plan_10gb: true @%1$s\n" + + "Column Family stats_summary\n" + + "\tconnected_cell: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s\n" + + "\tconnected_wifi: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s\n" + + "\tos_build: PQ2A.190401.002 @%1$s\n\n" + + "Reading data for phone#5c10102#20190502\n" + + "Column Family cell_plan\n" + + "\tdata_plan_10gb: true @%1$s\n" + + "Column Family stats_summary\n" + + "\tconnected_cell: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s\n" + + "\tconnected_wifi: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000 @%1$s\n" + + "\tos_build: PQ2A.190406.000 @%1$s", + TIMESTAMP, TIMESTAMP_MINUS_HR)); + } + + @Test + public void testFilterCellsPerRow() { + Filters.filterLimitCellsPerRow(projectId, instanceId, TABLE_ID); + + String output = bout.toString(); + assertThat(output) + .contains( + String.format( + "Reading data for phone#4c410523#20190501\n" + + "Column Family cell_plan\n" + + "\tdata_plan_01gb: false @%1$s\n" + + "\tdata_plan_01gb: true @%2$s\n\n" + + "Reading data for phone#4c410523#20190502\n" + + "Column Family cell_plan\n" + + "\tdata_plan_05gb: true @%1$s\n" + + "Column Family stats_summary\n" + + "\tconnected_cell: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s\n\n" + + "Reading data for phone#4c410523#20190505\n" + + "Column Family cell_plan\n" + + "\tdata_plan_05gb: true @%1$s\n" + + "Column Family stats_summary\n" + + "\tconnected_cell: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000 @%1$s\n\n" + + "Reading data for phone#5c10102#20190501\n" + + "Column Family cell_plan\n" + + "\tdata_plan_10gb: true @%1$s\n" + + "Column Family stats_summary\n" + + "\tconnected_cell: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s\n\n" + + "Reading data for phone#5c10102#20190502\n" + + "Column Family cell_plan\n" + + "\tdata_plan_10gb: true @%1$s\n" + + "Column Family stats_summary\n" + + "\tconnected_cell: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s\n", + TIMESTAMP, TIMESTAMP_MINUS_HR)); + } + + @Test + public void testFilterLimitCellsPerRowOffset() { + Filters.filterLimitCellsPerRowOffset(projectId, instanceId, TABLE_ID); + + String output = bout.toString(); + assertThat(output) + .contains( + String.format( + "Reading data for phone#4c410523#20190501\n" + + "Column Family cell_plan\n" + + "\tdata_plan_05gb: true @%1$s\n" + + "Column Family stats_summary\n" + + "\tconnected_cell: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s\n" + + "\tconnected_wifi: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s\n" + + "\tos_build: PQ2A.190405.003 @%1$s\n\n" + + "Reading data for phone#4c410523#20190502\n" + + "Column Family stats_summary\n" + + "\tconnected_wifi: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s\n" + + "\tos_build: PQ2A.190405.004 @%1$s\n\n" + + "Reading data for phone#4c410523#20190505\n" + + "Column Family stats_summary\n" + + "\tconnected_wifi: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s\n" + + "\tos_build: PQ2A.190406.000 @%1$s\n\n" + + "Reading data for phone#5c10102#20190501\n" + + "Column Family stats_summary\n" + + "\tconnected_wifi: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s\n" + + "\tos_build: PQ2A.190401.002 @%1$s\n\n" + + "Reading data for phone#5c10102#20190502\n" + + "Column Family stats_summary\n" + + "\tconnected_wifi: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000 @%1$s\n" + + "\tos_build: PQ2A.190406.000 @%1$s", + TIMESTAMP)); + } + + @Test + public void testFilterColFamilyRegex() { + Filters.filterLimitColFamilyRegex(projectId, instanceId, TABLE_ID); + + String output = bout.toString(); + assertThat(output) + .contains( + String.format( + "Reading data for phone#4c410523#20190501\n" + + "Column Family stats_summary\n" + + "\tconnected_cell: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s\n" + + "\tconnected_wifi: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s\n" + + "\tos_build: PQ2A.190405.003 @%1$s\n\n" + + "Reading data for phone#4c410523#20190502\n" + + "Column Family stats_summary\n" + + "\tconnected_cell: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s\n" + + "\tconnected_wifi: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s\n" + + "\tos_build: PQ2A.190405.004 @%1$s\n\n" + + "Reading data for phone#4c410523#20190505\n" + + "Column Family stats_summary\n" + + "\tconnected_cell: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000 @%1$s\n" + + "\tconnected_wifi: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s\n" + + "\tos_build: PQ2A.190406.000 @%1$s\n\n" + + "Reading data for phone#5c10102#20190501\n" + + "Column Family stats_summary\n" + + "\tconnected_cell: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s\n" + + "\tconnected_wifi: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s\n" + + "\tos_build: PQ2A.190401.002 @%1$s\n\n" + + "Reading data for phone#5c10102#20190502\n" + + "Column Family stats_summary\n" + + "\tconnected_cell: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s\n" + + "\tconnected_wifi: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000 @%1$s\n" + + "\tos_build: PQ2A.190406.000 @%1$s", + TIMESTAMP)); + } + + @Test + public void testFilterColQualifierRegex() { + Filters.filterLimitColQualifierRegex(projectId, instanceId, TABLE_ID); + + String output = bout.toString(); + assertThat(output) + .contains( + String.format( + "Reading data for phone#4c410523#20190501\n" + + "Column Family stats_summary\n" + + "\tconnected_cell: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s\n" + + "\tconnected_wifi: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s\n\n" + + "Reading data for phone#4c410523#20190502\n" + + "Column Family stats_summary\n" + + "\tconnected_cell: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s\n" + + "\tconnected_wifi: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s\n\n" + + "Reading data for phone#4c410523#20190505\n" + + "Column Family stats_summary\n" + + "\tconnected_cell: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000 @%1$s\n" + + "\tconnected_wifi: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s\n\n" + + "Reading data for phone#5c10102#20190501\n" + + "Column Family stats_summary\n" + + "\tconnected_cell: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s\n" + + "\tconnected_wifi: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s\n\n" + + "Reading data for phone#5c10102#20190502\n" + + "Column Family stats_summary\n" + + "\tconnected_cell: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s\n" + + "\tconnected_wifi: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000 @%1$s", + TIMESTAMP)); + } + + @Test + public void testFilterColRange() { + Filters.filterLimitColRange(projectId, instanceId, TABLE_ID); + + String output = bout.toString(); + assertThat(output) + .contains( + String.format( + "Reading data for phone#4c410523#20190501\n" + + "Column Family cell_plan\n" + + "\tdata_plan_01gb: false @%1$s\n" + + "\tdata_plan_01gb: true @%2$s\n" + + "\tdata_plan_05gb: true @%1$s\n\n" + + "Reading data for phone#4c410523#20190502\n" + + "Column Family cell_plan\n" + + "\tdata_plan_05gb: true @%1$s\n\n" + + "Reading data for phone#4c410523#20190505\n" + + "Column Family cell_plan\n" + + "\tdata_plan_05gb: true @%1$s", + TIMESTAMP, TIMESTAMP_MINUS_HR)); + } + + @Test + public void testFilterValueRange() { + Filters.filterLimitValueRange(projectId, instanceId, TABLE_ID); + + String output = bout.toString(); + assertThat(output) + .contains( + String.format( + "Reading data for phone#4c410523#20190501\n" + + "Column Family stats_summary\n" + + "\tos_build: PQ2A.190405.003 @%1$s\n\n" + + "Reading data for phone#4c410523#20190502\n" + + "Column Family stats_summary\n" + + "\tos_build: PQ2A.190405.004 @%1$s", + TIMESTAMP)); + } + + @Test + public void testFilterValueRegex() { + Filters.filterLimitValueRegex(projectId, instanceId, TABLE_ID); + + String output = bout.toString(); + assertThat(output) + .contains( + String.format( + "Reading data for phone#4c410523#20190501\n" + + "Column Family stats_summary\n" + + "\tos_build: PQ2A.190405.003 @%1$s\n\n" + + "Reading data for phone#4c410523#20190502\n" + + "Column Family stats_summary\n" + + "\tos_build: PQ2A.190405.004 @%1$s\n\n" + + "Reading data for phone#4c410523#20190505\n" + + "Column Family stats_summary\n" + + "\tos_build: PQ2A.190406.000 @%1$s\n\n" + + "Reading data for phone#5c10102#20190501\n" + + "Column Family stats_summary\n" + + "\tos_build: PQ2A.190401.002 @%1$s\n\n" + + "Reading data for phone#5c10102#20190502\n" + + "Column Family stats_summary\n" + + "\tos_build: PQ2A.190406.000 @%1$s", + TIMESTAMP)); + } + + @Test + public void testFilterTimestampRange() { + Filters.filterLimitTimestampRange(projectId, instanceId, TABLE_ID); + + String output = bout.toString(); + assertThat(output) + .contains( + String.format( + "Reading data for phone#4c410523#20190501\n" + + "Column Family cell_plan\n" + + "\tdata_plan_01gb: true @%s\n", + TIMESTAMP_MINUS_HR)); + } + + @Test + public void testFilterBlockAll() { + Filters.filterLimitBlockAll(projectId, instanceId, TABLE_ID); + + String output = bout.toString(); + assertThat(output).doesNotContain("Reading data for"); + } + + @Test + public void testFilterPassAll() { + Filters.filterLimitPassAll(projectId, instanceId, TABLE_ID); + + String output = bout.toString(); + assertThat(output) + .contains( + String.format( + "Reading data for phone#4c410523#20190501\n" + + "Column Family cell_plan\n" + + "\tdata_plan_01gb: false @%1$s\n" + + "\tdata_plan_01gb: true @%2$s\n" + + "\tdata_plan_05gb: true @%1$s\n" + + "Column Family stats_summary\n" + + "\tconnected_cell: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s\n" + + "\tconnected_wifi: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s\n" + + "\tos_build: PQ2A.190405.003 @%1$s\n\n" + + "Reading data for phone#4c410523#20190502\n" + + "Column Family cell_plan\n" + + "\tdata_plan_05gb: true @%1$s\n" + + "Column Family stats_summary\n" + + "\tconnected_cell: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s\n" + + "\tconnected_wifi: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s\n" + + "\tos_build: PQ2A.190405.004 @%1$s\n\n" + + "Reading data for phone#4c410523#20190505\n" + + "Column Family cell_plan\n" + + "\tdata_plan_05gb: true @%1$s\n" + + "Column Family stats_summary\n" + + "\tconnected_cell: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000 @%1$s\n" + + "\tconnected_wifi: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s\n" + + "\tos_build: PQ2A.190406.000 @%1$s\n\n" + + "Reading data for phone#5c10102#20190501\n" + + "Column Family cell_plan\n" + + "\tdata_plan_10gb: true @%1$s\n" + + "Column Family stats_summary\n" + + "\tconnected_cell: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s\n" + + "\tconnected_wifi: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s\n" + + "\tos_build: PQ2A.190401.002 @%1$s\n\n" + + "Reading data for phone#5c10102#20190502\n" + + "Column Family cell_plan\n" + + "\tdata_plan_10gb: true @%1$s\n" + + "Column Family stats_summary\n" + + "\tconnected_cell: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s\n" + + "\tconnected_wifi: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000 @%1$s\n" + + "\tos_build: PQ2A.190406.000 @%1$s", + TIMESTAMP, TIMESTAMP_MINUS_HR)); + } + + @Test + public void testFilterStripValue() { + Filters.filterModifyStripValue(projectId, instanceId, TABLE_ID); + + String output = bout.toString(); + assertThat(output) + .contains( + String.format( + "Reading data for phone#4c410523#20190501\n" + + "Column Family cell_plan\n" + + "\tdata_plan_01gb: @%1$s\n" + + "\tdata_plan_01gb: @%2$s\n" + + "\tdata_plan_05gb: @%1$s\n" + + "Column Family stats_summary\n" + + "\tconnected_cell: @%1$s\n" + + "\tconnected_wifi: @%1$s\n" + + "\tos_build: @%1$s\n\n" + + "Reading data for phone#4c410523#20190502\n" + + "Column Family cell_plan\n" + + "\tdata_plan_05gb: @%1$s\n" + + "Column Family stats_summary\n" + + "\tconnected_cell: @%1$s\n" + + "\tconnected_wifi: @%1$s\n" + + "\tos_build: @%1$s\n\n" + + "Reading data for phone#4c410523#20190505\n" + + "Column Family cell_plan\n" + + "\tdata_plan_05gb: @%1$s\n" + + "Column Family stats_summary\n" + + "\tconnected_cell: @%1$s\n" + + "\tconnected_wifi: @%1$s\n" + + "\tos_build: @%1$s\n\n" + + "Reading data for phone#5c10102#20190501\n" + + "Column Family cell_plan\n" + + "\tdata_plan_10gb: @%1$s\n" + + "Column Family stats_summary\n" + + "\tconnected_cell: @%1$s\n" + + "\tconnected_wifi: @%1$s\n" + + "\tos_build: @%1$s\n\n" + + "Reading data for phone#5c10102#20190502\n" + + "Column Family cell_plan\n" + + "\tdata_plan_10gb: @%1$s\n" + + "Column Family stats_summary\n" + + "\tconnected_cell: @%1$s\n" + + "\tconnected_wifi: @%1$s\n" + + "\tos_build: @%1$s", + TIMESTAMP, TIMESTAMP_MINUS_HR)); + } + + @Test + public void testFilterApplyLabel() { + Filters.filterModifyApplyLabel(projectId, instanceId, TABLE_ID); + + String output = bout.toString(); + assertThat(output) + .contains( + String.format( + "Reading data for phone#4c410523#20190501\n" + + "Column Family cell_plan\n" + + "\tdata_plan_01gb: false @%1$s [labelled]\n" + + "\tdata_plan_01gb: true @%2$s [labelled]\n" + + "\tdata_plan_05gb: true @%1$s [labelled]\n" + + "Column Family stats_summary\n" + + "\tconnected_cell: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s [labelled]\n" + + "\tconnected_wifi: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s [labelled]\n" + + "\tos_build: PQ2A.190405.003 @%1$s [labelled]\n\n" + + "Reading data for phone#4c410523#20190502\n" + + "Column Family cell_plan\n" + + "\tdata_plan_05gb: true @%1$s [labelled]\n" + + "Column Family stats_summary\n" + + "\tconnected_cell: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s [labelled]\n" + + "\tconnected_wifi: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s [labelled]\n" + + "\tos_build: PQ2A.190405.004 @%1$s [labelled]\n\n" + + "Reading data for phone#4c410523#20190505\n" + + "Column Family cell_plan\n" + + "\tdata_plan_05gb: true @%1$s [labelled]\n" + + "Column Family stats_summary\n" + + "\tconnected_cell: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000 @%1$s [labelled]\n" + + "\tconnected_wifi: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s [labelled]\n" + + "\tos_build: PQ2A.190406.000 @%1$s [labelled]\n\n" + + "Reading data for phone#5c10102#20190501\n" + + "Column Family cell_plan\n" + + "\tdata_plan_10gb: true @%1$s [labelled]\n" + + "Column Family stats_summary\n" + + "\tconnected_cell: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s [labelled]\n" + + "\tconnected_wifi: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s [labelled]\n" + + "\tos_build: PQ2A.190401.002 @%1$s [labelled]\n\n" + + "Reading data for phone#5c10102#20190502\n" + + "Column Family cell_plan\n" + + "\tdata_plan_10gb: true @%1$s [labelled]\n" + + "Column Family stats_summary\n" + + "\tconnected_cell: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s [labelled]\n" + + "\tconnected_wifi: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000 @%1$s [labelled]\n" + + "\tos_build: PQ2A.190406.000 @%1$s [labelled]", + TIMESTAMP, TIMESTAMP_MINUS_HR)); + } + + @Test + public void testFilterChain() { + Filters.filterComposingChain(projectId, instanceId, TABLE_ID); + + String output = bout.toString(); + assertThat(output) + .contains( + String.format( + "Reading data for phone#4c410523#20190501\n" + + "Column Family cell_plan\n" + + "\tdata_plan_01gb: false @%1$s\n" + + "\tdata_plan_05gb: true @%1$s\n\n" + + "Reading data for phone#4c410523#20190502\n" + + "Column Family cell_plan\n" + + "\tdata_plan_05gb: true @%1$s\n\n" + + "Reading data for phone#4c410523#20190505\n" + + "Column Family cell_plan\n" + + "\tdata_plan_05gb: true @%1$s\n\n" + + "Reading data for phone#5c10102#20190501\n" + + "Column Family cell_plan\n" + + "\tdata_plan_10gb: true @%1$s\n\n" + + "Reading data for phone#5c10102#20190502\n" + + "Column Family cell_plan\n" + + "\tdata_plan_10gb: true @%1$s\n", + TIMESTAMP)); + } + + @Test + public void testFilterInterleave() { + Filters.filterComposingInterleave(projectId, instanceId, TABLE_ID); + + String output = bout.toString(); + assertThat(output) + .contains( + String.format( + "Reading data for phone#4c410523#20190501\n" + + "Column Family cell_plan\n" + + "\tdata_plan_01gb: true @%2$s\n" + + "\tdata_plan_05gb: true @%1$s\n" + + "Column Family stats_summary\n" + + "\tos_build: PQ2A.190405.003 @%1$s\n\n" + + "Reading data for phone#4c410523#20190502\n" + + "Column Family cell_plan\n" + + "\tdata_plan_05gb: true @%1$s\n" + + "Column Family stats_summary\n" + + "\tos_build: PQ2A.190405.004 @%1$s\n\n" + + "Reading data for phone#4c410523#20190505\n" + + "Column Family cell_plan\n" + + "\tdata_plan_05gb: true @%1$s\n" + + "Column Family stats_summary\n" + + "\tos_build: PQ2A.190406.000 @%1$s\n\n" + + "Reading data for phone#5c10102#20190501\n" + + "Column Family cell_plan\n" + + "\tdata_plan_10gb: true @%1$s\n" + + "Column Family stats_summary\n" + + "\tos_build: PQ2A.190401.002 @%1$s\n\n" + + "Reading data for phone#5c10102#20190502\n" + + "Column Family cell_plan\n" + + "\tdata_plan_10gb: true @%1$s\n" + + "Column Family stats_summary\n" + + "\tos_build: PQ2A.190406.000 @%1$s", + TIMESTAMP, TIMESTAMP_MINUS_HR)); + } + + @Test + public void testFilterCondition() { + Filters.filterComposingCondition(projectId, instanceId, TABLE_ID); + + String output = bout.toString(); + assertThat(output) + .contains( + String.format( + "Reading data for phone#4c410523#20190501\n" + + "Column Family cell_plan\n" + + "\tdata_plan_01gb: false @%1$s [filtered-out]\n" + + "\tdata_plan_01gb: true @%2$s [filtered-out]\n" + + "\tdata_plan_05gb: true @%1$s [filtered-out]\n" + + "Column Family stats_summary\n" + + "\tconnected_cell: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s [filtered-out]\n" + + "\tconnected_wifi: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s [filtered-out]\n" + + "\tos_build: PQ2A.190405.003 @%1$s [filtered-out]\n\n" + + "Reading data for phone#4c410523#20190502\n" + + "Column Family cell_plan\n" + + "\tdata_plan_05gb: true @%1$s [filtered-out]\n" + + "Column Family stats_summary\n" + + "\tconnected_cell: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s [filtered-out]\n" + + "\tconnected_wifi: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s [filtered-out]\n" + + "\tos_build: PQ2A.190405.004 @%1$s [filtered-out]\n\n" + + "Reading data for phone#4c410523#20190505\n" + + "Column Family cell_plan\n" + + "\tdata_plan_05gb: true @%1$s [filtered-out]\n" + + "Column Family stats_summary\n" + + "\tconnected_cell: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000 @%1$s [filtered-out]\n" + + "\tconnected_wifi: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s [filtered-out]\n" + + "\tos_build: PQ2A.190406.000 @%1$s [filtered-out]\n\n" + + "Reading data for phone#5c10102#20190501\n" + + "Column Family cell_plan\n" + + "\tdata_plan_10gb: true @%1$s [passed-filter]\n" + + "Column Family stats_summary\n" + + "\tconnected_cell: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s [passed-filter]\n" + + "\tconnected_wifi: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s [passed-filter]\n" + + "\tos_build: PQ2A.190401.002 @%1$s [passed-filter]\n\n" + + "Reading data for phone#5c10102#20190502\n" + + "Column Family cell_plan\n" + + "\tdata_plan_10gb: true @%1$s [passed-filter]\n" + + "Column Family stats_summary\n" + + "\tconnected_cell: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s [passed-filter]\n" + + "\tconnected_wifi: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000 @%1$s [passed-filter]\n" + + "\tos_build: PQ2A.190406.000 @%1$s [passed-filter]", + TIMESTAMP, TIMESTAMP_MINUS_HR)); + } +} diff --git a/bigtable/snippets/src/test/java/com/example/bigtable/ReadsTest.java b/bigtable/snippets/src/test/java/com/example/bigtable/ReadsTest.java new file mode 100644 index 00000000000..e7afadee07d --- /dev/null +++ b/bigtable/snippets/src/test/java/com/example/bigtable/ReadsTest.java @@ -0,0 +1,343 @@ +/* + * Copyright 2019 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.bigtable; + +import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.assertNotNull; + +import com.google.cloud.bigtable.admin.v2.BigtableTableAdminClient; +import com.google.cloud.bigtable.admin.v2.models.CreateTableRequest; +import com.google.cloud.bigtable.admin.v2.models.Table; +import com.google.cloud.bigtable.data.v2.BigtableDataClient; +import com.google.cloud.bigtable.data.v2.models.BulkMutation; +import com.google.cloud.bigtable.data.v2.models.Mutation; +import com.google.protobuf.ByteString; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.PrintStream; +import java.util.UUID; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runners.MethodSorters; + +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class ReadsTest { + + private static final String INSTANCE_ENV = "BIGTABLE_TESTING_INSTANCE"; + private static final String TABLE_ID = + "mobile-time-series-" + UUID.randomUUID().toString().substring(0, 20); + private static final String COLUMN_FAMILY_NAME = "stats_summary"; + private static final long TIMESTAMP = System.currentTimeMillis() * 1000; + + private static String projectId; + private static String instanceId; + private ByteArrayOutputStream bout; + + private static String requireEnv(String varName) { + String value = System.getenv(varName); + assertNotNull(String.format("Environment variable '%s' is required to perform these tests.", varName), value); + return value; + } + + @BeforeClass + public static void beforeClass() throws IOException { + projectId = requireEnv("GOOGLE_CLOUD_PROJECT"); + instanceId = requireEnv(INSTANCE_ENV); + + try (BigtableTableAdminClient adminClient = + BigtableTableAdminClient.create(projectId, instanceId)) { + CreateTableRequest createTableRequest = + CreateTableRequest.of(TABLE_ID).addFamily(COLUMN_FAMILY_NAME); + adminClient.createTable(createTableRequest); + + try (BigtableDataClient dataClient = BigtableDataClient.create(projectId, instanceId)) { + BulkMutation bulkMutation = + BulkMutation.create(TABLE_ID) + .add( + "phone#4c410523#20190501", + Mutation.create() + .setCell( + COLUMN_FAMILY_NAME, + ByteString.copyFrom("connected_cell".getBytes()), + TIMESTAMP, + 1) + .setCell( + COLUMN_FAMILY_NAME, + ByteString.copyFrom("connected_wifi".getBytes()), + TIMESTAMP, + 1) + .setCell(COLUMN_FAMILY_NAME, "os_build", TIMESTAMP, "PQ2A.190405.003")) + .add( + "phone#4c410523#20190502", + Mutation.create() + .setCell( + COLUMN_FAMILY_NAME, + ByteString.copyFrom("connected_cell".getBytes()), + TIMESTAMP, + 1) + .setCell( + COLUMN_FAMILY_NAME, + ByteString.copyFrom("connected_wifi".getBytes()), + TIMESTAMP, + 1) + .setCell(COLUMN_FAMILY_NAME, "os_build", TIMESTAMP, "PQ2A.190405.004")) + .add( + "phone#4c410523#20190505", + Mutation.create() + .setCell( + COLUMN_FAMILY_NAME, + ByteString.copyFrom("connected_cell".getBytes()), + TIMESTAMP, + 0) + .setCell( + COLUMN_FAMILY_NAME, + ByteString.copyFrom("connected_wifi".getBytes()), + TIMESTAMP, + 1) + .setCell(COLUMN_FAMILY_NAME, "os_build", TIMESTAMP, "PQ2A.190406.000")) + .add( + "phone#5c10102#20190501", + Mutation.create() + .setCell( + COLUMN_FAMILY_NAME, + ByteString.copyFrom("connected_cell".getBytes()), + TIMESTAMP, + 1) + .setCell( + COLUMN_FAMILY_NAME, + ByteString.copyFrom("connected_wifi".getBytes()), + TIMESTAMP, + 1) + .setCell(COLUMN_FAMILY_NAME, "os_build", TIMESTAMP, "PQ2A.190401.002")) + .add( + "phone#5c10102#20190502", + Mutation.create() + .setCell( + COLUMN_FAMILY_NAME, + ByteString.copyFrom("connected_cell".getBytes()), + TIMESTAMP, + 1) + .setCell( + COLUMN_FAMILY_NAME, + ByteString.copyFrom("connected_wifi".getBytes()), + TIMESTAMP, + 0) + .setCell(COLUMN_FAMILY_NAME, "os_build", TIMESTAMP, "PQ2A.190406.000")); + + dataClient.bulkMutateRows(bulkMutation); + } + } catch (Exception e) { + System.out.println("Error during beforeClass: \n" + e.toString()); + throw (e); + } + } + + @Before + public void setupStream() { + bout = new ByteArrayOutputStream(); + System.setOut(new PrintStream(bout)); + } + + @AfterClass + public static void afterClass() throws IOException { + try (BigtableTableAdminClient adminClient = + BigtableTableAdminClient.create(projectId, instanceId)) { + adminClient.deleteTable(TABLE_ID); + } catch (Exception e) { + System.out.println("Error during afterClass: \n" + e.toString()); + throw (e); + } + } + + @Test + public void testReadRow() { + Reads.readRow(projectId, instanceId, TABLE_ID); + + String output = bout.toString(); + assertThat(output) + .contains( + String.format( + "Reading data for phone#4c410523#20190501\n" + + "Column Family stats_summary\n" + + "\tconnected_cell: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s\n" + + "\tconnected_wifi: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s\n" + + "\tos_build: PQ2A.190405.003 @%1$s", + TIMESTAMP)); + } + + @Test + public void testReadRowPartial() { + Reads.readRowPartial(projectId, instanceId, TABLE_ID); + + String output = bout.toString(); + assertThat(output) + .contains( + String.format( + "Reading data for phone#4c410523#20190501\n" + + "Column Family stats_summary\n" + + "\tos_build: PQ2A.190405.003 @%1$s", + TIMESTAMP)); + } + + @Test + public void testReadRows() { + Reads.readRows(projectId, instanceId, TABLE_ID); + + String output = bout.toString(); + assertThat(output) + .contains( + String.format( + "Reading data for phone#4c410523#20190501\n" + + "Column Family stats_summary\n" + + "\tconnected_cell: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s\n" + + "\tconnected_wifi: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s\n" + + "\tos_build: PQ2A.190405.003 @%1$s\n\n" + + "Reading data for phone#4c410523#20190502\n" + + "Column Family stats_summary\n" + + "\tconnected_cell: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s\n" + + "\tconnected_wifi: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s\n" + + "\tos_build: PQ2A.190405.004 @%1$s", + TIMESTAMP)); + } + + @Test + public void testReadRowRange() { + Reads.readRowRange(projectId, instanceId, TABLE_ID); + + String output = bout.toString(); + assertThat(output) + .contains( + String.format( + "Reading data for phone#4c410523#20190501\n" + + "Column Family stats_summary\n" + + "\tconnected_cell: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s\n" + + "\tconnected_wifi: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s\n" + + "\tos_build: PQ2A.190405.003 @%1$s\n\n" + + "Reading data for phone#4c410523#20190502\n" + + "Column Family stats_summary\n" + + "\tconnected_cell: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s\n" + + "\tconnected_wifi: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s\n" + + "\tos_build: PQ2A.190405.004 @%1$s\n\n" + + "Reading data for phone#4c410523#20190505\n" + + "Column Family stats_summary\n" + + "\tconnected_cell: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000 @%1$s\n" + + "\tconnected_wifi: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s\n" + + "\tos_build: PQ2A.190406.000 @%1$s", + TIMESTAMP)); + } + + @Test + public void testReadRowRanges() { + Reads.readRowRanges(projectId, instanceId, TABLE_ID); + + String output = bout.toString(); + assertThat(output) + .contains( + String.format( + "Reading data for phone#4c410523#20190501\n" + + "Column Family stats_summary\n" + + "\tconnected_cell: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s\n" + + "\tconnected_wifi: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s\n" + + "\tos_build: PQ2A.190405.003 @%1$s\n\n" + + "Reading data for phone#4c410523#20190502\n" + + "Column Family stats_summary\n" + + "\tconnected_cell: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s\n" + + "\tconnected_wifi: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s\n" + + "\tos_build: PQ2A.190405.004 @%1$s\n\n" + + "Reading data for phone#4c410523#20190505\n" + + "Column Family stats_summary\n" + + "\tconnected_cell: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000 @%1$s\n" + + "\tconnected_wifi: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s\n" + + "\tos_build: PQ2A.190406.000 @%1$s\n\n" + + "Reading data for phone#5c10102#20190501\n" + + "Column Family stats_summary\n" + + "\tconnected_cell: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s\n" + + "\tconnected_wifi: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s\n" + + "\tos_build: PQ2A.190401.002 @%1$s\n\n" + + "Reading data for phone#5c10102#20190502\n" + + "Column Family stats_summary\n" + + "\tconnected_cell: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s\n" + + "\tconnected_wifi: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000 @%1$s\n" + + "\tos_build: PQ2A.190406.000 @%1$s", + TIMESTAMP)); + } + + @Test + public void testReadPrefix() { + Reads.readPrefix(projectId, instanceId, TABLE_ID); + + String output = bout.toString(); + assertThat(output) + .contains( + String.format( + "Reading data for phone#4c410523#20190501\n" + + "Column Family stats_summary\n" + + "\tconnected_cell: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s\n" + + "\tconnected_wifi: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s\n" + + "\tos_build: PQ2A.190405.003 @%1$s\n\n" + + "Reading data for phone#4c410523#20190502\n" + + "Column Family stats_summary\n" + + "\tconnected_cell: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s\n" + + "\tconnected_wifi: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s\n" + + "\tos_build: PQ2A.190405.004 @%1$s\n\n" + + "Reading data for phone#4c410523#20190505\n" + + "Column Family stats_summary\n" + + "\tconnected_cell: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000 @%1$s\n" + + "\tconnected_wifi: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s\n" + + "\tos_build: PQ2A.190406.000 @%1$s\n\n" + + "Reading data for phone#5c10102#20190501\n" + + "Column Family stats_summary\n" + + "\tconnected_cell: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s\n" + + "\tconnected_wifi: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s\n" + + "\tos_build: PQ2A.190401.002 @%1$s\n\n" + + "Reading data for phone#5c10102#20190502\n" + + "Column Family stats_summary\n" + + "\tconnected_cell: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001 @%1$s\n" + + "\tconnected_wifi: \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000 @%1$s\n" + + "\tos_build: PQ2A.190406.000 @%1$s", + TIMESTAMP)); + } + + @Test + public void testReadFilter() { + Reads.readFilter(projectId, instanceId, TABLE_ID); + + String output = bout.toString(); + assertThat(output) + .contains( + String.format( + "Reading data for phone#4c410523#20190501\n" + + "Column Family stats_summary\n" + + "\tos_build: PQ2A.190405.003 @%1$s\n\n" + + "Reading data for phone#4c410523#20190502\n" + + "Column Family stats_summary\n" + + "\tos_build: PQ2A.190405.004 @%1$s\n\n" + + "Reading data for phone#4c410523#20190505\n" + + "Column Family stats_summary\n" + + "\tos_build: PQ2A.190406.000 @%1$s\n\n" + + "Reading data for phone#5c10102#20190501\n" + + "Column Family stats_summary\n" + + "\tos_build: PQ2A.190401.002 @%1$s\n\n" + + "Reading data for phone#5c10102#20190502\n" + + "Column Family stats_summary\n" + + "\tos_build: PQ2A.190406.000 @%1$s", + TIMESTAMP)); + } +} diff --git a/bigtable/snippets/src/test/java/com/example/bigtable/WritesTest.java b/bigtable/snippets/src/test/java/com/example/bigtable/WritesTest.java index afe70c4027c..364b527a962 100644 --- a/bigtable/snippets/src/test/java/com/example/bigtable/WritesTest.java +++ b/bigtable/snippets/src/test/java/com/example/bigtable/WritesTest.java @@ -43,12 +43,10 @@ public class WritesTest { private static String projectId; private static String instanceId; private ByteArrayOutputStream bout; - private static String requireEnv(String varName) { - assertNotNull( - System.getenv(varName), - "Environment variable '%s' is required to perform these tests.".format(varName)); - return System.getenv(varName); + String value = System.getenv(varName); + assertNotNull(String.format("Environment variable '%s' is required to perform these tests.", varName), value); + return value; } @BeforeClass