You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by is...@apache.org on 2021/10/07 10:40:18 UTC

[ignite-3] branch main updated: IGNITE-15379 Add Java client examples. Add tests

This is an automated email from the ASF dual-hosted git repository.

isapego pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/ignite-3.git


The following commit(s) were added to refs/heads/main by this push:
     new 15ef025  IGNITE-15379 Add Java client examples. Add tests
15ef025 is described below

commit 15ef025ee3419a776cf29155a1602ddbc32d3072
Author: Igor Sapego <is...@apache.org>
AuthorDate: Thu Oct 7 12:38:25 2021 +0200

    IGNITE-15379 Add Java client examples. Add tests
    
    Fixes #384
---
 .../example/client/ClientKeyValueViewExample.java  | 121 ++++++++++++++++++++
 .../example/client/ClientRecordViewExample.java    | 122 +++++++++++++++++++++
 .../{ => example}/sql/jdbc/SqlJdbcExample.java     |   4 +-
 .../apache/ignite/example/ExampleTestUtils.java    |  93 ++++++++++++++++
 .../ClientExamplesTest.java}                       |  28 +++--
 .../jdbc/SqlExamplesTest.java}                     |  37 ++++---
 .../ignite/example/table/TableExamplesTest.java    |  18 ++-
 7 files changed, 393 insertions(+), 30 deletions(-)

diff --git a/examples/src/main/java/org/apache/ignite/example/client/ClientKeyValueViewExample.java b/examples/src/main/java/org/apache/ignite/example/client/ClientKeyValueViewExample.java
new file mode 100644
index 0000000..beb53df
--- /dev/null
+++ b/examples/src/main/java/org/apache/ignite/example/client/ClientKeyValueViewExample.java
@@ -0,0 +1,121 @@
+/*
+ * 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.ignite.example.client;
+
+import java.nio.file.Files;
+import java.nio.file.Path;
+import org.apache.ignite.Ignite;
+import org.apache.ignite.IgnitionManager;
+import org.apache.ignite.client.IgniteClient;
+import org.apache.ignite.internal.schema.configuration.SchemaConfigurationConverter;
+import org.apache.ignite.schema.SchemaBuilders;
+import org.apache.ignite.schema.definition.ColumnType;
+import org.apache.ignite.table.KeyValueView;
+import org.apache.ignite.table.Tuple;
+
+/**
+ * This example demonstrates the usage of the {@link KeyValueView} API of Java client.
+ * <p>
+ * To run the example, do the following:
+ * <ol>
+ *     <li>Import the examples project into you IDE.</li>
+ *     <li>
+ *         (optional) Run one or more standalone nodes using the CLI tool:<br>
+ *         {@code ignite node start --config=$IGNITE_HOME/examples/config/ignite-config.json node-1}<br>
+ *         {@code ignite node start --config=$IGNITE_HOME/examples/config/ignite-config.json node-2}<br>
+ *         {@code ...}<br>
+*          {@code ignite node start --config=$IGNITE_HOME/examples/config/ignite-config.json node-n}<br>
+ *     </li>
+ *     <li>Run the example in the IDE.</li>
+ * </ol>
+ */
+public class ClientKeyValueViewExample {
+    public static void main(String[] args) throws Exception {
+        try (Ignite ignite = IgnitionManager.start(
+            "node-0",
+            Files.readString(Path.of("config", "ignite-config.json")),
+            Path.of("work")
+        )) {
+
+            //---------------------------------------------------------------------------------
+            //
+            // Creating a table. The API call below is the equivalent of the following DDL:
+            //
+            //     CREATE TABLE accounts (
+            //         accountNumber INT PRIMARY KEY,
+            //         firstName     VARCHAR,
+            //         lastName      VARCHAR,
+            //         balance       DOUBLE
+            //     )
+            //
+            //---------------------------------------------------------------------------------
+
+            ignite.tables().createTable("PUBLIC.accounts", tbl ->
+                SchemaConfigurationConverter.convert(
+                    SchemaBuilders.tableBuilder("PUBLIC", "accounts")
+                        .columns(
+                            SchemaBuilders.column("accountNumber", ColumnType.INT32).asNonNull().build(),
+                            SchemaBuilders.column("firstName", ColumnType.string()).asNullable().build(),
+                            SchemaBuilders.column("lastName", ColumnType.string()).asNullable().build(),
+                            SchemaBuilders.column("balance", ColumnType.DOUBLE).asNullable().build()
+                        )
+                        .withPrimaryKey("accountNumber")
+                        .build(), tbl)
+                    .changeReplicas(1)
+                    .changePartitions(10)
+            );
+
+            try (IgniteClient client = IgniteClient.builder()
+                    .addresses("127.0.0.1:10800")
+                    .build()
+            ) {
+                KeyValueView<Tuple, Tuple> kvView = client.tables().table("PUBLIC.accounts").keyValueView();
+
+                //---------------------------------------------------------------------------------
+                //
+                // Tuple API: insert operation.
+                //
+                //---------------------------------------------------------------------------------
+
+                Tuple key = Tuple.create()
+                    .set("accountNumber", 123456);
+
+                Tuple value = Tuple.create()
+                    .set("firstName", "Val")
+                    .set("lastName", "Kulichenko")
+                    .set("balance", 100.00d);
+
+                kvView.put(key, value);
+
+                //---------------------------------------------------------------------------------
+                //
+                // Tuple API: get operation.
+                //
+                //---------------------------------------------------------------------------------
+
+                value = kvView.get(key);
+
+                System.out.println(
+                    "Retrieved using Key-Value API\n" +
+                        "    Account Number: " + key.intValue("accountNumber") + '\n' +
+                        "    Owner: " + value.stringValue("firstName") + " " + value.stringValue("lastName") + '\n' +
+                        "    Balance: $" + value.doubleValue("balance"));
+            }
+        }
+    }
+}
diff --git a/examples/src/main/java/org/apache/ignite/example/client/ClientRecordViewExample.java b/examples/src/main/java/org/apache/ignite/example/client/ClientRecordViewExample.java
new file mode 100644
index 0000000..a32dd89
--- /dev/null
+++ b/examples/src/main/java/org/apache/ignite/example/client/ClientRecordViewExample.java
@@ -0,0 +1,122 @@
+/*
+ * 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.ignite.example.client;
+
+import java.nio.file.Files;
+import java.nio.file.Path;
+import org.apache.ignite.Ignite;
+import org.apache.ignite.IgnitionManager;
+import org.apache.ignite.client.IgniteClient;
+import org.apache.ignite.internal.schema.configuration.SchemaConfigurationConverter;
+import org.apache.ignite.schema.SchemaBuilders;
+import org.apache.ignite.schema.definition.ColumnType;
+import org.apache.ignite.table.RecordView;
+import org.apache.ignite.table.Table;
+import org.apache.ignite.table.Tuple;
+
+/**
+ * This example demonstrates the usage of the {@link Table} API of Java client.
+ * <p>
+ * To run the example, do the following:
+ * <ol>
+ *     <li>Import the examples project into you IDE.</li>
+ *     <li>
+ *         (optional) Run one or more standalone nodes using the CLI tool:<br>
+ *         {@code ignite node start --config=$IGNITE_HOME/examples/config/ignite-config.json node-1}<br>
+ *         {@code ignite node start --config=$IGNITE_HOME/examples/config/ignite-config.json node-2}<br>
+ *         {@code ...}<br>
+*          {@code ignite node start --config=$IGNITE_HOME/examples/config/ignite-config.json node-n}<br>
+ *     </li>
+ *     <li>Run the example in the IDE.</li>
+ * </ol>
+ */
+public class ClientRecordViewExample {
+    public static void main(String[] args) throws Exception {
+        try (Ignite ignite = IgnitionManager.start(
+                "node-0",
+                Files.readString(Path.of("config", "ignite-config.json")),
+                Path.of("work")
+        )) {
+
+            //---------------------------------------------------------------------------------
+            //
+            // Creating a table. The API call below is the equivalent of the following DDL:
+            //
+            //     CREATE TABLE accounts (
+            //         accountNumber INT PRIMARY KEY,
+            //         firstName     VARCHAR,
+            //         lastName      VARCHAR,
+            //         balance       DOUBLE
+            //     )
+            //
+            //---------------------------------------------------------------------------------
+
+             ignite.tables().createTable("PUBLIC.accounts", tbl ->
+                SchemaConfigurationConverter.convert(
+                    SchemaBuilders.tableBuilder("PUBLIC", "accounts")
+                        .columns(
+                            SchemaBuilders.column("accountNumber", ColumnType.INT32).asNonNull().build(),
+                            SchemaBuilders.column("firstName", ColumnType.string()).asNullable().build(),
+                            SchemaBuilders.column("lastName", ColumnType.string()).asNullable().build(),
+                            SchemaBuilders.column("balance", ColumnType.DOUBLE).asNullable().build()
+                        )
+                        .withPrimaryKey("accountNumber")
+                        .build(), tbl)
+                    .changeReplicas(1)
+                    .changePartitions(10)
+            );
+
+            try (IgniteClient client = IgniteClient.builder()
+                    .addresses("127.0.0.1:10800")
+                    .build()
+            ) {
+                RecordView<Tuple> accounts = client.tables().table("PUBLIC.accounts").recordView();
+
+                //---------------------------------------------------------------------------------
+                //
+                // Tuple API: insert operation.
+                //
+                //---------------------------------------------------------------------------------
+
+                Tuple newAccountTuple = Tuple.create()
+                    .set("accountNumber", 123456)
+                    .set("firstName", "Val")
+                    .set("lastName", "Kulichenko")
+                    .set("balance", 100.00d);
+
+                accounts.insert(newAccountTuple);
+
+                //---------------------------------------------------------------------------------
+                //
+                // Tuple API: get operation.
+                //
+                //---------------------------------------------------------------------------------
+
+                Tuple accountNumberTuple = Tuple.create().set("accountNumber", 123456);
+
+                Tuple accountTuple = accounts.get(accountNumberTuple);
+
+                System.out.println(
+                    "Retrieved using Tuple API\n" +
+                        "    Account Number: " + accountTuple.intValue("accountNumber") + '\n' +
+                        "    Owner: " + accountTuple.stringValue("firstName") + " " + accountTuple.stringValue("lastName") + '\n' +
+                        "    Balance: $" + accountTuple.doubleValue("balance"));
+            }
+        }
+    }
+}
diff --git a/examples/src/main/java/org/apache/ignite/sql/jdbc/SqlJdbcExample.java b/examples/src/main/java/org/apache/ignite/example/sql/jdbc/SqlJdbcExample.java
similarity index 98%
rename from examples/src/main/java/org/apache/ignite/sql/jdbc/SqlJdbcExample.java
rename to examples/src/main/java/org/apache/ignite/example/sql/jdbc/SqlJdbcExample.java
index ecd97e9..20026e6 100644
--- a/examples/src/main/java/org/apache/ignite/sql/jdbc/SqlJdbcExample.java
+++ b/examples/src/main/java/org/apache/ignite/example/sql/jdbc/SqlJdbcExample.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.ignite.sql.jdbc;
+package org.apache.ignite.example.sql.jdbc;
 
 import java.nio.file.Files;
 import java.nio.file.Path;
@@ -51,7 +51,7 @@ public class SqlJdbcExample {
     public static void main(String[] args) throws Exception {
         Ignite ignite = IgnitionManager.start(
             "node-0",
-            Files.readString(Path.of( "config", "ignite-config.json")),
+            Files.readString(Path.of("config", "ignite-config.json")),
             Path.of("work")
         );
 
diff --git a/examples/src/test/java/org/apache/ignite/example/ExampleTestUtils.java b/examples/src/test/java/org/apache/ignite/example/ExampleTestUtils.java
new file mode 100644
index 0000000..e098463
--- /dev/null
+++ b/examples/src/test/java/org/apache/ignite/example/ExampleTestUtils.java
@@ -0,0 +1,93 @@
+/*
+ * 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.ignite.example;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * Example test utilities.
+ */
+public class ExampleTestUtils {
+    /**
+     * Interface for a general example main function.
+     */
+    @FunctionalInterface
+    public interface ExampleConsumer {
+        void accept(String[] args) throws Exception;
+    }
+
+    /**
+     * Capture console output of the example.
+     * @param consumer Method which output should be captured. Ordinary main of the example.
+     * @param args Arguments.
+     * @return Captured output as a string.
+     */
+    public static String captureConsole(ExampleConsumer consumer, String[] args) throws Exception {
+        ByteArrayOutputStream outStream = new ByteArrayOutputStream();
+        PrintStream printStream = new PrintStream(outStream);
+
+        PrintStream old = System.out;
+
+        try {
+            System.setOut(printStream);
+
+            consumer.accept(args);
+
+            System.out.flush();
+        }
+        finally {
+            System.setOut(old);
+        }
+
+        return outStream.toString();
+    }
+
+    /**
+     * Assert that console output of the example equals expected.
+     * @param consumer Method which output should be captured. Ordinary main of the example.
+     * @param args Arguments.
+     * @param expected Expected console output.
+     */
+    public static void assertConsoleOutput(ExampleConsumer consumer, String[] args, String expected) throws Exception {
+        String captured = ExampleTestUtils.captureConsole(consumer, args);
+
+        captured = captured.replaceAll("\r", "");
+
+        assertEquals(expected, captured);
+    }
+
+    /**
+     * Assert that console output of the example equals expected.
+     * @param consumer Method which output should be captured. Ordinary main of the example.
+     * @param args Arguments.
+     * @param expected Expected console output.
+     */
+    public static void assertConsoleOutputContains(ExampleConsumer consumer, String[] args,
+            String... expected) throws Exception {
+        String captured = ExampleTestUtils.captureConsole(consumer, args);
+
+        captured = captured.replaceAll("\r", "");
+
+        for (String single : expected)
+            assertTrue(captured.contains(single));
+    }
+}
diff --git a/examples/src/test/java/org/apache/ignite/example/table/TableExamplesTest.java b/examples/src/test/java/org/apache/ignite/example/client/ClientExamplesTest.java
similarity index 61%
copy from examples/src/test/java/org/apache/ignite/example/table/TableExamplesTest.java
copy to examples/src/test/java/org/apache/ignite/example/client/ClientExamplesTest.java
index e3db749..6b38419 100644
--- a/examples/src/test/java/org/apache/ignite/example/table/TableExamplesTest.java
+++ b/examples/src/test/java/org/apache/ignite/example/client/ClientExamplesTest.java
@@ -15,40 +15,50 @@
  * limitations under the License.
  */
 
-package org.apache.ignite.example.table;
+package org.apache.ignite.example.client;
 
 import java.nio.file.Files;
 import java.nio.file.Path;
+
+import org.apache.ignite.example.ExampleTestUtils;
 import org.apache.ignite.internal.util.IgniteUtils;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
 /**
- * These tests check that all table examples pass correctly.
+ * These tests check that all client examples pass correctly.
  */
-public class TableExamplesTest {
+public class ClientExamplesTest {
     /** Empty argument to invoke an example. */
     protected static final String[] EMPTY_ARGS = new String[0];
 
     /**
-     * Runs RecordViewExample.
+     * Runs ClientRecordViewExample and checks its output.
      *
      * @throws Exception If failed.
      */
     @Test
-    public void testRecordViewExample() throws Exception {
-        RecordViewExample.main(EMPTY_ARGS);
+    public void testClientRecordViewExample() throws Exception {
+        ExampleTestUtils.assertConsoleOutput(ClientRecordViewExample::main, EMPTY_ARGS,
+            "Retrieved using Tuple API\n" +
+            "    Account Number: 123456\n" +
+            "    Owner: Val Kulichenko\n" +
+            "    Balance: $100.0\n");
     }
 
     /**
-     * Runs KeyValueViewExample.
+     * Runs ClientKeyValueViewExample and checks its     output.
      *
      * @throws Exception If failed.
      */
     @Test
-    public void testKeyValueViewExample() throws Exception {
-        KeyValueViewExample.main(EMPTY_ARGS);
+    public void testClientKeyValueViewExample() throws Exception {
+        ExampleTestUtils.assertConsoleOutput(ClientKeyValueViewExample::main, EMPTY_ARGS,
+            "Retrieved using Key-Value API\n" +
+            "    Account Number: 123456\n" +
+            "    Owner: Val Kulichenko\n" +
+            "    Balance: $100.0\n");
     }
 
     /**
diff --git a/examples/src/test/java/org/apache/ignite/example/table/TableExamplesTest.java b/examples/src/test/java/org/apache/ignite/example/sql/jdbc/SqlExamplesTest.java
similarity index 61%
copy from examples/src/test/java/org/apache/ignite/example/table/TableExamplesTest.java
copy to examples/src/test/java/org/apache/ignite/example/sql/jdbc/SqlExamplesTest.java
index e3db749..2a7db3a 100644
--- a/examples/src/test/java/org/apache/ignite/example/table/TableExamplesTest.java
+++ b/examples/src/test/java/org/apache/ignite/example/sql/jdbc/SqlExamplesTest.java
@@ -15,40 +15,47 @@
  * limitations under the License.
  */
 
-package org.apache.ignite.example.table;
+package org.apache.ignite.example.sql.jdbc;
 
 import java.nio.file.Files;
 import java.nio.file.Path;
+
+import org.apache.ignite.example.ExampleTestUtils;
 import org.apache.ignite.internal.util.IgniteUtils;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
 /**
- * These tests check that all table examples pass correctly.
+ * These tests check that all SQL JDBC examples pass correctly.
  */
-public class TableExamplesTest {
+public class SqlExamplesTest {
     /** Empty argument to invoke an example. */
     protected static final String[] EMPTY_ARGS = new String[0];
 
     /**
-     * Runs RecordViewExample.
+     * Runs SqlJdbcExample and checks its output.
      *
      * @throws Exception If failed.
      */
     @Test
-    public void testRecordViewExample() throws Exception {
-        RecordViewExample.main(EMPTY_ARGS);
-    }
+    public void testSqlJdbcExample() throws Exception {
+        ExampleTestUtils.assertConsoleOutputContains(SqlJdbcExample::main, EMPTY_ARGS,
+            ">>> Query results:\n" +
+            ">>>    John, Doe, Forest Hill\n" +
+            ">>>    Jane, Roe, Forest Hill\n" +
+            ">>>    Mary, Major, Denver\n" +
+            ">>>    Richard, Miles, St. Petersburg\n",
 
-    /**
-     * Runs KeyValueViewExample.
-     *
-     * @throws Exception If failed.
-     */
-    @Test
-    public void testKeyValueViewExample() throws Exception {
-        KeyValueViewExample.main(EMPTY_ARGS);
+            ">>> Query results:\n" +
+            ">>>    John, Doe, 1000.0\n" +
+            ">>>    Richard, Miles, 1450.0\n",
+
+            ">>> Query results:\n" +
+            ">>>    Jane, Roe, Forest Hill\n" +
+            ">>>    Mary, Major, Denver\n" +
+            ">>>    Richard, Miles, St. Petersburg\n"
+        );
     }
 
     /**
diff --git a/examples/src/test/java/org/apache/ignite/example/table/TableExamplesTest.java b/examples/src/test/java/org/apache/ignite/example/table/TableExamplesTest.java
index e3db749..8c7daa6 100644
--- a/examples/src/test/java/org/apache/ignite/example/table/TableExamplesTest.java
+++ b/examples/src/test/java/org/apache/ignite/example/table/TableExamplesTest.java
@@ -19,6 +19,8 @@ package org.apache.ignite.example.table;
 
 import java.nio.file.Files;
 import java.nio.file.Path;
+
+import org.apache.ignite.example.ExampleTestUtils;
 import org.apache.ignite.internal.util.IgniteUtils;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
@@ -34,21 +36,29 @@ public class TableExamplesTest {
     /**
      * Runs RecordViewExample.
      *
-     * @throws Exception If failed.
+     * @throws Exception If failed and checks its output.
      */
     @Test
     public void testRecordViewExample() throws Exception {
-        RecordViewExample.main(EMPTY_ARGS);
+        ExampleTestUtils.assertConsoleOutput(RecordViewExample::main, EMPTY_ARGS,
+            "Retrieved using Tuple API\n" +
+            "    Account Number: 123456\n" +
+            "    Owner: Val Kulichenko\n" +
+            "    Balance: $100.0\n");
     }
 
     /**
-     * Runs KeyValueViewExample.
+     * Runs KeyValueViewExample and checks its output.
      *
      * @throws Exception If failed.
      */
     @Test
     public void testKeyValueViewExample() throws Exception {
-        KeyValueViewExample.main(EMPTY_ARGS);
+        ExampleTestUtils.assertConsoleOutput(KeyValueViewExample::main, EMPTY_ARGS,
+            "Retrieved using Key-Value API\n" +
+            "    Account Number: 123456\n" +
+            "    Owner: Val Kulichenko\n" +
+            "    Balance: $100.0\n");
     }
 
     /**