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

[ignite-3] branch main updated: IGNITE-15720 - Fixed examples to be able to run with a remote node (#394)

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

vkulichenko 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 0083c45  IGNITE-15720 - Fixed examples to be able to run with a remote node (#394)
0083c45 is described below

commit 0083c45941cf44db00bc07986305739c6e6b158f
Author: Valentin Kulichenko <va...@gmail.com>
AuthorDate: Tue Oct 12 11:50:26 2021 -0700

    IGNITE-15720 - Fixed examples to be able to run with a remote node (#394)
---
 examples/.gitignore                                |   2 +-
 examples/config/ignite-config.json                 |   2 +-
 examples/config/java.util.logging.properties       |   4 +-
 examples/config/rebalance/ignite-config-0.json     |  13 --
 examples/config/rebalance/ignite-config-1.json     |  13 --
 examples/config/rebalance/ignite-config-2.json     |  13 --
 examples/config/rebalance/ignite-config-3.json     |  13 --
 examples/config/rebalance/ignite-config-4.json     |  13 --
 .../ignite/example/rebalance/RebalanceExample.java | 229 +++++++++++++--------
 .../ignite/example/sql/jdbc/SqlJdbcExample.java    |  21 +-
 .../ignite/example/table/KeyValueViewExample.java  |  21 +-
 .../ignite/example/table/RecordViewExample.java    |  21 +-
 .../ignite/example/sql/jdbc/SqlExamplesTest.java   |  26 +++
 .../ignite/example/table/TableExamplesTest.java    |  26 +++
 14 files changed, 239 insertions(+), 178 deletions(-)

diff --git a/examples/.gitignore b/examples/.gitignore
index 02e7b03..3b50ac4 100644
--- a/examples/.gitignore
+++ b/examples/.gitignore
@@ -1,2 +1,2 @@
 work*
-ignite.log*
+example-node.log*
diff --git a/examples/config/ignite-config.json b/examples/config/ignite-config.json
index d09db83..4c3a902 100644
--- a/examples/config/ignite-config.json
+++ b/examples/config/ignite-config.json
@@ -1,7 +1,7 @@
 {
     "node": {
         "metastorageNodes": [
-            "node-0", "node-1", "node-2"
+            "my-first-node"
         ]
     },
     "network": {
diff --git a/examples/config/java.util.logging.properties b/examples/config/java.util.logging.properties
index ab67713..357c56b 100644
--- a/examples/config/java.util.logging.properties
+++ b/examples/config/java.util.logging.properties
@@ -19,5 +19,5 @@
 
 handlers=java.util.logging.FileHandler
 
-java.util.logging.FileHandler.formatter = org.apache.ignite.lang.JavaLoggerFormatter
-java.util.logging.FileHandler.pattern = ignite.log
+java.util.logging.FileHandler.formatter=org.apache.ignite.lang.JavaLoggerFormatter
+java.util.logging.FileHandler.pattern=example-node.log
diff --git a/examples/config/rebalance/ignite-config-0.json b/examples/config/rebalance/ignite-config-0.json
deleted file mode 100644
index b492441..0000000
--- a/examples/config/rebalance/ignite-config-0.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
-    "node": {
-        "metastorageNodes": [
-            "node-0"
-        ]
-    },
-    "network": {
-        "port": 3344,
-        "netClusterNodes": [
-            "localhost:3344", "localhost:3345", "localhost:3346"
-        ]
-    }
-}
diff --git a/examples/config/rebalance/ignite-config-1.json b/examples/config/rebalance/ignite-config-1.json
deleted file mode 100644
index c814e97..0000000
--- a/examples/config/rebalance/ignite-config-1.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
-    "node": {
-        "metastorageNodes": [
-            "node-0"
-        ]
-    },
-    "network": {
-        "port": 3345,
-        "netClusterNodes": [
-            "localhost:3344", "localhost:3345", "localhost:3346"
-        ]
-    }
-}
diff --git a/examples/config/rebalance/ignite-config-2.json b/examples/config/rebalance/ignite-config-2.json
deleted file mode 100644
index 39cfc33..0000000
--- a/examples/config/rebalance/ignite-config-2.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
-    "node": {
-        "metastorageNodes": [
-            "node-0"
-        ]
-    },
-    "network": {
-        "port": 3346,
-        "netClusterNodes": [
-            "localhost:3344", "localhost:3345", "localhost:3346"
-        ]
-    }
-}
diff --git a/examples/config/rebalance/ignite-config-3.json b/examples/config/rebalance/ignite-config-3.json
deleted file mode 100644
index 357c33e..0000000
--- a/examples/config/rebalance/ignite-config-3.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
-    "node": {
-        "metastorageNodes": [
-            "node-0"
-        ]
-    },
-    "network": {
-        "port": 3347,
-        "netClusterNodes": [
-            "localhost:3344", "localhost:3345", "localhost:3346"
-        ]
-    }
-}
diff --git a/examples/config/rebalance/ignite-config-4.json b/examples/config/rebalance/ignite-config-4.json
deleted file mode 100644
index e418070..0000000
--- a/examples/config/rebalance/ignite-config-4.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
-    "node": {
-        "metastorageNodes": [
-            "node-0"
-        ]
-    },
-    "network": {
-        "port": 3348,
-        "netClusterNodes": [
-            "localhost:3344", "localhost:3345", "localhost:3346"
-        ]
-    }
-}
diff --git a/examples/src/main/java/org/apache/ignite/example/rebalance/RebalanceExample.java b/examples/src/main/java/org/apache/ignite/example/rebalance/RebalanceExample.java
index 9fac5bf..501cacc 100644
--- a/examples/src/main/java/org/apache/ignite/example/rebalance/RebalanceExample.java
+++ b/examples/src/main/java/org/apache/ignite/example/rebalance/RebalanceExample.java
@@ -19,56 +19,62 @@ package org.apache.ignite.example.rebalance;
 
 import java.nio.file.Files;
 import java.nio.file.Path;
-import java.util.ArrayList;
-import java.util.List;
 import java.util.Set;
 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.schema.definition.TableDefinition;
 import org.apache.ignite.table.KeyValueView;
-import org.apache.ignite.table.Table;
 import org.apache.ignite.table.Tuple;
 
 /**
  * This example demonstrates the data rebalance process.
- * The following sequence of events is emulated:
- *
- * <ul>
- * <li>Start 3 nodes (A, B and C)</li>
- * <li>Insert some data</li>
- * <li>Add 2 more nodes (D and E)</li>
- * <li>Set new baseline to (A, D, E)</li>
- * <li>Stop nodes B and C</li>
- * <li>Check that data is still available on the new configuration</li>
- * </ul>
- *
+ * <p>
+ * The example emulates the basic scenario when one starts a three-node topology,
+ * inserts some data, and then scales out by adding two more nodes. After the
+ * topology is changed, the data is rebalanced and verified for correctness.
  * <p>
  * To run the example, do the following:
  * <ol>
  *     <li>Import the examples project into you IDE.</li>
+ *     <li>
+ *         Start <b>two</b> nodes using the CLI tool:<br>
+ *         {@code ignite node start --config=$IGNITE_HOME/examples/config/ignite-config.json my-first-node}<br>
+ *         {@code ignite node start --config=$IGNITE_HOME/examples/config/ignite-config.json my-second-node}
+ *     </li>
  *     <li>Run the example in the IDE.</li>
+ *     <li>
+ *         When requested, start another two nodes using the CLI tool:
+ *         {@code ignite node start --config=$IGNITE_HOME/examples/config/ignite-config.json my-first-additional-node}<br>
+ *         {@code ignite node start --config=$IGNITE_HOME/examples/config/ignite-config.json my-second-additional-node}
+ *     </li>
+ *     <li>Press {@code Enter} to resume the example.</li>
  * </ol>
  */
 public class RebalanceExample {
     public static void main(String[] args) throws Exception {
-        List<Ignite> nodes = new ArrayList<>();
-
-        try {
-            System.out.println("Starting server nodes... Logging to file: ignite.log");
-
-            System.setProperty("java.util.logging.config.file", "config/java.util.logging.properties");
-
-            for (int i = 0; i < 3; i++) {
-                nodes.add(IgnitionManager.start("node-" + i,
-                    Files.readString(Path.of("config", "rebalance", "ignite-config-" + i + ".json")),
-                    Path.of("work" + i)));
-            }
-
-            Ignite node0 = nodes.get(0);
-
+        //--------------------------------------------------------------------------------------
+        //
+        // Starting a server node.
+        //
+        // NOTE: An embedded server node is only needed to invoke the 'createTable' API.
+        //       In the future releases, this API will be available on the client,
+        //       eliminating the need to start an embedded server node in this example.
+        //
+        //--------------------------------------------------------------------------------------
+
+        System.out.println("Starting a server node... Logging to file: example-node.log");
+
+        System.setProperty("java.util.logging.config.file", "config/java.util.logging.properties");
+
+        try (Ignite server = IgnitionManager.start(
+                "example-node",
+                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:
@@ -83,75 +89,122 @@ public class RebalanceExample {
             System.out.println("\nCreating a table...");
 
             TableDefinition tableDef = SchemaBuilders.tableBuilder("PUBLIC", "rebalance")
-                .columns(
-                    SchemaBuilders.column("key", ColumnType.INT32).asNonNull().build(),
-                    SchemaBuilders.column("value", ColumnType.string()).asNullable().build()
-                )
-                .withPrimaryKey("key")
-                .build();
-
-            Table testTable = node0.tables().createTable("PUBLIC.rebalance", tableChange ->
-                SchemaConfigurationConverter.convert(tableDef, tableChange)
-                    .changeReplicas(5)
-                    .changePartitions(1)
+                    .columns(
+                            SchemaBuilders.column("key", ColumnType.INT32).asNonNull().build(),
+                            SchemaBuilders.column("value", ColumnType.string()).asNullable().build()
+                    )
+                    .withPrimaryKey("key")
+                    .build();
+
+            server.tables().createTable(tableDef.canonicalName(), tableChange ->
+                    SchemaConfigurationConverter.convert(tableDef, tableChange)
+                            .changeReplicas(5)
+                            .changePartitions(1)
             );
 
             //--------------------------------------------------------------------------------------
             //
-            // Inserting a key-value pair into the table.
+            // Creating a client to connect to the cluster.
             //
             //--------------------------------------------------------------------------------------
 
-            System.out.println("\nInserting a key-value pair...");
-
-            KeyValueView<Tuple, Tuple> kvView = testTable.keyValueView();
-
-            Tuple key = Tuple.create().set("key", 1);
-            Tuple value = Tuple.create().set("value", "test");
-
-            kvView.put(key, value);
-
-            System.out.println("\nCurrent value: " + kvView.get(key).value("value"));
-
-            //--------------------------------------------------------------------------------------
-            //
-            // Changing the topology and updating the baseline.
-            //
-            //--------------------------------------------------------------------------------------
-
-            System.out.println("\nChanging the topology...");
-
-            for (int i = 3; i < 5; i++) {
-                nodes.add(IgnitionManager.start("node-" + i,
-                    Files.readString(Path.of("config", "rebalance", "ignite-config-" + i + ".json")),
-                    Path.of("work" + i)));
+            System.out.println("\nConnecting to server...");
+
+            try (IgniteClient client = IgniteClient.builder()
+                    .addresses("127.0.0.1:10800")
+                    .build()
+            ) {
+                KeyValueView<Tuple, Tuple> kvView = client.tables().table("PUBLIC.rebalance").keyValueView();
+
+                //--------------------------------------------------------------------------------------
+                //
+                // Inserting several key-value pairs into the table.
+                //
+                //--------------------------------------------------------------------------------------
+
+                System.out.println("\nInserting key-value pairs...");
+
+                for (int i = 0; i < 10; i++) {
+                    Tuple key = Tuple.create().set("key", i);
+                    Tuple value = Tuple.create().set("value", "test_" + i);
+
+                    kvView.put(key, value);
+                }
+
+                //--------------------------------------------------------------------------------------
+                //
+                // Retrieving the newly inserted data.
+                //
+                //--------------------------------------------------------------------------------------
+
+                System.out.println("\nRetrieved key-value pairs:");
+
+                for (int i = 0; i < 10; i++) {
+                    Tuple key = Tuple.create().set("key", i);
+                    Tuple value = kvView.get(key);
+
+                    System.out.println("    " + i + " -> " + value.stringValue("value"));
+                }
+
+                //--------------------------------------------------------------------------------------
+                //
+                // Scaling out by adding two more nodes into the topology.
+                //
+                //--------------------------------------------------------------------------------------
+
+                System.out.println("\n" +
+                        "Run the following commands using the CLI tool to start two more nodes, and then press 'Enter' to continue...\n" +
+                        "    ignite node start --config=examples/config/ignite-config.json my-first-additional-node\n" +
+                        "    ignite node start --config=examples/config/ignite-config.json my-second-additional-node");
+
+                System.in.read();
+
+                //--------------------------------------------------------------------------------------
+                //
+                // Updating baseline to initiate the data rebalancing process.
+                //
+                // New topology includes the following five nodes:
+                //     1. 'my-first-node' -- the first node started prior to running the example
+                //     2. 'my-second-node' -- the second node started prior to running the example
+                //     3. 'example-node' -- node that is embedded into the example
+                //     4. 'additional-node-1' -- the first node added to the topology
+                //     5. 'additional-node-2' -- the second node added to the topology
+                //
+                // NOTE: In the future releases, this API will be provided by the clients as well.
+                //       In addition, the process will be automated where applicable to eliminate
+                //       the need for this manual step.
+                //
+                //--------------------------------------------------------------------------------------
+
+                System.out.println("\nUpdating the baseline and rebalancing the data...");
+
+                server.setBaseline(Set.of(
+                        "my-first-node",
+                        "my-second-node",
+                        "example-node",
+                        "my-first-additional-node",
+                        "my-second-additional-node"
+                ));
+
+                //--------------------------------------------------------------------------------------
+                //
+                // Retrieving data again to validate correctness.
+                //
+                //--------------------------------------------------------------------------------------
+
+                System.out.println("\nKey-value pairs retrieved after the topology change:");
+
+                for (int i = 0; i < 10; i++) {
+                    Tuple key = Tuple.create().set("key", i);
+                    Tuple value = kvView.get(key);
+
+                    System.out.println("    " + i + " -> " + value.stringValue("value"));
+                }
             }
 
-            node0.setBaseline(Set.of("node-0", "node-3", "node-4"));
+            System.out.println("\nDropping the table and stopping the server...");
 
-            IgnitionManager.stop(nodes.get(1).name());
-            IgnitionManager.stop(nodes.get(2).name());
-
-            //--------------------------------------------------------------------------------------
-            //
-            // Retrieving the value from one of the new nodes.
-            //
-            //--------------------------------------------------------------------------------------
-
-            System.out.println("\nRetrieving the value from one of the new nodes...");
-
-            String valueOnNewNode = nodes.get(4).tables().table("PUBLIC.rebalance").keyValueView().get(key).value("value");
-
-            System.out.println("\nRetrieved value: " + valueOnNewNode);
-
-            System.out.println("\nDropping the table and stopping the cluster...");
-
-            node0.tables().dropTable(tableDef.canonicalName());
-        }
-        finally {
-            IgnitionManager.stop(nodes.get(0).name());
-            IgnitionManager.stop(nodes.get(3).name());
-            IgnitionManager.stop(nodes.get(4).name());
+            server.tables().dropTable(tableDef.canonicalName());
         }
     }
 }
diff --git a/examples/src/main/java/org/apache/ignite/example/sql/jdbc/SqlJdbcExample.java b/examples/src/main/java/org/apache/ignite/example/sql/jdbc/SqlJdbcExample.java
index a44f8b8..cab1079 100644
--- a/examples/src/main/java/org/apache/ignite/example/sql/jdbc/SqlJdbcExample.java
+++ b/examples/src/main/java/org/apache/ignite/example/sql/jdbc/SqlJdbcExample.java
@@ -38,23 +38,30 @@ import org.apache.ignite.schema.definition.TableDefinition;
  * <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>
+ *         Start a server node using the CLI tool:<br>
+ *         {@code ignite node start --config=$IGNITE_HOME/examples/config/ignite-config.json my-first-node}
  *     </li>
  *     <li>Run the example in the IDE.</li>
  * </ol>
  */
 public class SqlJdbcExample {
     public static void main(String[] args) throws Exception {
-        System.out.println("Starting a server node... Logging to file: ignite.log");
+        //--------------------------------------------------------------------------------------
+        //
+        // Starting a server node.
+        //
+        // NOTE: An embedded server node is only needed to invoke the 'createTable' API.
+        //       In the future releases, this API will be available on the client,
+        //       eliminating the need to start an embedded server node in this example.
+        //
+        //--------------------------------------------------------------------------------------
+
+        System.out.println("Starting a server node... Logging to file: example-node.log");
 
         System.setProperty("java.util.logging.config.file", "config/java.util.logging.properties");
 
         try (Ignite ignite = IgnitionManager.start(
-            "node-0",
+            "example-node",
             Files.readString(Path.of("config", "ignite-config.json")),
             Path.of("work")
         )) {
diff --git a/examples/src/main/java/org/apache/ignite/example/table/KeyValueViewExample.java b/examples/src/main/java/org/apache/ignite/example/table/KeyValueViewExample.java
index 810d669..960361c 100644
--- a/examples/src/main/java/org/apache/ignite/example/table/KeyValueViewExample.java
+++ b/examples/src/main/java/org/apache/ignite/example/table/KeyValueViewExample.java
@@ -36,23 +36,30 @@ import org.apache.ignite.table.Tuple;
  * <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>
+ *         Start a server node using the CLI tool:<br>
+ *         {@code ignite node start --config=$IGNITE_HOME/examples/config/ignite-config.json my-first-node}
  *     </li>
  *     <li>Run the example in the IDE.</li>
  * </ol>
  */
 public class KeyValueViewExample {
     public static void main(String[] args) throws Exception {
-        System.out.println("Starting a server node... Logging to file: ignite.log");
+        //--------------------------------------------------------------------------------------
+        //
+        // Starting a server node.
+        //
+        // NOTE: An embedded server node is only needed to invoke the 'createTable' API.
+        //       In the future releases, this API will be available on the client,
+        //       eliminating the need to start an embedded server node in this example.
+        //
+        //--------------------------------------------------------------------------------------
+
+        System.out.println("Starting a server node... Logging to file: example-node.log");
 
         System.setProperty("java.util.logging.config.file", "config/java.util.logging.properties");
 
         try (Ignite server = IgnitionManager.start(
-            "node-0",
+            "example-node",
             Files.readString(Path.of("config", "ignite-config.json")),
             Path.of("work")
         )) {
diff --git a/examples/src/main/java/org/apache/ignite/example/table/RecordViewExample.java b/examples/src/main/java/org/apache/ignite/example/table/RecordViewExample.java
index b747839..3598d4e 100644
--- a/examples/src/main/java/org/apache/ignite/example/table/RecordViewExample.java
+++ b/examples/src/main/java/org/apache/ignite/example/table/RecordViewExample.java
@@ -36,23 +36,30 @@ import org.apache.ignite.table.Tuple;
  * <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>
+ *         Start a server node using the CLI tool:<br>
+ *         {@code ignite node start --config=$IGNITE_HOME/examples/config/ignite-config.json my-first-node}
  *     </li>
  *     <li>Run the example in the IDE.</li>
  * </ol>
  */
 public class RecordViewExample {
     public static void main(String[] args) throws Exception {
-        System.out.println("Starting a server node... Logging to file: ignite.log");
+        //--------------------------------------------------------------------------------------
+        //
+        // Starting a server node.
+        //
+        // NOTE: An embedded server node is only needed to invoke the 'createTable' API.
+        //       In the future releases, this API will be available on the client,
+        //       eliminating the need to start an embedded server node in this example.
+        //
+        //--------------------------------------------------------------------------------------
+
+        System.out.println("Starting a server node... Logging to file: example-node.log");
 
         System.setProperty("java.util.logging.config.file", "config/java.util.logging.properties");
 
         try (Ignite server = IgnitionManager.start(
-            "node-0",
+            "example-node",
             Files.readString(Path.of("config", "ignite-config.json")),
             Path.of("work")
         )) {
diff --git a/examples/src/test/java/org/apache/ignite/example/sql/jdbc/SqlExamplesTest.java b/examples/src/test/java/org/apache/ignite/example/sql/jdbc/SqlExamplesTest.java
index 7bd9033..cefecbf 100644
--- a/examples/src/test/java/org/apache/ignite/example/sql/jdbc/SqlExamplesTest.java
+++ b/examples/src/test/java/org/apache/ignite/example/sql/jdbc/SqlExamplesTest.java
@@ -17,9 +17,11 @@
 
 package org.apache.ignite.example.sql.jdbc;
 
+import java.io.IOException;
 import java.nio.file.Files;
 import java.nio.file.Path;
 
+import org.apache.ignite.IgnitionManager;
 import org.apache.ignite.example.ExampleTestUtils;
 import org.apache.ignite.internal.util.IgniteUtils;
 import org.junit.jupiter.api.AfterEach;
@@ -58,6 +60,30 @@ public class SqlExamplesTest {
         );
     }
 
+    @BeforeEach
+    private void startNode() throws IOException {
+        Path workDir = Path.of("my-first-node-work");
+
+        if (Files.exists(workDir))
+            IgniteUtils.deleteIfExists(workDir);
+
+        IgnitionManager.start(
+            "my-first-node",
+            Files.readString(Path.of("config", "ignite-config.json")),
+            workDir
+        );
+    }
+
+    @AfterEach
+    private void stopNode() {
+        IgnitionManager.stop("my-first-node");
+
+        Path workDir = Path.of("my-first-node-work");
+
+        if (Files.exists(workDir))
+            IgniteUtils.deleteIfExists(workDir);
+    }
+
     /**
      * Removes a previously created work directory.
      */
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 2004ba6..3c016dd 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
@@ -17,9 +17,11 @@
 
 package org.apache.ignite.example.table;
 
+import java.io.IOException;
 import java.nio.file.Files;
 import java.nio.file.Path;
 
+import org.apache.ignite.IgnitionManager;
 import org.apache.ignite.example.ExampleTestUtils;
 import org.apache.ignite.internal.util.IgniteUtils;
 import org.junit.jupiter.api.AfterEach;
@@ -61,6 +63,30 @@ public class TableExamplesTest {
             "    Balance: $100.0\n");
     }
 
+    @BeforeEach
+    private void startNode() throws IOException {
+        Path workDir = Path.of("my-first-node-work");
+
+        if (Files.exists(workDir))
+            IgniteUtils.deleteIfExists(workDir);
+
+        IgnitionManager.start(
+            "my-first-node",
+            Files.readString(Path.of("config", "ignite-config.json")),
+            workDir
+        );
+    }
+
+    @AfterEach
+    private void stopNode() {
+        IgnitionManager.stop("my-first-node");
+
+        Path workDir = Path.of("my-first-node-work");
+
+        if (Files.exists(workDir))
+            IgniteUtils.deleteIfExists(workDir);
+    }
+
     /**
      * Removes a previously created work directory.
      */