[examples] Improve the basic Java example

This improves the Java example in a bunch of ways:

1. Renames java-sample -> java-example.
2. Renames class to org.apache.kudu.examples.Example.
3. Adds licenses everywhere.
4. Rewrites the README, using adoc format.
5. Updates the pom, including syncing some plugin versions with
   java/pom and updating the version of the client the example uses.
6. Expands and improves the Example class:
   - Adds range partitioning with split rows.
   - Adds an alter table example.
   - Scans with a predicate and checks the results.

Change-Id: I79ab5b0b2c30e8fd7c799857a0e3754b7618a580
Reviewed-on: http://gerrit.cloudera.org:8080/9852
Reviewed-by: Adar Dembo <a...@cloudera.com>
Tested-by: Will Berkeley <wdberke...@gmail.com>


Project: http://git-wip-us.apache.org/repos/asf/kudu/repo
Commit: http://git-wip-us.apache.org/repos/asf/kudu/commit/c3684b6e
Tree: http://git-wip-us.apache.org/repos/asf/kudu/tree/c3684b6e
Diff: http://git-wip-us.apache.org/repos/asf/kudu/diff/c3684b6e

Branch: refs/heads/master
Commit: c3684b6e10ece50dd382d178e392a25e3130a86e
Parents: cc8c5e3
Author: Will Berkeley <wdberke...@apache.org>
Authored: Wed Mar 28 21:27:10 2018 -0700
Committer: Will Berkeley <wdberke...@gmail.com>
Committed: Tue Apr 3 04:30:29 2018 +0000

----------------------------------------------------------------------
 examples/java/java-example/README.adoc          |  46 ++++
 examples/java/java-example/pom.xml              |  78 +++++++
 .../java/org/apache/kudu/examples/Example.java  | 215 +++++++++++++++++++
 examples/java/java-sample/README                |  15 --
 examples/java/java-sample/pom.xml               |  72 -------
 .../java/org/kududb/examples/sample/Sample.java |  77 -------
 6 files changed, 339 insertions(+), 164 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/kudu/blob/c3684b6e/examples/java/java-example/README.adoc
----------------------------------------------------------------------
diff --git a/examples/java/java-example/README.adoc 
b/examples/java/java-example/README.adoc
new file mode 100644
index 0000000..950c4e5
--- /dev/null
+++ b/examples/java/java-example/README.adoc
@@ -0,0 +1,46 @@
+// 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.
+
+= Kudu Java client example README
+:author: Kudu Team
+:homepage: https://kudu.apache.org/
+
+This is an example program that uses the synchronous Kudu Java client APIs to
+
+- Create a table
+- Insert some rows
+- Alter the table
+- Scan some rows
+- Delete the table
+
+To build and run, ensure maven is installed and from the java-example 
directory run:
+
+[source,bash]
+----
+$ mvn package
+$ java -jar target/kudu-java-example-1.0-SNAPSHOT.jar
+----
+
+By default, the example assumes the Kudu cluster has a single master running on
+localhost with the default port 7051. To specify a different set of masters for
+Kudu cluster, set the property `kuduMasters` to a CSV of the master addresses 
in
+the form `host:port`, as shown:
+
+[source,bash]
+----
+$ java -DkuduMasters=master-0:7051,master-1:7051,master-2:7051 -jar 
target/kudu-java-example-1.0-SNAPSHOT.jar
+----

http://git-wip-us.apache.org/repos/asf/kudu/blob/c3684b6e/examples/java/java-example/pom.xml
----------------------------------------------------------------------
diff --git a/examples/java/java-example/pom.xml 
b/examples/java/java-example/pom.xml
new file mode 100644
index 0000000..67b0754
--- /dev/null
+++ b/examples/java/java-example/pom.xml
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+//
+// 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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/maven-v4_0_0.xsd";>
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>org.apache.kudu</groupId>
+  <artifactId>kudu-java-example</artifactId>
+  <packaging>jar</packaging>
+  <version>1.0-SNAPSHOT</version>
+  <name>Kudu Java Client Examples</name>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <version>3.6.2</version>
+        <configuration>
+          <source>1.7</source>
+          <target>1.7</target>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-shade-plugin</artifactId>
+        <version>3.0.0</version>
+        <executions>
+          <execution>
+            <phase>package</phase>
+            <goals>
+              <goal>shade</goal>
+            </goals>
+            <configuration>
+              <transformers>
+                <transformer 
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
+                  <mainClass>org.apache.kudu.examples.Example</mainClass>
+                </transformer>
+              </transformers>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.kudu</groupId>
+      <artifactId>kudu-client</artifactId>
+      <version>1.7.0</version>
+    </dependency>
+
+    <!-- For logging messages. -->
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-simple</artifactId>
+      <version>1.7.25</version>
+    </dependency>
+  </dependencies>
+</project>

http://git-wip-us.apache.org/repos/asf/kudu/blob/c3684b6e/examples/java/java-example/src/main/java/org/apache/kudu/examples/Example.java
----------------------------------------------------------------------
diff --git 
a/examples/java/java-example/src/main/java/org/apache/kudu/examples/Example.java
 
b/examples/java/java-example/src/main/java/org/apache/kudu/examples/Example.java
new file mode 100644
index 0000000..0805c12
--- /dev/null
+++ 
b/examples/java/java-example/src/main/java/org/apache/kudu/examples/Example.java
@@ -0,0 +1,215 @@
+// 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 org.apache.kudu.examples;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.kudu.ColumnSchema;
+import org.apache.kudu.Schema;
+import org.apache.kudu.Type;
+import org.apache.kudu.client.AlterTableOptions;
+import org.apache.kudu.client.CreateTableOptions;
+import org.apache.kudu.client.Insert;
+import org.apache.kudu.client.KuduClient;
+import org.apache.kudu.client.KuduException;
+import org.apache.kudu.client.KuduPredicate;
+import org.apache.kudu.client.KuduPredicate.ComparisonOp;
+import org.apache.kudu.client.KuduScanner;
+import org.apache.kudu.client.KuduSession;
+import org.apache.kudu.client.KuduTable;
+import org.apache.kudu.client.PartialRow;
+import org.apache.kudu.client.RowResult;
+import org.apache.kudu.client.RowResultIterator;
+
+/*
+ * A simple example of using the synchronous Kudu Java client to
+ * - Create a table.
+ * - Insert rows.
+ * - Alter a table.
+ * - Scan rows.
+ * - Delete a table.
+ */
+public class Example {
+  private static final Double DEFAULT_DOUBLE = 12.345;
+  private static final String KUDU_MASTERS = System.getProperty("kuduMasters", 
"localhost:7051");
+
+  private static void createExampleTable(KuduClient client, String tableName)  
throws KuduException {
+    // Set up a simple schema.
+    List<ColumnSchema> columns = new ArrayList<>(2);
+    columns.add(new ColumnSchema.ColumnSchemaBuilder("key", Type.INT32)
+        .key(true)
+        .build());
+    columns.add(new ColumnSchema.ColumnSchemaBuilder("value", 
Type.STRING).nullable(true)
+        .build());
+    Schema schema = new Schema(columns);
+
+    // Set up the partition schema, which distributes rows to different 
tablets by hash.
+    // Kudu also supports partitioning by key range. Hash and range 
partitioning can be combined.
+    // For more information, see 
http://kudu.apache.org/docs/schema_design.html.
+    CreateTableOptions cto = new CreateTableOptions();
+    List<String> hashKeys = new ArrayList<>(1);
+    hashKeys.add("key");
+    int numBuckets = 8;
+    cto.addHashPartitions(hashKeys, numBuckets);
+
+    // Create the table.
+    client.createTable(tableName, schema, cto);
+    System.out.println("Created table " + tableName);
+  }
+
+  private static void insertRows(KuduClient client, String tableName, int 
numRows) throws KuduException {
+    // Open the newly-created table and create a KuduSession.
+    KuduTable table = client.openTable(tableName);
+    KuduSession session = client.newSession();
+    for (int i = 0; i < numRows; i++) {
+      Insert insert = table.newInsert();
+      PartialRow row = insert.getRow();
+      row.addInt("key", i);
+      // Make even-keyed row have a null 'value'.
+      if (i % 2 == 0) {
+        row.setNull("value");
+      } else {
+        row.addString("value", "value " + i);
+      }
+      session.apply(insert);
+    }
+
+    // Call session.close() to end the session and ensure the rows are
+    // flushed and errors are returned.
+    // You can also call session.flush() to do the same without ending the 
session.
+    // When flushing in AUTO_FLUSH_BACKGROUND mode (the default mode 
recommended
+    // for most workloads, you must check the pending errors as shown below, 
since
+    // write operations are flushed to Kudu in background threads.
+    session.close();
+    if (session.countPendingErrors() != 0) {
+      System.out.println("errors inserting rows");
+      org.apache.kudu.client.RowErrorsAndOverflowStatus roStatus = 
session.getPendingErrors();
+      org.apache.kudu.client.RowError[] errs = roStatus.getRowErrors();
+      int numErrs = Math.min(errs.length, 5);
+      System.out.println("there were errors inserting rows to Kudu");
+      System.out.println("the first few errors follow:");
+      for (int i = 0; i < numErrs; i++) {
+        System.out.println(errs[i]);
+      }
+      if (roStatus.isOverflowed()) {
+        System.out.println("error buffer overflowed: some errors were 
discarded");
+      }
+      throw new RuntimeException("error inserting rows to Kudu");
+    }
+    System.out.println("Inserted " + numRows + " rows");
+  }
+
+  private static void scanTableAndCheckResults(KuduClient client, String 
tableName, int numRows) throws KuduException {
+    KuduTable table = client.openTable(tableName);
+    Schema schema = table.getSchema();
+
+    // Scan with a predicate on the 'key' column, returning the 'value' and 
"added" columns.
+    List<String> projectColumns = new ArrayList<>(2);
+    projectColumns.add("key");
+    projectColumns.add("value");
+    projectColumns.add("added");
+    int lowerBound = 0;
+    KuduPredicate lowerPred = KuduPredicate.newComparisonPredicate(
+        schema.getColumn("key"),
+        ComparisonOp.GREATER_EQUAL,
+        lowerBound);
+    int upperBound = numRows / 2;
+    KuduPredicate upperPred = KuduPredicate.newComparisonPredicate(
+        schema.getColumn("key"),
+        ComparisonOp.LESS,
+        upperBound);
+    KuduScanner scanner = client.newScannerBuilder(table)
+        .setProjectedColumnNames(projectColumns)
+        .addPredicate(lowerPred)
+        .addPredicate(upperPred)
+        .build();
+
+    // Check the correct number of values and null values are returned, and
+    // that the default value was set for the new column on each row.
+    // Note: scanning a hash-partitioned table will not return results in 
primary key order.
+    int resultCount = 0;
+    int nullCount = 0;
+    while (scanner.hasMoreRows()) {
+      RowResultIterator results = scanner.nextRows();
+      while (results.hasNext()) {
+        RowResult result = results.next();
+        if (result.isNull("value")) {
+          nullCount++;
+        }
+        double added = result.getDouble("added");
+        if (added != DEFAULT_DOUBLE) {
+          throw new RuntimeException("expected added=" + DEFAULT_DOUBLE +
+              " but got added= " + added);
+        }
+        resultCount++;
+      }
+    }
+    int expectedResultCount = upperBound - lowerBound;
+    if (resultCount != expectedResultCount) {
+      throw new RuntimeException("scan error: expected " + expectedResultCount 
+
+          " results but got " + resultCount + " results");
+    }
+    int expectedNullCount = expectedResultCount / 2 + (numRows % 2 == 0 ? 1 : 
0);
+    if (nullCount != expectedNullCount) {
+      throw new RuntimeException("scan error: expected " + expectedNullCount +
+          " rows with value=null but found " + nullCount);
+    }
+    System.out.println("Scanned some rows and checked the results");
+  }
+
+  public static void main(String[] args) {
+    System.out.println("-----------------------------------------------");
+    System.out.println("Will try to connect to Kudu master(s) at " + 
KUDU_MASTERS);
+    System.out.println("Run with -DkuduMasters=master-0:port,master-1:port,... 
to override.");
+    System.out.println("-----------------------------------------------");
+    String tableName = "java_example-" + System.currentTimeMillis();
+    KuduClient client = new KuduClient.KuduClientBuilder(KUDU_MASTERS).build();
+
+    try {
+      createExampleTable(client, tableName);
+
+      int numRows = 150;
+      insertRows(client, tableName, numRows);
+
+      // Alter the table, adding a column with a default value.
+      // Note: after altering the table, the table needs to be re-opened.
+      AlterTableOptions ato = new AlterTableOptions();
+      ato.addColumn("added", org.apache.kudu.Type.DOUBLE, DEFAULT_DOUBLE);
+      client.alterTable(tableName, ato);
+      System.out.println("Altered the table");
+
+      scanTableAndCheckResults(client, tableName, numRows);
+    } catch (Exception e) {
+      e.printStackTrace();
+    } finally {
+      try {
+        client.deleteTable(tableName);
+        System.out.println("Deleted the table");
+      } catch (Exception e) {
+        e.printStackTrace();
+      } finally {
+        try {
+          client.shutdown();
+        } catch (Exception e) {
+          e.printStackTrace();
+        }
+      }
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/kudu/blob/c3684b6e/examples/java/java-sample/README
----------------------------------------------------------------------
diff --git a/examples/java/java-sample/README b/examples/java/java-sample/README
deleted file mode 100644
index 71cd034..0000000
--- a/examples/java/java-sample/README
+++ /dev/null
@@ -1,15 +0,0 @@
-Here's a Java client sample that creates a table, writes some data, scans it, 
and then deletes
-its table.
-
-
-To build and run, do the following:
-
-$ mvn package
-$ java -jar target/kudu-java-sample-1.0-SNAPSHOT.jar
-
-This example assumes that you are running the Quickstart VM with the host name
-"quickstart.cloudera". If you are running against a different cluster, pass the
-host name of the Kudu Master using a Java property:
-
-$ java -DkuduMaster=a1216.halxg.cloudera.com -jar 
target/kudu-java-sample-1.0-SNAPSHOT.jar
-

http://git-wip-us.apache.org/repos/asf/kudu/blob/c3684b6e/examples/java/java-sample/pom.xml
----------------------------------------------------------------------
diff --git a/examples/java/java-sample/pom.xml 
b/examples/java/java-sample/pom.xml
deleted file mode 100644
index b078b04..0000000
--- a/examples/java/java-sample/pom.xml
+++ /dev/null
@@ -1,72 +0,0 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
-  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/maven-v4_0_0.xsd";>
-  <modelVersion>4.0.0</modelVersion>
-  <groupId>kudu-java-sample</groupId>
-  <artifactId>kudu-java-sample</artifactId>
-  <packaging>jar</packaging>
-  <version>1.0-SNAPSHOT</version>
-  <name>kudu-java-sample</name>
-
-  <build>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-compiler-plugin</artifactId>
-        <version>2.3.1</version>
-        <configuration>
-          <source>1.7</source>
-          <target>1.7</target>
-        </configuration>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-shade-plugin</artifactId>
-        <version>2.4</version>
-        <executions>
-          <execution>
-            <phase>package</phase>
-            <goals>
-              <goal>shade</goal>
-            </goals>
-            <configuration>
-              <transformers>
-                <transformer 
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
-                  <mainClass>org.kududb.examples.sample.Sample</mainClass>
-                </transformer>
-              </transformers>
-            </configuration>
-          </execution>
-        </executions>
-      </plugin>
-    </plugins>
-  </build>
-
-  <repositories>
-    <repository>
-      <id>cdh.repo</id>
-      <name>Cloudera Repositories</name>
-      <url>https://repository.cloudera.com/artifactory/cloudera-repos</url>
-      <snapshots>
-        <enabled>false</enabled>
-      </snapshots>
-    </repository>
-  </repositories>
-
-  <dependencies>
-
-    <dependency>
-      <groupId>org.apache.kudu</groupId>
-      <artifactId>kudu-client</artifactId>
-      <version>1.1.0</version>
-    </dependency>
-
-    <!-- for logging messages -->
-    <dependency>
-      <groupId>org.slf4j</groupId>
-      <artifactId>slf4j-simple</artifactId>
-      <version>1.7.12</version>
-    </dependency>
-
-  </dependencies>
-
-</project>

http://git-wip-us.apache.org/repos/asf/kudu/blob/c3684b6e/examples/java/java-sample/src/main/java/org/kududb/examples/sample/Sample.java
----------------------------------------------------------------------
diff --git 
a/examples/java/java-sample/src/main/java/org/kududb/examples/sample/Sample.java
 
b/examples/java/java-sample/src/main/java/org/kududb/examples/sample/Sample.java
deleted file mode 100644
index 5c5285f..0000000
--- 
a/examples/java/java-sample/src/main/java/org/kududb/examples/sample/Sample.java
+++ /dev/null
@@ -1,77 +0,0 @@
-package org.kududb.examples.sample;
-
-import org.apache.kudu.ColumnSchema;
-import org.apache.kudu.Schema;
-import org.apache.kudu.Type;
-import org.apache.kudu.client.*;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class Sample {
-
-  private static final String KUDU_MASTER = System.getProperty(
-      "kuduMaster", "quickstart.cloudera");
-
-  public static void main(String[] args) {
-    System.out.println("-----------------------------------------------");
-    System.out.println("Will try to connect to Kudu master at " + KUDU_MASTER);
-    System.out.println("Run with -DkuduMaster=myHost:port to override.");
-    System.out.println("-----------------------------------------------");
-    String tableName = "java_sample-" + System.currentTimeMillis();
-    KuduClient client = new KuduClient.KuduClientBuilder(KUDU_MASTER).build();
-
-    try {
-      List<ColumnSchema> columns = new ArrayList(2);
-      columns.add(new ColumnSchema.ColumnSchemaBuilder("key", Type.INT32)
-          .key(true)
-          .build());
-      columns.add(new ColumnSchema.ColumnSchemaBuilder("value", Type.STRING)
-          .build());
-      List<String> rangeKeys = new ArrayList<>();
-      rangeKeys.add("key");
-
-      Schema schema = new Schema(columns);
-      client.createTable(tableName, schema,
-                         new 
CreateTableOptions().setRangePartitionColumns(rangeKeys));
-
-      KuduTable table = client.openTable(tableName);
-      KuduSession session = client.newSession();
-      for (int i = 0; i < 3; i++) {
-        Insert insert = table.newInsert();
-        PartialRow row = insert.getRow();
-        row.addInt(0, i);
-        row.addString(1, "value " + i);
-        session.apply(insert);
-      }
-
-      List<String> projectColumns = new ArrayList<>(1);
-      projectColumns.add("value");
-      KuduScanner scanner = client.newScannerBuilder(table)
-          .setProjectedColumnNames(projectColumns)
-          .build();
-      while (scanner.hasMoreRows()) {
-        RowResultIterator results = scanner.nextRows();
-        while (results.hasNext()) {
-          RowResult result = results.next();
-          System.out.println(result.getString(0));
-        }
-      }
-    } catch (Exception e) {
-      e.printStackTrace();
-    } finally {
-      try {
-        client.deleteTable(tableName);
-      } catch (Exception e) {
-        e.printStackTrace();
-      } finally {
-        try {
-          client.shutdown();
-        } catch (Exception e) {
-          e.printStackTrace();
-        }
-      }
-    }
-  }
-}
-

Reply via email to