Skip to content

Commit eb6c4d2

Browse files
elisheva-qlogicigorbernstein2
authored andcommitted
Cloud Bigtable: helloWorld sample (#4274)
* helloWorld sample * test class modified * format change in ITHelloWorld
1 parent 73e93c0 commit eb6c4d2

3 files changed

Lines changed: 321 additions & 1 deletion

File tree

google-cloud-examples/pom.xml

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,14 @@
2929
<groupId>com.google.cloud</groupId>
3030
<artifactId>google-cloud-bigquery</artifactId>
3131
</dependency>
32+
<dependency>
33+
<groupId>com.google.cloud</groupId>
34+
<artifactId>google-cloud-bigtable-admin</artifactId>
35+
</dependency>
36+
<dependency>
37+
<groupId>com.google.cloud</groupId>
38+
<artifactId>google-cloud-bigtable</artifactId>
39+
</dependency>
3240
<dependency>
3341
<groupId>com.google.cloud</groupId>
3442
<artifactId>google-cloud-compute</artifactId>
@@ -188,7 +196,7 @@
188196
<version>2.19.1</version>
189197
<configuration>
190198
<excludes>
191-
<exclude>**/IT*Snippets.java</exclude>
199+
<exclude>**/IT*.java</exclude>
192200
</excludes>
193201
</configuration>
194202
</plugin>
Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
/*
2+
* Copyright 2018 Google LLC. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.google.cloud.examples.bigtable;
17+
18+
import com.google.api.gax.rpc.NotFoundException;
19+
import com.google.api.gax.rpc.ServerStream;
20+
import com.google.cloud.bigtable.admin.v2.BigtableTableAdminClient;
21+
import com.google.cloud.bigtable.admin.v2.BigtableTableAdminSettings;
22+
import com.google.cloud.bigtable.admin.v2.models.CreateTableRequest;
23+
import com.google.cloud.bigtable.data.v2.BigtableDataClient;
24+
import com.google.cloud.bigtable.data.v2.BigtableDataSettings;
25+
import com.google.cloud.bigtable.data.v2.models.InstanceName;
26+
import com.google.cloud.bigtable.data.v2.models.Query;
27+
import com.google.cloud.bigtable.data.v2.models.Row;
28+
import com.google.cloud.bigtable.data.v2.models.RowCell;
29+
import com.google.cloud.bigtable.data.v2.models.RowMutation;
30+
import java.io.IOException;
31+
32+
public class HelloWorld {
33+
34+
private static final String COLUMN_FAMILY = "cf1";
35+
private static final String COLUMN_QUALIFIER = "greeting";
36+
private static final String ROW_KEY_PREFIX = "rowKey";
37+
private final String tableId;
38+
private final BigtableDataClient dataClient;
39+
private final BigtableTableAdminClient adminClient;
40+
41+
public static void main(String[] args) throws Exception {
42+
43+
if (args.length != 2) {
44+
System.out.println("Missing required project id or instance id");
45+
return;
46+
}
47+
String projectId = args[0];
48+
String instanceId = args[1];
49+
50+
HelloWorld helloWorld = new HelloWorld(projectId, instanceId, "test-table");
51+
helloWorld.run();
52+
}
53+
54+
public HelloWorld(String projectId, String instanceId, String tableId) throws IOException {
55+
this.tableId = tableId;
56+
57+
// [START connecting_to_bigtable]
58+
// Create the settings to configure a bigtable data client
59+
BigtableDataSettings settings =
60+
BigtableDataSettings.newBuilder()
61+
.setInstanceName(InstanceName.of(projectId, instanceId))
62+
.build();
63+
64+
// Create bigtable data client
65+
dataClient = BigtableDataClient.create(settings);
66+
67+
// Create the settings to configure a bigtable table admin client
68+
BigtableTableAdminSettings adminSettings =
69+
BigtableTableAdminSettings.newBuilder()
70+
.setInstanceName(com.google.bigtable.admin.v2.InstanceName.of(projectId, instanceId))
71+
.build();
72+
73+
// Create bigtable table admin client
74+
adminClient = BigtableTableAdminClient.create(adminSettings);
75+
// [END connecting_to_bigtable]
76+
}
77+
78+
public void run() throws Exception {
79+
createTable();
80+
writeToTable();
81+
readSingleRow();
82+
readTable();
83+
deleteTable();
84+
dataClient.close();
85+
adminClient.close();
86+
}
87+
88+
public void createTable() {
89+
// [START creating_a_table]
90+
// Check if table exists, create table if does not exist
91+
if (!adminClient.exists(tableId)) {
92+
System.out.println("Creating table: " + tableId);
93+
CreateTableRequest createTableRequest =
94+
CreateTableRequest.of(tableId).addFamily(COLUMN_FAMILY);
95+
adminClient.createTable(createTableRequest);
96+
System.out.printf("Table %s created successfully%n", tableId);
97+
}
98+
// [END creating_a_table]
99+
}
100+
101+
public void writeToTable() {
102+
// [START writing_rows]
103+
try {
104+
System.out.println("\nWriting some greetings to the table");
105+
String[] greetings = {"Hello World!", "Hello Bigtable!", "Hello Java!"};
106+
for (int i = 0; i < greetings.length; i++) {
107+
RowMutation rowMutation =
108+
RowMutation.create(tableId, ROW_KEY_PREFIX + i)
109+
.setCell(COLUMN_FAMILY, COLUMN_QUALIFIER, greetings[i]);
110+
dataClient.mutateRow(rowMutation);
111+
System.out.println(greetings[i]);
112+
}
113+
} catch (NotFoundException e) {
114+
System.err.println("Failed to write to non-existent table: " + e.getMessage());
115+
}
116+
// [END writing_rows]
117+
}
118+
119+
public void readSingleRow() {
120+
// [START reading_a_row]
121+
try {
122+
System.out.println("\nReading a single row by row key");
123+
Row row = dataClient.readRow(tableId, ROW_KEY_PREFIX + 0);
124+
System.out.println("Row: " + row.getKey().toStringUtf8());
125+
for (RowCell cell : row.getCells()) {
126+
System.out.printf(
127+
"Family: %s Qualifier: %s Value: %s%n",
128+
cell.getFamily(), cell.getQualifier().toStringUtf8(), cell.getValue().toStringUtf8());
129+
}
130+
} catch (NotFoundException e) {
131+
System.err.println("Failed to read from a non-existent table: " + e.getMessage());
132+
}
133+
// [END reading_a_row]
134+
}
135+
136+
public void readTable() {
137+
// [START scanning_all_rows]
138+
try {
139+
System.out.println("\nReading the entire table");
140+
Query query = Query.create(tableId);
141+
ServerStream<Row> rowStream = dataClient.readRows(query);
142+
for (Row r : rowStream) {
143+
System.out.println("Row Key: " + r.getKey().toStringUtf8());
144+
for (RowCell cell : r.getCells()) {
145+
System.out.printf(
146+
"Family: %s Qualifier: %s Value: %s%n",
147+
cell.getFamily(), cell.getQualifier().toStringUtf8(), cell.getValue().toStringUtf8());
148+
}
149+
}
150+
} catch (NotFoundException e) {
151+
System.err.println("Failed to read a non-existent table: " + e.getMessage());
152+
}
153+
// [END scanning_all_rows]
154+
}
155+
156+
public void deleteTable() {
157+
// [START deleting_a_table]
158+
System.out.println("\nDeleting table: " + tableId);
159+
try {
160+
adminClient.deleteTable(tableId);
161+
System.out.printf("Table %s deleted successfully%n", tableId);
162+
} catch (NotFoundException e) {
163+
System.err.println("Failed to delete a non-existent table: " + e.getMessage());
164+
}
165+
// [END deleting_a_table]
166+
}
167+
}
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
/*
2+
* Copyright 2018 Google LLC. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.google.cloud.examples.bigtable;
17+
18+
import static org.junit.Assert.assertNotNull;
19+
import static org.junit.Assert.assertTrue;
20+
21+
import com.google.cloud.bigtable.admin.v2.BigtableTableAdminClient;
22+
import com.google.cloud.bigtable.admin.v2.BigtableTableAdminSettings;
23+
import com.google.cloud.bigtable.admin.v2.models.CreateTableRequest;
24+
import com.google.cloud.bigtable.data.v2.BigtableDataClient;
25+
import com.google.cloud.bigtable.data.v2.BigtableDataSettings;
26+
import com.google.cloud.bigtable.data.v2.models.InstanceName;
27+
import com.google.cloud.bigtable.data.v2.models.Row;
28+
import java.io.IOException;
29+
import java.util.Random;
30+
import java.util.concurrent.TimeUnit;
31+
import java.util.regex.Matcher;
32+
import java.util.regex.Pattern;
33+
import org.junit.After;
34+
import org.junit.AfterClass;
35+
import org.junit.AssumptionViolatedException;
36+
import org.junit.Before;
37+
import org.junit.BeforeClass;
38+
import org.junit.Test;
39+
40+
public class ITHelloWorld {
41+
42+
private static final String INSTANCE_PROPERTY_NAME = "bigtable.instance";
43+
private static final String TABLE_PREFIX = "table";
44+
private static String tableId;
45+
private static BigtableDataClient dataClient;
46+
private static BigtableTableAdminClient adminClient;
47+
private static InstanceName instanceName;
48+
private HelloWorld helloWorld;
49+
50+
@BeforeClass
51+
public static void beforeClass() throws IOException {
52+
String targetInstance = System.getProperty(INSTANCE_PROPERTY_NAME);
53+
if (targetInstance == null) {
54+
dataClient = null;
55+
adminClient = null;
56+
return;
57+
}
58+
instanceName = InstanceName.parse(targetInstance);
59+
BigtableDataSettings settings =
60+
BigtableDataSettings.newBuilder().setInstanceName(instanceName).build();
61+
dataClient = BigtableDataClient.create(settings);
62+
BigtableTableAdminSettings adminSettings =
63+
BigtableTableAdminSettings.newBuilder()
64+
.setInstanceName(com.google.bigtable.admin.v2.InstanceName.parse(targetInstance))
65+
.build();
66+
adminClient = BigtableTableAdminClient.create(adminSettings);
67+
}
68+
69+
@AfterClass
70+
public static void afterClass() throws Exception {
71+
garbageCollect();
72+
dataClient.close();
73+
adminClient.close();
74+
}
75+
76+
@Before
77+
public void setup() throws IOException {
78+
if (adminClient == null || dataClient == null) {
79+
throw new AssumptionViolatedException(
80+
INSTANCE_PROPERTY_NAME + " property is not set, skipping integration tests.");
81+
}
82+
tableId = generateTableId();
83+
helloWorld = new HelloWorld(instanceName.getProject(), instanceName.getInstance(), tableId);
84+
adminClient.createTable(CreateTableRequest.of(tableId).addFamily("cf1"));
85+
}
86+
87+
@After
88+
public void after() {
89+
if (adminClient.exists(tableId)) {
90+
adminClient.deleteTable(tableId);
91+
}
92+
}
93+
94+
@Test
95+
public void testCreateAndDeleteTable() throws IOException {
96+
// Create table
97+
String fakeTable = generateTableId();
98+
HelloWorld testHelloWorld =
99+
new HelloWorld(instanceName.getProject(), instanceName.getInstance(), fakeTable);
100+
testHelloWorld.createTable();
101+
assertTrue(adminClient.exists(fakeTable));
102+
103+
// Delete table
104+
testHelloWorld.deleteTable();
105+
assertTrue(!adminClient.exists(fakeTable));
106+
}
107+
108+
@Test
109+
public void testWriteToTable() {
110+
// Write to table
111+
helloWorld.writeToTable();
112+
Row row = dataClient.readRow(tableId, "rowKey0");
113+
assertNotNull(row);
114+
}
115+
116+
// TODO: add test for helloWorld.readSingleRow()
117+
// TODO: add test for helloWorld.readTable()
118+
119+
@Test
120+
public void testRunDoesNotFail() throws Exception {
121+
helloWorld.run();
122+
}
123+
124+
private String generateTableId() {
125+
return String.format(
126+
"%s-%016x-%x", TABLE_PREFIX, System.currentTimeMillis(), new Random().nextLong());
127+
}
128+
129+
private static void garbageCollect() {
130+
Pattern timestampPattern = Pattern.compile(TABLE_PREFIX + "-([0-9a-f]+)-([0-9a-f]+)");
131+
for (String tableId : adminClient.listTables()) {
132+
Matcher matcher = timestampPattern.matcher(tableId);
133+
if (!matcher.matches()) {
134+
continue;
135+
}
136+
String timestampStr = matcher.group(1);
137+
long timestamp = Long.parseLong(timestampStr, 16);
138+
if (System.currentTimeMillis() - timestamp < TimeUnit.MINUTES.toMillis(15)) {
139+
continue;
140+
}
141+
System.out.println("\nGarbage collecting orphaned table: " + tableId);
142+
adminClient.deleteTable(tableId);
143+
}
144+
}
145+
}

0 commit comments

Comments
 (0)