diff --git a/java/pom.xml b/java/pom.xml index f97a60d6..9d1a36c8 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -36,6 +36,7 @@ limitations under the License. dataproc-wordcount gae-flexible-helloworld hello-world + tracing-hello-world metric-scaler simple-cli simple-performance-test diff --git a/java/tracing-hello-world/README.md b/java/tracing-hello-world/README.md new file mode 100644 index 00000000..9f3eb018 --- /dev/null +++ b/java/tracing-hello-world/README.md @@ -0,0 +1,266 @@ +# Cloud Bigtable Hello World with Tracing + +This application builds on top of the [basic Cloud Bigtable hello world example](../hello-world). +This project adds automatic exports of [tracing to stackdriver](https://cloud.google.com/trace/) and +[Z-Pages](https://github.com/census-instrumentation/opencensus-java/tree/master/contrib/zpages) that +show information about traces on the local machine. + +See the [documentation for this +sample](https://cloud.google.com/bigtable/docs/samples-java-hello) for a brief +explanation of the hello world code. + + + + +**Table of Contents** + +- [Downloading the sample](#downloading-the-sample) +- [Costs](#costs) +- [Before you begin](#before-you-begin) + - [Installing Maven](#installing-maven) + - [Creating a Project in the Google Cloud Platform Console](#creating-a-project-in-the-google-cloud-platform-console) + - [Enabling billing for your project.](#enabling-billing-for-your-project) + - [Install the Google Cloud SDK.](#install-the-google-cloud-sdk) + - [Setting Google Application Default Credentials](#setting-google-application-default-credentials) +- [Provisioning an instance](#provisioning-an-instance) +- [Running the application](#running-the-application) +- [Cleaning up](#cleaning-up) + + + + +## Downloading the sample + +Download the sample app and navigate into the app directory: + +1. Clone the [Cloud Bigtable examples repository][github-repo], to your local + machine: + + git clone https://github.com/GoogleCloudPlatform/cloud-bigtable-examples.git + + Alternatively, you can [download the sample][github-zip] as a zip file and + extract it. + +2. Change to the Hello World code sample directory. + + cd cloud-bigtable-examples/java/tracing-hello-world + +[github-repo]: https://github.com/GoogleCloudPlatform/cloud-bigtable-examples +[github-zip]: https://github.com/GoogleCloudPlatform/cloud-bigtable-examples/archive/master.zip + + +## Costs + +This sample uses billable components of Cloud Platform, including: + ++ Google Cloud Bigtable + +Use the [Pricing Calculator][bigtable-pricing] to generate a cost estimate +based on your projected usage. New Cloud Platform users might be eligible for +a [free trial][free-trial]. + +[bigtable-pricing]: https://cloud.google.com/products/calculator/#id=1eb47664-13a2-4be1-9d16-6722902a7572 +[free-trial]: https://cloud.google.com/free-trial + + +## Before you begin + +This sample assumes you have [Java 8][java8] JDK installed. + +[java8]: http://www.oracle.com/technetwork/java/javase/downloads/ + +### Installing Maven + +These samples use the [Apache Maven][maven] build system. Before getting +started, be sure to [download][maven-download] and [install][maven-install] it. +When you use Maven as described here, it will automatically download the needed +client libraries. + +[maven]: https://maven.apache.org +[maven-download]: https://maven.apache.org/download.cgi +[maven-install]: https://maven.apache.org/install.html + +### Creating a Project in the Google Cloud Platform Console + +If you haven't already created a project, create one now. Projects enable you to +manage all Google Cloud Platform resources for your app, including deployment, +access control, billing, and services. + +1. Open the [Cloud Platform Console][cloud-console]. +1. In the drop-down menu at the top, select **Create a project**. +1. Give your project a name. +1. Make a note of the project ID, which might be different from the project + name. The project ID is used in commands and in configurations. + +[cloud-console]: https://console.cloud.google.com/ + +### Enabling billing for your project. + +If you haven't already enabled billing for your project, [enable +billing][enable-billing] now. Enabling billing allows is required to use Cloud Bigtable +and to create VM instances. + +[enable-billing]: https://console.cloud.google.com/project/_/settings + +### Install the Google Cloud SDK. + +If you haven't already installed the Google Cloud SDK, [install the Google +Cloud SDK][cloud-sdk] now. The SDK contains tools and libraries that enable you +to create and manage resources on Google Cloud Platform. + +[cloud-sdk]: https://cloud.google.com/sdk/ + +### Setting Google Application Default Credentials + +Set your [Google Application Default +Credentials][application-default-credentials] by [initializing the Google Cloud +SDK][cloud-sdk-init] with the command: + + gcloud init + +Generate a credentials file by running the [application-default login](https://cloud.google.com/sdk/gcloud/reference/auth/application-default/login) command: + + gcloud auth application-default login + +[cloud-sdk-init]: https://cloud.google.com/sdk/docs/initializing +[application-default-credentials]: https://developers.google.com/identity/protocols/application-default-credentials + + +## Provisioning an instance + +Follow the instructions in the [user +documentation](https://cloud.google.com/bigtable/docs/creating-instance) to +create a Google Cloud Platform project and Cloud Bigtable instance if necessary. +You'll need to reference your project id and instance id to run the +application. + + +## Running the application + +Build and run the sample using Maven. + + mvn package + mvn exec:java -Dbigtable.projectID=GCLOUDPROJECT -Dbigtable.instanceID=BIGTABLEINSTANCE + +You will see output resembling the following, interspersed with informational logging +from the underlying libraries: + + HelloWorld: Create table Hello-Bigtable + HelloWorld: Write some greetings to the table + HelloWorld: Scan for all greetings: + Hello World! + Hello Cloud Bigtable! + Hello HBase! + HelloWorld: Delete the table + +## View Z-Pages + +Open [http://localhost:8080/tracez](http://localhost:8080/trace) to see a local rendering +of trace information + +## View Stackdriver tracing + +Open [Stackriver traces](https://pantheon.corp.google.com/traces/traces) to see traces +in the Google Cloud Console. + +## Pom.xml + +Setting up the [pom.xml](pom.xml) is as follows. + +NOTE: cloud-bigtable-hbase-1.x-hadoop, cloud-bigtable-dataflow and cloud-bigtable-beam +do not require this configuration, since they already include +[shaded](https://maven.apache.org/plugins/maven-shade-plugin/) versions of tracing dependencies. + +```xml + + + + + + io.opencensus + opencensus-impl + ${opencensus.version} + + + io.grpc + * + + + + + + + io.opencensus + opencensus-contrib-zpages + ${opencensus.version} + + + io.grpc + * + + + + + + + io.opencensus + opencensus-exporter-trace-stackdriver + ${opencensus.version} + + + io.grpc + * + + + io.netty + * + + + +``` + +## Java code + +Here is the code from [HelloWorld](src/main/java/com/example/cloud/bigtable/helloworld/HelloWorld.java) +that sets up tracing + +```java + + // Force tracing for every request for demo purposes. + Tracing.getTraceConfig().updateActiveTraceParams( + TraceParams.DEFAULT.toBuilder().setSampler(Samplers.probabilitySampler(1)).build()); + + // HBase Bigtable specific setup for zpages + HBaseTracingUtilities.setupTracingConfig(); + + StackdriverExporter.createAndRegisterWithProjectId(projectId); + + // Start a web server on port 8080 for tracing data + ZPageHandlers.startHttpServerAndRegisterAll(8080); + + doHelloWorld(projectId, instanceId); + + System.out.println("Sleeping for 1 minute so that you can view http://localhost:8080/tracez"); + // Sleep for 1 minute. + Thread.sleep(TimeUnit.MINUTES.toSeconds(1)); + +``` + +## Cleaning up + +To avoid incurring extra charges to your Google Cloud Platform account, remove +the resources created for this sample. + +1. Go to the Clusters page in the [Cloud + Console](https://console.cloud.google.com). + + [Go to the Clusters page](https://console.cloud.google.com/project/_/bigtable/clusters) + +1. Click the cluster name. + +1. Click **Delete**. + + ![Delete](https://cloud.google.com/bigtable/img/delete-quickstart-cluster.png) + +1. Type the cluster ID, then click **Delete** to delete the cluster. + diff --git a/java/tracing-hello-world/pom.xml b/java/tracing-hello-world/pom.xml new file mode 100644 index 00000000..e4fa7087 --- /dev/null +++ b/java/tracing-hello-world/pom.xml @@ -0,0 +1,116 @@ + + + + 4.0.0 + com.example.bigtable.helloworld + cloud-bigtable-tracing-hello-world + + jar + 1.0-SNAPSHOT + cloud-bigtable-tracing-hello-world + http://maven.apache.org + + + com.google.cloud + bigtable-samples + 1.0.0 + .. + + + + 1.0.0 + 0.7.0 + 1.8 + 1.8 + + + + + snapshots-repo + https://oss.sonatype.org/content/repositories/snapshots + false + true + + + + + + com.google.cloud.bigtable + bigtable-hbase-1.x + ${bigtable.version} + + + + + + + io.opencensus + opencensus-impl + ${opencensus.version} + + + io.grpc + * + + + + + + + io.opencensus + opencensus-contrib-zpages + ${opencensus.version} + + + io.grpc + * + + + + + + + io.opencensus + opencensus-exporter-trace-stackdriver + ${opencensus.version} + + + io.grpc + * + + + io.netty + * + + + + + + + + + + org.codehaus.mojo + exec-maven-plugin + 1.5.0 + + com.example.cloud.bigtable.helloworld.HelloWorld + + + + + diff --git a/java/tracing-hello-world/src/main/java/com/example/cloud/bigtable/helloworld/HelloWorld.java b/java/tracing-hello-world/src/main/java/com/example/cloud/bigtable/helloworld/HelloWorld.java new file mode 100644 index 00000000..8b224bc3 --- /dev/null +++ b/java/tracing-hello-world/src/main/java/com/example/cloud/bigtable/helloworld/HelloWorld.java @@ -0,0 +1,181 @@ +/** + * Copyright 2017 Google Inc. All Rights Reserved. + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.cloud.bigtable.helloworld; + +import com.google.cloud.bigtable.hbase.BigtableConfiguration; +import com.google.cloud.bigtable.hbase.util.HBaseTracingUtilities; + +import io.opencensus.contrib.zpages.ZPageHandlers; +import io.opencensus.exporter.trace.stackdriver.StackdriverExporter; +import io.opencensus.trace.Tracing; +import io.opencensus.trace.config.TraceParams; +import io.opencensus.trace.samplers.Samplers; + +import org.apache.hadoop.hbase.HColumnDescriptor; +import org.apache.hadoop.hbase.HTableDescriptor; +import org.apache.hadoop.hbase.TableName; +import org.apache.hadoop.hbase.client.Admin; +import org.apache.hadoop.hbase.client.Connection; +import org.apache.hadoop.hbase.client.Get; +import org.apache.hadoop.hbase.client.Put; +import org.apache.hadoop.hbase.client.Result; +import org.apache.hadoop.hbase.client.ResultScanner; +import org.apache.hadoop.hbase.client.Scan; +import org.apache.hadoop.hbase.client.Table; +import org.apache.hadoop.hbase.util.Bytes; + +import java.io.IOException; +import java.util.concurrent.TimeUnit; + +/** + * A minimal application that connects to Cloud Bigtable using the native HBase API + * and performs some basic operations. + */ +public class HelloWorld { + + // Refer to table metadata names by byte array in the HBase API + private static final byte[] TABLE_NAME = Bytes.toBytes("Hello-Bigtable"); + private static final byte[] COLUMN_FAMILY_NAME = Bytes.toBytes("cf1"); + private static final byte[] COLUMN_NAME = Bytes.toBytes("greeting"); + + // Write some friendly greetings to Cloud Bigtable + private static final String[] GREETINGS = + { "Hello World!", "Hello Cloud Bigtable!", "Hello HBase!" }; + + /** + * Connects to Cloud Bigtable, runs some basic operations and prints the results. + */ + private static void doHelloWorld(String projectId, String instanceId) { + + // [START connecting_to_bigtable] + // Create the Bigtable connection, use try-with-resources to make sure it gets closed + try (Connection connection = BigtableConfiguration.connect(projectId, instanceId)) { + + // The admin API lets us create, manage and delete tables + Admin admin = connection.getAdmin(); + // [END connecting_to_bigtable] + + // [START creating_a_table] + // Create a table with a single column family + HTableDescriptor descriptor = new HTableDescriptor(TableName.valueOf(TABLE_NAME)); + descriptor.addFamily(new HColumnDescriptor(COLUMN_FAMILY_NAME)); + + print("Create table " + descriptor.getNameAsString()); + admin.createTable(descriptor); + // [END creating_a_table] + + // [START writing_rows] + // Retrieve the table we just created so we can do some reads and writes + Table table = connection.getTable(TableName.valueOf(TABLE_NAME)); + + // Write some rows to the table + print("Write some greetings to the table"); + for (int i = 0; i < GREETINGS.length; i++) { + // Each row has a unique row key. + // + // Note: This example uses sequential numeric IDs for simplicity, but + // this can result in poor performance in a production application. + // Since rows are stored in sorted order by key, sequential keys can + // result in poor distribution of operations across nodes. + // + // For more information about how to design a Bigtable schema for the + // best performance, see the documentation: + // + // https://cloud.google.com/bigtable/docs/schema-design + String rowKey = "greeting" + i; + + // Put a single row into the table. We could also pass a list of Puts to write a batch. + Put put = new Put(Bytes.toBytes(rowKey)); + put.addColumn(COLUMN_FAMILY_NAME, COLUMN_NAME, Bytes.toBytes(GREETINGS[i])); + table.put(put); + } + // [END writing_rows] + + // [START getting_a_row] + // Get the first greeting by row key + String rowKey = "greeting0"; + Result getResult = table.get(new Get(Bytes.toBytes(rowKey))); + String greeting = Bytes.toString(getResult.getValue(COLUMN_FAMILY_NAME, COLUMN_NAME)); + System.out.println("Get a single greeting by row key"); + System.out.printf("\t%s = %s\n", rowKey, greeting); + // [END getting_a_row] + + // [START scanning_all_rows] + // Now scan across all rows. + Scan scan = new Scan(); + + print("Scan for all greetings:"); + ResultScanner scanner = table.getScanner(scan); + for (Result row : scanner) { + byte[] valueBytes = row.getValue(COLUMN_FAMILY_NAME, COLUMN_NAME); + System.out.println('\t' + Bytes.toString(valueBytes)); + } + // [END scanning_all_rows] + + // [START deleting_a_table] + // Clean up by disabling and then deleting the table + print("Delete the table"); + admin.disableTable(table.getName()); + admin.deleteTable(table.getName()); + // [END deleting_a_table] + + } catch (IOException e) { + System.err.println("Exception while running HelloWorld: " + e.getMessage()); + e.printStackTrace(); + } + } + + private static void print(String msg) { + System.out.println("HelloWorld: " + msg); + } + + public static void main(String[] args) throws IOException, InterruptedException { + // Consult system properties to get project/instance + String projectId = requiredProperty("bigtable.projectID"); + String instanceId = requiredProperty("bigtable.instanceID"); + + // Force tracing for every request for demo purposes. + Tracing.getTraceConfig().updateActiveTraceParams( + TraceParams.DEFAULT.toBuilder().setSampler(Samplers.probabilitySampler(1)).build()); + + // HBase Bigtable specific setup for zpages + HBaseTracingUtilities.setupTracingConfig(); + + StackdriverExporter.createAndRegisterWithProjectId(projectId); + + // Start a web server on port 8080 for tracing data + ZPageHandlers.startHttpServerAndRegisterAll(8080); + + doHelloWorld(projectId, instanceId); + + System.out.println("Sleeping for 1 minute so that you can view http://localhost:8080/tracez"); + // Sleep for 1 minute. + Thread.sleep(TimeUnit.MINUTES.toSeconds(1)); + } + + private static String requiredProperty(String prop) { + String value = System.getProperty(prop); + if (value == null) { + throw new IllegalArgumentException("Missing required system property: " + prop); + } + return value; + } + +}