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

vpyatkov 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 2667636  IGNITE-15926 DDL methods for tables should throw an exception 
when the tables exist or not
2667636 is described below

commit 26676363ad9b8aacf9fc33af01ee3072195a7556
Author: Vladislav Pyatkov <[email protected]>
AuthorDate: Mon Dec 13 17:33:03 2021 +0300

    IGNITE-15926 DDL methods for tables should throw an exception when the 
tables exist or not
---
 .../ignite/lang/ColumnAlreadyExistsException.java  |   2 +-
 .../ignite/lang/ColumnNotFoundException.java       |   2 +-
 .../ignite/lang/IndexAlreadyExistsException.java   |   2 +-
 .../apache/ignite/lang/IndexNotFoundException.java |   2 +-
 .../ignite/lang/TableAlreadyExistsException.java   |   2 +-
 ...sException.java => TableNotFoundException.java} |   8 +-
 .../apache/ignite/table/manager/IgniteTables.java  |  49 +---
 .../query/calcite/exec/ddl/DdlCommandHandler.java  |  44 ++--
 .../calcite/exec/DdlWithMockedManagersTest.java    |  30 ++-
 .../ignite/internal/client/table/ClientTables.java |  15 --
 .../ignite/client/AbstractClientTableTest.java     |  14 +-
 .../ignite/client/fakes/FakeIgniteTables.java      |  22 --
 .../org/apache/ignite/internal/util/ByteUtils.java |   4 +-
 .../apache/ignite/internal/util/IgniteUtils.java   |   4 +-
 .../java/org/apache/ignite/lang/IgniteLogger.java  |   6 +-
 ...ssageHelper.java => IgniteStringFormatter.java} |   2 +-
 ...stractTest.java => BaseIgniteAbstractTest.java} |  22 +-
 .../internal/testframework/IgniteAbstractTest.java |  53 +---
 .../internal/testframework/IgniteTestUtils.java    |   4 +-
 .../org/apache/ignite/lang/LoggerHelperTest.java   | 106 ++++----
 .../java/org/apache/ignite/internal/raft/Loza.java |   6 +-
 .../internal/raft/server/impl/JraftServerImpl.java |   4 +-
 .../raft/jraft/disruptor/StripedDisruptor.java     |  10 +-
 .../ignite/disruptor/StripedDisruptorTest.java     |   6 +-
 .../internal/raft/server/impl/RaftServerImpl.java  |   4 +-
 .../calcite/AbstractBasicIntegrationTest.java      | 119 +++++----
 .../ignite/internal/calcite/ItFunctionsTest.java   |   4 +-
 .../runner/app/ItIgniteNodeRestartTest.java        |   2 +-
 .../runner/app/ItTableApiContractTest.java         | 279 +++++++++++++++++++++
 .../internal/runner/app/ItTablesApiTest.java       |  74 ++++--
 .../runner/app/ItThinClientConnectionTest.java     |   2 +-
 .../apache/ignite/internal/app/IgnitionImpl.java   |   4 +-
 .../apache/ignite/internal/schema/SchemaUtils.java |   4 +-
 .../internal/table/distributed/TableManager.java   | 271 ++++++++++----------
 .../table/distributed/raft/PartitionListener.java  |   2 +-
 .../distributed/storage/InternalTableImpl.java     |   6 +-
 .../ignite/internal/table/TableManagerTest.java    |   8 +-
 .../ignite/internal/tx/impl/TxManagerImpl.java     |   2 +-
 38 files changed, 727 insertions(+), 473 deletions(-)

diff --git 
a/modules/api/src/main/java/org/apache/ignite/lang/ColumnAlreadyExistsException.java
 
b/modules/api/src/main/java/org/apache/ignite/lang/ColumnAlreadyExistsException.java
index fd61796..89f0282 100644
--- 
a/modules/api/src/main/java/org/apache/ignite/lang/ColumnAlreadyExistsException.java
+++ 
b/modules/api/src/main/java/org/apache/ignite/lang/ColumnAlreadyExistsException.java
@@ -27,6 +27,6 @@ public class ColumnAlreadyExistsException extends 
IgniteException {
      * @param name Column name.
      */
     public ColumnAlreadyExistsException(String name) {
-        super(LoggerMessageHelper.format("Column already exists [name={}]", 
name));
+        super(IgniteStringFormatter.format("Column already exists [name={}]", 
name));
     }
 }
diff --git 
a/modules/api/src/main/java/org/apache/ignite/lang/ColumnNotFoundException.java 
b/modules/api/src/main/java/org/apache/ignite/lang/ColumnNotFoundException.java
index 6747d3a..c0f578d 100644
--- 
a/modules/api/src/main/java/org/apache/ignite/lang/ColumnNotFoundException.java
+++ 
b/modules/api/src/main/java/org/apache/ignite/lang/ColumnNotFoundException.java
@@ -28,6 +28,6 @@ public class ColumnNotFoundException extends IgniteException {
      * @param fullName Table canonical name.
      */
     public ColumnNotFoundException(String columnName, String fullName) {
-        super(LoggerMessageHelper.format("Column '{}' does not exist in table 
'{}'", columnName, fullName));
+        super(IgniteStringFormatter.format("Column '{}' does not exist in 
table '{}'", columnName, fullName));
     }
 }
diff --git 
a/modules/api/src/main/java/org/apache/ignite/lang/IndexAlreadyExistsException.java
 
b/modules/api/src/main/java/org/apache/ignite/lang/IndexAlreadyExistsException.java
index 910009a..ce3b48a 100644
--- 
a/modules/api/src/main/java/org/apache/ignite/lang/IndexAlreadyExistsException.java
+++ 
b/modules/api/src/main/java/org/apache/ignite/lang/IndexAlreadyExistsException.java
@@ -27,6 +27,6 @@ public class IndexAlreadyExistsException extends 
IgniteException {
      * @param name Index name.
      */
     public IndexAlreadyExistsException(String name) {
-        super(LoggerMessageHelper.format("Index already exists [name={}]", 
name));
+        super(IgniteStringFormatter.format("Index already exists [name={}]", 
name));
     }
 }
diff --git 
a/modules/api/src/main/java/org/apache/ignite/lang/IndexNotFoundException.java 
b/modules/api/src/main/java/org/apache/ignite/lang/IndexNotFoundException.java
index c119fac..1e89aee 100644
--- 
a/modules/api/src/main/java/org/apache/ignite/lang/IndexNotFoundException.java
+++ 
b/modules/api/src/main/java/org/apache/ignite/lang/IndexNotFoundException.java
@@ -27,6 +27,6 @@ public class IndexNotFoundException extends IgniteException {
      * @param indexName Index canonical name.
      */
     public IndexNotFoundException(String indexName) {
-        super(LoggerMessageHelper.format("Index '{}' does not exist.", 
indexName));
+        super(IgniteStringFormatter.format("Index '{}' does not exist.", 
indexName));
     }
 }
diff --git 
a/modules/api/src/main/java/org/apache/ignite/lang/TableAlreadyExistsException.java
 
b/modules/api/src/main/java/org/apache/ignite/lang/TableAlreadyExistsException.java
index b9b3477..058d0fc 100644
--- 
a/modules/api/src/main/java/org/apache/ignite/lang/TableAlreadyExistsException.java
+++ 
b/modules/api/src/main/java/org/apache/ignite/lang/TableAlreadyExistsException.java
@@ -27,6 +27,6 @@ public class TableAlreadyExistsException extends 
IgniteException {
      * @param name Table name.
      */
     public TableAlreadyExistsException(String name) {
-        super(LoggerMessageHelper.format("Table already exists [name={}]", 
name));
+        super(IgniteStringFormatter.format("Table already exists [name={}]", 
name));
     }
 }
diff --git 
a/modules/api/src/main/java/org/apache/ignite/lang/TableAlreadyExistsException.java
 b/modules/api/src/main/java/org/apache/ignite/lang/TableNotFoundException.java
similarity index 75%
copy from 
modules/api/src/main/java/org/apache/ignite/lang/TableAlreadyExistsException.java
copy to 
modules/api/src/main/java/org/apache/ignite/lang/TableNotFoundException.java
index b9b3477..c066c9d 100644
--- 
a/modules/api/src/main/java/org/apache/ignite/lang/TableAlreadyExistsException.java
+++ 
b/modules/api/src/main/java/org/apache/ignite/lang/TableNotFoundException.java
@@ -18,15 +18,15 @@
 package org.apache.ignite.lang;
 
 /**
- * This exception is thrown when a new table failed to be created, because a 
table with same name already exists.
+ * Exception is thrown when appropriate table can`t be found.
  */
-public class TableAlreadyExistsException extends IgniteException {
+public class TableNotFoundException extends IgniteException {
     /**
      * Create a new exception with given table name.
      *
      * @param name Table name.
      */
-    public TableAlreadyExistsException(String name) {
-        super(LoggerMessageHelper.format("Table already exists [name={}]", 
name));
+    public TableNotFoundException(String name) {
+        super(IgniteStringFormatter.format("Table does not exist [name={}]", 
name));
     }
 }
diff --git 
a/modules/api/src/main/java/org/apache/ignite/table/manager/IgniteTables.java 
b/modules/api/src/main/java/org/apache/ignite/table/manager/IgniteTables.java
index 36f98c0..e20e8b7 100644
--- 
a/modules/api/src/main/java/org/apache/ignite/table/manager/IgniteTables.java
+++ 
b/modules/api/src/main/java/org/apache/ignite/table/manager/IgniteTables.java
@@ -23,6 +23,7 @@ import java.util.function.Consumer;
 import org.apache.ignite.configuration.schemas.table.TableChange;
 import org.apache.ignite.lang.IgniteException;
 import org.apache.ignite.lang.TableAlreadyExistsException;
+import org.apache.ignite.lang.TableNotFoundException;
 import org.apache.ignite.table.Table;
 
 /**
@@ -45,7 +46,7 @@ public interface IgniteTables {
 
     /**
      * Creates a new table with the given {@code name} asynchronously. If a 
table with the same name already exists, a future will be
-     * completed with exception.
+     * completed with the {@link TableAlreadyExistsException}.
      *
      * @param name            Table name.
      * @param tableInitChange Table changer.
@@ -59,40 +60,11 @@ public interface IgniteTables {
     CompletableFuture<Table> createTableAsync(String name, 
Consumer<TableChange> tableInitChange);
 
     /**
-     * Creates a new table with the given {@code name} or returns an existing 
one with the same {@code name}.
-     *
-     * <p>Note: the configuration of the existed table will NOT be validated 
against the given {@code tableInitChange}.
-     *
-     * @param name            Table name.
-     * @param tableInitChange Table changer.
-     * @return Existing or newly created table.
-     * @throws IgniteException If an unspecified platform exception has 
happened internally. Is thrown when:
-     *                         <ul>
-     *                             <li>the node is stopping.</li>
-     *                         </ul>
-     */
-    Table createTableIfNotExists(String name, Consumer<TableChange> 
tableInitChange);
-
-    /**
-     * Creates a new table with the given {@code name} or returns an existing 
one with the same {@code name}.
-     *
-     * <p>Note: the configuration of the existed table will NOT be validated 
against the given {@code tableInitChange}.
-     *
-     * @param name            Table name.
-     * @param tableInitChange Table changer.
-     * @return Future representing pending completion of the operation.
-     * @throws IgniteException If an unspecified platform exception has 
happened internally. Is thrown when:
-     *                         <ul>
-     *                             <li>the node is stopping.</li>
-     *                         </ul>
-     */
-    CompletableFuture<Table> createTableIfNotExistsAsync(String name, 
Consumer<TableChange> tableInitChange);
-
-    /**
-     * Alter a cluster table.
+     * Alters a cluster table. If the appropriate table does not exist, an 
exception will be thrown.
      *
      * @param name        Table name.
      * @param tableChange Table changer.
+     * @throws TableNotFoundException If a table with the {@code name} does 
not exist.
      * @throws IgniteException If an unspecified platform exception has 
happened internally. Is thrown when:
      *                         <ul>
      *                             <li>the node is stopping.</li>
@@ -101,7 +73,8 @@ public interface IgniteTables {
     void alterTable(String name, Consumer<TableChange> tableChange);
 
     /**
-     * Alter a cluster table.
+     * Alters a cluster table. If the appropriate table does not exist, a 
future will
+     * complete with the {@link TableNotFoundException}.
      *
      * @param name        Table name.
      * @param tableChange Table changer.
@@ -110,14 +83,15 @@ public interface IgniteTables {
      *                         <ul>
      *                             <li>the node is stopping.</li>
      *                         </ul>
+     * @see TableNotFoundException
      */
     CompletableFuture<Void> alterTableAsync(String name, Consumer<TableChange> 
tableChange);
 
     /**
-     * Drops a table with the name specified. If a table with the specified 
name does not exist in the cluster, the operation has no
-     * effect.
+     * Drops a table with the name specified. If the appropriate table does 
not exist, an exception will be thrown.
      *
      * @param name Table name.
+     * @throws TableNotFoundException If a table with the {@code name} does 
not exist.
      * @throws IgniteException If an unspecified platform exception has 
happened internally. Is thrown when:
      *                         <ul>
      *                             <li>the node is stopping.</li>
@@ -126,8 +100,8 @@ public interface IgniteTables {
     void dropTable(String name);
 
     /**
-     * Drops a table with the name specified. If a table with the specified 
name does not exist in the cluster, the operation has no
-     * effect.
+     * Drops a table with the name specified. If the appropriate table does 
not exist, a future will
+     * complete with the {@link TableNotFoundException}.
      *
      * @param name Table name.
      * @return Future representing pending completion of the operation.
@@ -135,6 +109,7 @@ public interface IgniteTables {
      *                         <ul>
      *                             <li>the node is stopping.</li>
      *                         </ul>
+     * @see TableNotFoundException
      */
     CompletableFuture<Void> dropTableAsync(String name);
 
diff --git 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/ddl/DdlCommandHandler.java
 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/ddl/DdlCommandHandler.java
index 6f9b5ba..1be6252 100644
--- 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/ddl/DdlCommandHandler.java
+++ 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/ddl/DdlCommandHandler.java
@@ -51,8 +51,10 @@ import org.apache.ignite.lang.ColumnAlreadyExistsException;
 import org.apache.ignite.lang.ColumnNotFoundException;
 import org.apache.ignite.lang.IgniteException;
 import org.apache.ignite.lang.IgniteInternalCheckedException;
+import org.apache.ignite.lang.IgniteStringFormatter;
 import org.apache.ignite.lang.IndexAlreadyExistsException;
-import org.apache.ignite.lang.LoggerMessageHelper;
+import org.apache.ignite.lang.TableAlreadyExistsException;
+import org.apache.ignite.lang.TableNotFoundException;
 import org.apache.ignite.schema.SchemaBuilders;
 import org.apache.ignite.schema.definition.builder.ColumnDefinitionBuilder;
 import org.apache.ignite.schema.definition.builder.PrimaryKeyDefinitionBuilder;
@@ -140,10 +142,12 @@ public class DdlCommandHandler {
 
         String fullName = TableDefinitionImpl.canonicalName(cmd.schemaName(), 
cmd.tableName());
 
-        if (cmd.ifTableExists()) {
-            tableManager.createTableIfNotExists(fullName, tblChanger);
-        } else {
+        try {
             tableManager.createTable(fullName, tblChanger);
+        } catch (TableAlreadyExistsException ex) {
+            if (!cmd.ifTableExists()) {
+                throw ex;
+            }
         }
     }
 
@@ -151,9 +155,13 @@ public class DdlCommandHandler {
     private void handleDropTable(DropTableCommand cmd) {
         String fullName = TableDefinitionImpl.canonicalName(cmd.schemaName(), 
cmd.tableName());
 
-        // if (!cmd.ifTableExists()) todo will be implemented after 
IGNITE-15926
-
-        tableManager.dropTable(fullName);
+        try {
+            tableManager.dropTable(fullName);
+        } catch (TableNotFoundException ex) {
+            if (!cmd.ifTableExists()) {
+                throw ex;
+            }
+        }
     }
 
     /** Handles add column command. */
@@ -162,11 +170,15 @@ public class DdlCommandHandler {
             return;
         }
 
-        // if (!cmd.ifTableExists()) todo will be implemented after 
IGNITE-15926
-
         String fullName = TableDefinitionImpl.canonicalName(cmd.schemaName(), 
cmd.tableName());
 
-        addColumnInternal(fullName, cmd.columns(), cmd.ifColumnNotExists());
+        try {
+            addColumnInternal(fullName, cmd.columns(), 
cmd.ifColumnNotExists());
+        } catch (TableNotFoundException ex) {
+            if (!cmd.ifTableExists()) {
+                throw ex;
+            }
+        }
     }
 
     /** Handles drop column command. */
@@ -175,11 +187,15 @@ public class DdlCommandHandler {
             return;
         }
 
-        // if (!cmd.ifTableExists()) todo will be implemented after 
IGNITE-15926
-
         String fullName = TableDefinitionImpl.canonicalName(cmd.schemaName(), 
cmd.tableName());
 
-        dropColumnInternal(fullName, cmd.columns(), cmd.ifColumnExists());
+        try {
+            dropColumnInternal(fullName, cmd.columns(), cmd.ifColumnExists());
+        } catch (TableNotFoundException ex) {
+            if (!cmd.ifTableExists()) {
+                throw ex;
+            }
+        }
     }
 
     /** Handles create index command. */
@@ -284,7 +300,7 @@ public class DdlCommandHandler {
                         }
 
                         if (primaryCols.contains(colName)) {
-                            throw new IgniteException(LoggerMessageHelper
+                            throw new IgniteException(IgniteStringFormatter
                                     .format("Can`t delete column, belongs to 
primary key: [name={}]", colName));
                         }
                     }
diff --git 
a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/exec/DdlWithMockedManagersTest.java
 
b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/exec/DdlWithMockedManagersTest.java
index 71b7ac4..5ceff9f 100644
--- 
a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/exec/DdlWithMockedManagersTest.java
+++ 
b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/exec/DdlWithMockedManagersTest.java
@@ -53,6 +53,7 @@ import org.apache.ignite.lang.IgniteInternalException;
 import org.apache.ignite.lang.IndexAlreadyExistsException;
 import org.apache.ignite.lang.NodeStoppingException;
 import org.apache.ignite.lang.TableAlreadyExistsException;
+import org.apache.ignite.lang.TableNotFoundException;
 import org.apache.ignite.network.ClusterLocalConfiguration;
 import org.apache.ignite.network.ClusterNode;
 import org.apache.ignite.network.ClusterService;
@@ -224,21 +225,20 @@ public class DdlWithMockedManagersTest extends 
IgniteAbstractTest {
 
         queryProc.query("PUBLIC", "DROP TABLE " + curMethodName);
 
-        // todo will be implemented after IGNITE-15926
-        /*SqlQueryProcessor finalQueryProc = queryProc;
-        
-        assertThrows(IgniteInternalCheckedException.class, () -> 
finalQueryProc.query("PUBLIC",
-            "DROP TABLE " + curMethodName + "_not_exist"));
-    
-        assertThrows(IgniteInternalCheckedException.class, () -> 
finalQueryProc.query("PUBLIC",
-            "DROP TABLE " + curMethodName));
+        SqlQueryProcessor finalQueryProc = queryProc;
 
-        assertThrows(IgniteInternalCheckedException.class, () -> 
finalQueryProc.query("PUBLIC",
-            "DROP TABLE PUBLIC." + curMethodName));
+        assertThrows(TableNotFoundException.class, () -> 
finalQueryProc.query("PUBLIC",
+                "DROP TABLE " + curMethodName + "_not_exist"));
 
-        queryProc.query("PUBLIC", "DROP TABLE IF EXISTS PUBLIC." + 
curMethodName);
+        assertThrows(TableNotFoundException.class, () -> 
finalQueryProc.query("PUBLIC",
+                "DROP TABLE " + curMethodName));
+
+        assertThrows(TableNotFoundException.class, () -> 
finalQueryProc.query("PUBLIC",
+                "DROP TABLE PUBLIC." + curMethodName));
 
-        queryProc.query("PUBLIC", "DROP TABLE PUBLIC." + curMethodName);*/
+        queryProc.query("PUBLIC", "DROP TABLE IF EXISTS PUBLIC." + 
curMethodName + "_not_exist");
+
+        queryProc.query("PUBLIC", "DROP TABLE IF EXISTS PUBLIC." + 
curMethodName);
 
         assertTrue(tblManager.tables().stream().noneMatch(t -> t.name()
                 .equalsIgnoreCase("PUBLIC." + curMethodName)));
@@ -267,10 +267,9 @@ public class DdlWithMockedManagersTest extends 
IgniteAbstractTest {
 
         assertThrows(ColumnAlreadyExistsException.class, () -> 
finalQueryProc.query("PUBLIC", alterCmd));
 
-        // todo will be implemented after IGNITE-15926
-        /*String alterCmdNoTbl = String.format("ALTER TABLE %s ADD COLUMN (c3 
varchar, c4 int)", curMethodName + "_notExist");
+        String alterCmdNoTbl = String.format("ALTER TABLE %s ADD COLUMN (c3 
varchar, c4 int)", curMethodName + "_notExist");
 
-        queryProc.query("PUBLIC", alterCmdNoTbl);
+        assertThrows(TableNotFoundException.class, () -> 
queryProc.query("PUBLIC", alterCmdNoTbl));
 
         String alterIfExistsCmd = String.format("ALTER TABLE IF EXISTS %s ADD 
COLUMN (c3 varchar, c4 int)", curMethodName + "NotExist");
 
@@ -279,7 +278,6 @@ public class DdlWithMockedManagersTest extends 
IgniteAbstractTest {
         assertThrows(ColumnAlreadyExistsException.class, () -> 
finalQueryProc.query("PUBLIC", alterCmd));
 
         finalQueryProc.query("PUBLIC", String.format("ALTER TABLE %s DROP 
COLUMN c4", curMethodName));
-        */
 
         queryProc.query("PUBLIC", String.format("ALTER TABLE %s ADD COLUMN IF 
NOT EXISTS c3 varchar", curMethodName));
 
diff --git 
a/modules/client/src/main/java/org/apache/ignite/internal/client/table/ClientTables.java
 
b/modules/client/src/main/java/org/apache/ignite/internal/client/table/ClientTables.java
index 1de7f6b..3a5a7a5 100644
--- 
a/modules/client/src/main/java/org/apache/ignite/internal/client/table/ClientTables.java
+++ 
b/modules/client/src/main/java/org/apache/ignite/internal/client/table/ClientTables.java
@@ -75,21 +75,6 @@ public class ClientTables implements IgniteTables {
 
     /** {@inheritDoc} */
     @Override
-    public Table createTableIfNotExists(String name, Consumer<TableChange> 
tableInitChange) {
-        return createTableIfNotExistsAsync(name, tableInitChange).join();
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public CompletableFuture<Table> createTableIfNotExistsAsync(String name, 
Consumer<TableChange> tableInitChange) {
-        Objects.requireNonNull(name);
-        Objects.requireNonNull(tableInitChange);
-
-        throw new UnsupportedOperationException("Not implemented yet.");
-    }
-
-    /** {@inheritDoc} */
-    @Override
     public void dropTable(String name) {
         dropTableAsync(name).join();
     }
diff --git 
a/modules/client/src/test/java/org/apache/ignite/client/AbstractClientTableTest.java
 
b/modules/client/src/test/java/org/apache/ignite/client/AbstractClientTableTest.java
index f6546ed..410855d 100644
--- 
a/modules/client/src/test/java/org/apache/ignite/client/AbstractClientTableTest.java
+++ 
b/modules/client/src/test/java/org/apache/ignite/client/AbstractClientTableTest.java
@@ -89,13 +89,15 @@ public class AbstractClientTableTest extends 
AbstractClientTest {
     }
 
     protected Table defaultTable() {
-        server.tables().createTableIfNotExists(DEFAULT_TABLE, tbl -> 
tbl.changeReplicas(1));
+        server.tables().createTable(DEFAULT_TABLE, tbl -> 
tbl.changeReplicas(1));
 
         return client.tables().table(DEFAULT_TABLE);
     }
 
     protected Table tableWithDefaultValues() {
-        server.tables().createTableIfNotExists(TABLE_WITH_DEFAULT_VALUES, tbl 
-> tbl.changeReplicas(1));
+        if (server.tables().table(TABLE_WITH_DEFAULT_VALUES) == null) {
+            server.tables().createTable(TABLE_WITH_DEFAULT_VALUES, tbl -> 
tbl.changeReplicas(1));
+        }
 
         return client.tables().table(TABLE_WITH_DEFAULT_VALUES);
     }
@@ -126,7 +128,9 @@ public class AbstractClientTableTest extends 
AbstractClientTest {
     }
 
     protected Table fullTable() {
-        server.tables().createTableIfNotExists(TABLE_ALL_COLUMNS, tbl -> 
tbl.changeReplicas(1));
+        if (server.tables().table(TABLE_ALL_COLUMNS) == null) {
+            server.tables().createTable(TABLE_ALL_COLUMNS, tbl -> 
tbl.changeReplicas(1));
+        }
 
         return client.tables().table(TABLE_ALL_COLUMNS);
     }
@@ -136,7 +140,9 @@ public class AbstractClientTableTest extends 
AbstractClientTest {
     }
 
     protected Table oneColumnTable() {
-        server.tables().createTableIfNotExists(TABLE_ONE_COLUMN, tbl -> 
tbl.changeReplicas(1));
+        if (server.tables().table(TABLE_ONE_COLUMN) == null) {
+            server.tables().createTable(TABLE_ONE_COLUMN, tbl -> 
tbl.changeReplicas(1));
+        }
 
         return client.tables().table(TABLE_ONE_COLUMN);
     }
diff --git 
a/modules/client/src/test/java/org/apache/ignite/client/fakes/FakeIgniteTables.java
 
b/modules/client/src/test/java/org/apache/ignite/client/fakes/FakeIgniteTables.java
index 6a4b5c2..5c69493 100644
--- 
a/modules/client/src/test/java/org/apache/ignite/client/fakes/FakeIgniteTables.java
+++ 
b/modules/client/src/test/java/org/apache/ignite/client/fakes/FakeIgniteTables.java
@@ -87,28 +87,6 @@ public class FakeIgniteTables implements IgniteTables, 
IgniteTablesInternal {
 
     /** {@inheritDoc} */
     @Override
-    public Table createTableIfNotExists(String name, Consumer<TableChange> 
tableInitChange) {
-        var newTable = getNewTable(name);
-
-        var oldTable = tables.putIfAbsent(name, newTable);
-
-        if (oldTable != null) {
-            return oldTable;
-        }
-
-        tablesById.put(newTable.tableId(), newTable);
-
-        return newTable;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public CompletableFuture<Table> createTableIfNotExistsAsync(String name, 
Consumer<TableChange> tableInitChange) {
-        return CompletableFuture.completedFuture(createTableIfNotExists(name, 
tableInitChange));
-    }
-
-    /** {@inheritDoc} */
-    @Override
     public void dropTable(String name) {
         var table = tables.remove(name);
 
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/util/ByteUtils.java 
b/modules/core/src/main/java/org/apache/ignite/internal/util/ByteUtils.java
index fba94d1..bc478f1 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/util/ByteUtils.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/util/ByteUtils.java
@@ -22,7 +22,7 @@ import java.io.ByteArrayOutputStream;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
 import org.apache.ignite.lang.IgniteLogger;
-import org.apache.ignite.lang.LoggerMessageHelper;
+import org.apache.ignite.lang.IgniteStringFormatter;
 
 /**
  * Utility class provides various method for manipulating with bytes.
@@ -120,7 +120,7 @@ public class ByteUtils {
             }
         } catch (Exception e) {
             LOG.warn(() ->
-                            LoggerMessageHelper.format("Could not serialize a 
class [cls={}]", obj.getClass().getName()),
+                            IgniteStringFormatter.format("Could not serialize 
a class [cls={}]", obj.getClass().getName()),
                     e);
 
             return null;
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java 
b/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java
index e21f081..aea480e 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java
@@ -42,7 +42,7 @@ import java.util.concurrent.atomic.AtomicReference;
 import java.util.function.Predicate;
 import java.util.stream.Stream;
 import org.apache.ignite.lang.IgniteLogger;
-import org.apache.ignite.lang.LoggerMessageHelper;
+import org.apache.ignite.lang.IgniteStringFormatter;
 import org.jetbrains.annotations.Nullable;
 
 /**
@@ -522,7 +522,7 @@ public class IgniteUtils {
     public static void dumpStack(IgniteLogger log, String msg, Object... 
params) {
         String reason = "Dumping stack.";
 
-        var err = new Exception(LoggerMessageHelper.format(msg, params));
+        var err = new Exception(IgniteStringFormatter.format(msg, params));
 
         if (log != null) {
             log.error(reason, err);
diff --git 
a/modules/core/src/main/java/org/apache/ignite/lang/IgniteLogger.java 
b/modules/core/src/main/java/org/apache/ignite/lang/IgniteLogger.java
index eaa60c9..8fa7a85 100644
--- a/modules/core/src/main/java/org/apache/ignite/lang/IgniteLogger.java
+++ b/modules/core/src/main/java/org/apache/ignite/lang/IgniteLogger.java
@@ -257,7 +257,7 @@ public class IgniteLogger {
      * Logs a message with an optional list of parameters.
      *
      * @param level  One of the log message level identifiers.
-     * @param msg    The string message format in {@link LoggerMessageHelper} 
format.
+     * @param msg    The string message format in {@link 
IgniteStringFormatter} format.
      * @param th     The {@code Throwable} associated with the log message.
      * @param params An optional list of parameters to the message (may be 
none).
      * @throws NullPointerException If {@code level} is {@code null}.
@@ -270,9 +270,9 @@ public class IgniteLogger {
         }
 
         if (th != null) {
-            log.log(level, LoggerMessageHelper.arrayFormat(msg, params), th);
+            log.log(level, IgniteStringFormatter.arrayFormat(msg, params), th);
         } else {
-            log.log(level, LoggerMessageHelper.arrayFormat(msg, params));
+            log.log(level, IgniteStringFormatter.arrayFormat(msg, params));
         }
     }
 
diff --git 
a/modules/core/src/main/java/org/apache/ignite/lang/LoggerMessageHelper.java 
b/modules/core/src/main/java/org/apache/ignite/lang/IgniteStringFormatter.java
similarity index 99%
rename from 
modules/core/src/main/java/org/apache/ignite/lang/LoggerMessageHelper.java
rename to 
modules/core/src/main/java/org/apache/ignite/lang/IgniteStringFormatter.java
index 4992f4d..c65f28b 100644
--- a/modules/core/src/main/java/org/apache/ignite/lang/LoggerMessageHelper.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/lang/IgniteStringFormatter.java
@@ -60,7 +60,7 @@ import java.util.HashSet;
  *
  * <p>will return the string "File name is C:\file.zip".
  */
-public final class LoggerMessageHelper {
+public final class IgniteStringFormatter {
     /** Left brace. */
     private static final char DELIM_START = '{';
 
diff --git 
a/modules/core/src/test/java/org/apache/ignite/internal/testframework/IgniteAbstractTest.java
 
b/modules/core/src/test/java/org/apache/ignite/internal/testframework/BaseIgniteAbstractTest.java
similarity index 83%
copy from 
modules/core/src/test/java/org/apache/ignite/internal/testframework/IgniteAbstractTest.java
copy to 
modules/core/src/test/java/org/apache/ignite/internal/testframework/BaseIgniteAbstractTest.java
index a95b781..ddb2fed 100644
--- 
a/modules/core/src/test/java/org/apache/ignite/internal/testframework/IgniteAbstractTest.java
+++ 
b/modules/core/src/test/java/org/apache/ignite/internal/testframework/BaseIgniteAbstractTest.java
@@ -26,25 +26,20 @@ import java.nio.file.Path;
 import org.apache.ignite.internal.tostring.S;
 import org.apache.ignite.internal.tostring.SensitiveDataLoggingPolicy;
 import org.apache.ignite.lang.IgniteLogger;
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.TestInfo;
 import org.junit.jupiter.api.extension.ExtendWith;
 
 /**
  * Ignite base test class.
  */
-@ExtendWith({SystemPropertiesExtension.class, WorkDirectoryExtension.class})
-public abstract class IgniteAbstractTest {
+@ExtendWith(SystemPropertiesExtension.class)
+public abstract class BaseIgniteAbstractTest {
     /** Logger. */
     protected static IgniteLogger log;
 
     /** Tets start milliseconds. */
     private long testStartMs;
 
-    /** Work directory. */
-    protected Path workDir;
-
     /* Init test env. */
     static {
         S.setSensitiveDataLoggingPolicySupplier(() ->
@@ -52,32 +47,29 @@ public abstract class IgniteAbstractTest {
     }
 
     /**
-     * Invokes before the test will start.
+     * Should be invoked before a test will start.
      *
      * @param testInfo Test information oject.
      * @param workDir  Work directory.
      * @throws Exception If failed.
      */
-    @BeforeEach
-    public void setup(TestInfo testInfo, @WorkDirectory Path workDir) throws 
Exception {
+    protected void setupBase(TestInfo testInfo, Path workDir) throws Exception 
{
         log.info(">>> Starting test: {}#{}, displayName: {}, workDir: {}",
                 testInfo.getTestClass().map(Class::getSimpleName).orElseGet(() 
-> "<null>"),
                 testInfo.getTestMethod().map(Method::getName).orElseGet(() -> 
"<null>"),
                 testInfo.getDisplayName(),
                 workDir.toAbsolutePath());
 
-        this.workDir = workDir;
         this.testStartMs = monotonicMs();
     }
 
     /**
-     * Invokes after the test has finished.
+     * Should be invoked after the test has finished.
      *
      * @param testInfo Test information oject.
      * @throws Exception If failed.
      */
-    @AfterEach
-    public void tearDown(TestInfo testInfo) throws Exception {
+    protected void tearDownBase(TestInfo testInfo) throws Exception {
         log.info(">>> Stopping test: {}#{}, displayName: {}, cost: {}ms.",
                 testInfo.getTestClass().map(Class::getSimpleName).orElseGet(() 
-> "<null>"),
                 testInfo.getTestMethod().map(Method::getName).orElseGet(() -> 
"<null>"),
@@ -88,7 +80,7 @@ public abstract class IgniteAbstractTest {
      * Constructor.
      */
     @SuppressWarnings("AssignmentToStaticFieldFromInstanceMethod")
-    protected IgniteAbstractTest() {
+    protected BaseIgniteAbstractTest() {
         log = IgniteLogger.forClass(getClass());
     }
 
diff --git 
a/modules/core/src/test/java/org/apache/ignite/internal/testframework/IgniteAbstractTest.java
 
b/modules/core/src/test/java/org/apache/ignite/internal/testframework/IgniteAbstractTest.java
index a95b781..4ad902b 100644
--- 
a/modules/core/src/test/java/org/apache/ignite/internal/testframework/IgniteAbstractTest.java
+++ 
b/modules/core/src/test/java/org/apache/ignite/internal/testframework/IgniteAbstractTest.java
@@ -17,15 +17,7 @@
 
 package org.apache.ignite.internal.testframework;
 
-import static org.apache.ignite.internal.util.IgniteUtils.monotonicMs;
-import static 
org.apache.ignite.lang.IgniteSystemProperties.IGNITE_SENSITIVE_DATA_LOGGING;
-import static org.apache.ignite.lang.IgniteSystemProperties.getString;
-
-import java.lang.reflect.Method;
 import java.nio.file.Path;
-import org.apache.ignite.internal.tostring.S;
-import org.apache.ignite.internal.tostring.SensitiveDataLoggingPolicy;
-import org.apache.ignite.lang.IgniteLogger;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.TestInfo;
@@ -34,23 +26,11 @@ import org.junit.jupiter.api.extension.ExtendWith;
 /**
  * Ignite base test class.
  */
-@ExtendWith({SystemPropertiesExtension.class, WorkDirectoryExtension.class})
-public abstract class IgniteAbstractTest {
-    /** Logger. */
-    protected static IgniteLogger log;
-
-    /** Tets start milliseconds. */
-    private long testStartMs;
-
+@ExtendWith(WorkDirectoryExtension.class)
+public abstract class IgniteAbstractTest extends BaseIgniteAbstractTest {
     /** Work directory. */
     protected Path workDir;
 
-    /* Init test env. */
-    static {
-        S.setSensitiveDataLoggingPolicySupplier(() ->
-                
SensitiveDataLoggingPolicy.valueOf(getString(IGNITE_SENSITIVE_DATA_LOGGING, 
"hash").toUpperCase()));
-    }
-
     /**
      * Invokes before the test will start.
      *
@@ -60,14 +40,9 @@ public abstract class IgniteAbstractTest {
      */
     @BeforeEach
     public void setup(TestInfo testInfo, @WorkDirectory Path workDir) throws 
Exception {
-        log.info(">>> Starting test: {}#{}, displayName: {}, workDir: {}",
-                testInfo.getTestClass().map(Class::getSimpleName).orElseGet(() 
-> "<null>"),
-                testInfo.getTestMethod().map(Method::getName).orElseGet(() -> 
"<null>"),
-                testInfo.getDisplayName(),
-                workDir.toAbsolutePath());
+        setupBase(testInfo, workDir);
 
         this.workDir = workDir;
-        this.testStartMs = monotonicMs();
     }
 
     /**
@@ -78,26 +53,6 @@ public abstract class IgniteAbstractTest {
      */
     @AfterEach
     public void tearDown(TestInfo testInfo) throws Exception {
-        log.info(">>> Stopping test: {}#{}, displayName: {}, cost: {}ms.",
-                testInfo.getTestClass().map(Class::getSimpleName).orElseGet(() 
-> "<null>"),
-                testInfo.getTestMethod().map(Method::getName).orElseGet(() -> 
"<null>"),
-                testInfo.getDisplayName(), monotonicMs() - testStartMs);
-    }
-
-    /**
-     * Constructor.
-     */
-    @SuppressWarnings("AssignmentToStaticFieldFromInstanceMethod")
-    protected IgniteAbstractTest() {
-        log = IgniteLogger.forClass(getClass());
-    }
-
-    /**
-     * Returns logger.
-     *
-     * @return Logger.
-     */
-    protected IgniteLogger logger() {
-        return log;
+        tearDownBase(testInfo);
     }
 }
diff --git 
a/modules/core/src/test/java/org/apache/ignite/internal/testframework/IgniteTestUtils.java
 
b/modules/core/src/test/java/org/apache/ignite/internal/testframework/IgniteTestUtils.java
index cee117a..0d58dcf 100644
--- 
a/modules/core/src/test/java/org/apache/ignite/internal/testframework/IgniteTestUtils.java
+++ 
b/modules/core/src/test/java/org/apache/ignite/internal/testframework/IgniteTestUtils.java
@@ -30,7 +30,7 @@ import java.util.concurrent.CompletableFuture;
 import java.util.function.BooleanSupplier;
 import org.apache.ignite.internal.thread.NamedThreadFactory;
 import org.apache.ignite.lang.IgniteInternalException;
-import org.apache.ignite.lang.LoggerMessageHelper;
+import org.apache.ignite.lang.IgniteStringFormatter;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 import org.junit.jupiter.api.TestInfo;
@@ -346,7 +346,7 @@ public final class IgniteTestUtils {
      * @return Node name.
      */
     public static String testNodeName(TestInfo testInfo, int idx) {
-        return LoggerMessageHelper.format("{}_{}_{}",
+        return IgniteStringFormatter.format("{}_{}_{}",
                 testInfo.getTestClass().map(Class::getSimpleName).orElseGet(() 
-> "null"),
                 testInfo.getTestMethod().map(Method::getName).orElseGet(() -> 
"null"),
                 idx);
diff --git 
a/modules/core/src/test/java/org/apache/ignite/lang/LoggerHelperTest.java 
b/modules/core/src/test/java/org/apache/ignite/lang/LoggerHelperTest.java
index 2acbe88..b04c931 100644
--- a/modules/core/src/test/java/org/apache/ignite/lang/LoggerHelperTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/lang/LoggerHelperTest.java
@@ -48,7 +48,7 @@ public class LoggerHelperTest {
      */
     @Test
     public void testNull() {
-        result = LoggerMessageHelper.format(null, i1);
+        result = IgniteStringFormatter.format(null, i1);
         assertEquals(null, result);
     }
 
@@ -57,25 +57,25 @@ public class LoggerHelperTest {
      */
     @Test
     public void nullParametersShouldBeHandledWithoutBarfing() {
-        result = LoggerMessageHelper.format("Value is {}.", new 
Object[]{null});
+        result = IgniteStringFormatter.format("Value is {}.", new 
Object[]{null});
         assertEquals("Value is null.", result);
 
-        result = LoggerMessageHelper.format("Val1 is {}, val2 is {}.", null, 
null);
+        result = IgniteStringFormatter.format("Val1 is {}, val2 is {}.", null, 
null);
         assertEquals("Val1 is null, val2 is null.", result);
 
-        result = LoggerMessageHelper.format("Val1 is {}, val2 is {}.", i1, 
null);
+        result = IgniteStringFormatter.format("Val1 is {}, val2 is {}.", i1, 
null);
         assertEquals("Val1 is 1, val2 is null.", result);
 
-        result = LoggerMessageHelper.format("Val1 is {}, val2 is {}.", null, 
i2);
+        result = IgniteStringFormatter.format("Val1 is {}, val2 is {}.", null, 
i2);
         assertEquals("Val1 is null, val2 is 2.", result);
 
-        result = LoggerMessageHelper.format("Val1 is {}, val2 is {}, val3 is 
{}", new Integer[]{null, null, null});
+        result = IgniteStringFormatter.format("Val1 is {}, val2 is {}, val3 is 
{}", new Integer[]{null, null, null});
         assertEquals("Val1 is null, val2 is null, val3 is null", result);
 
-        result = LoggerMessageHelper.format("Val1 is {}, val2 is {}, val3 is 
{}", new Integer[]{null, i2, i3});
+        result = IgniteStringFormatter.format("Val1 is {}, val2 is {}, val3 is 
{}", new Integer[]{null, i2, i3});
         assertEquals("Val1 is null, val2 is 2, val3 is 3", result);
 
-        result = LoggerMessageHelper.format("Val1 is {}, val2 is {}, val3 is 
{}", new Integer[]{null, null, i3});
+        result = IgniteStringFormatter.format("Val1 is {}, val2 is {}, val3 is 
{}", new Integer[]{null, null, i3});
         assertEquals("Val1 is null, val2 is null, val3 is 3", result);
     }
 
@@ -84,38 +84,38 @@ public class LoggerHelperTest {
      */
     @Test
     public void verifyOneParameterIsHandledCorrectly() {
-        result = LoggerMessageHelper.format("Value is {}.", i3);
+        result = IgniteStringFormatter.format("Value is {}.", i3);
         assertEquals("Value is 3.", result);
 
-        result = LoggerMessageHelper.format("Value is {", i3);
+        result = IgniteStringFormatter.format("Value is {", i3);
         assertEquals("Value is {", result);
 
-        result = LoggerMessageHelper.format("{} is larger than 2.", i3);
+        result = IgniteStringFormatter.format("{} is larger than 2.", i3);
         assertEquals("3 is larger than 2.", result);
 
-        result = LoggerMessageHelper.format("No subst", i3);
+        result = IgniteStringFormatter.format("No subst", i3);
         assertEquals("No subst", result);
 
-        result = LoggerMessageHelper.format("Incorrect {subst", i3);
+        result = IgniteStringFormatter.format("Incorrect {subst", i3);
         assertEquals("Incorrect {subst", result);
 
-        result = LoggerMessageHelper.format("Value is {bla} {}", i3);
+        result = IgniteStringFormatter.format("Value is {bla} {}", i3);
         assertEquals("Value is {bla} 3", result);
 
-        result = LoggerMessageHelper.format("Escaped \\{} subst", i3);
+        result = IgniteStringFormatter.format("Escaped \\{} subst", i3);
         assertEquals("Escaped {} subst", result);
 
-        result = LoggerMessageHelper.format("{Escaped", i3);
+        result = IgniteStringFormatter.format("{Escaped", i3);
         assertEquals("{Escaped", result);
 
-        result = LoggerMessageHelper.format("\\{}Escaped", i3);
+        result = IgniteStringFormatter.format("\\{}Escaped", i3);
         assertEquals("{}Escaped", result);
 
-        result = LoggerMessageHelper.format("File name is {{}}.", "App 
folder.zip");
+        result = IgniteStringFormatter.format("File name is {{}}.", "App 
folder.zip");
         assertEquals("File name is {App folder.zip}.", result);
 
         // escaping the escape character
-        result = LoggerMessageHelper.format("File name is C:\\\\{}.", "App 
folder.zip");
+        result = IgniteStringFormatter.format("File name is C:\\\\{}.", "App 
folder.zip");
         assertEquals("File name is C:\\App folder.zip.", result);
     }
 
@@ -124,31 +124,31 @@ public class LoggerHelperTest {
      */
     @Test
     public void testTwoParameters() {
-        result = LoggerMessageHelper.format("Value {} is smaller than {}.", 
i1, i2);
+        result = IgniteStringFormatter.format("Value {} is smaller than {}.", 
i1, i2);
         assertEquals("Value 1 is smaller than 2.", result);
 
-        result = LoggerMessageHelper.format("Value {} is smaller than {}", i1, 
i2);
+        result = IgniteStringFormatter.format("Value {} is smaller than {}", 
i1, i2);
         assertEquals("Value 1 is smaller than 2", result);
 
-        result = LoggerMessageHelper.format("{}{}", i1, i2);
+        result = IgniteStringFormatter.format("{}{}", i1, i2);
         assertEquals("12", result);
 
-        result = LoggerMessageHelper.format("Val1={}, Val2={", i1, i2);
+        result = IgniteStringFormatter.format("Val1={}, Val2={", i1, i2);
         assertEquals("Val1=1, Val2={", result);
 
-        result = LoggerMessageHelper.format("Value {} is smaller than \\{}", 
i1, i2);
+        result = IgniteStringFormatter.format("Value {} is smaller than \\{}", 
i1, i2);
         assertEquals("Value 1 is smaller than {}", result);
 
-        result = LoggerMessageHelper.format("Value {} is smaller than \\{} 
tail", i1, i2);
+        result = IgniteStringFormatter.format("Value {} is smaller than \\{} 
tail", i1, i2);
         assertEquals("Value 1 is smaller than {} tail", result);
 
-        result = LoggerMessageHelper.format("Value {} is smaller than \\{", 
i1, i2);
+        result = IgniteStringFormatter.format("Value {} is smaller than \\{", 
i1, i2);
         assertEquals("Value 1 is smaller than \\{", result);
 
-        result = LoggerMessageHelper.format("Value {} is smaller than {tail", 
i1, i2);
+        result = IgniteStringFormatter.format("Value {} is smaller than 
{tail", i1, i2);
         assertEquals("Value 1 is smaller than {tail", result);
 
-        result = LoggerMessageHelper.format("Value \\{} is smaller than {}", 
i1, i2);
+        result = IgniteStringFormatter.format("Value \\{} is smaller than {}", 
i1, i2);
         assertEquals("Value {} is smaller than 1", result);
     }
 
@@ -159,7 +159,7 @@ public class LoggerHelperTest {
                 throw new IllegalStateException("a");
             }
         };
-        result = LoggerMessageHelper.format("Troublesome object {}", o);
+        result = IgniteStringFormatter.format("Troublesome object {}", o);
         assertEquals("Troublesome object Failed toString() invocation on an 
object of type [cls=" + o.getClass().getName()
                 + ", errMsg=java.lang.IllegalStateException, errMsg=a]", 
result);
     }
@@ -173,16 +173,16 @@ public class LoggerHelperTest {
 
         Object[] args = null;
 
-        result = LoggerMessageHelper.format(msg0, args);
+        result = IgniteStringFormatter.format(msg0, args);
         assertEquals(msg0, result);
 
-        result = LoggerMessageHelper.format(msg1, args);
+        result = IgniteStringFormatter.format(msg1, args);
         assertEquals(msg1, result);
 
-        result = LoggerMessageHelper.format(msg2, args);
+        result = IgniteStringFormatter.format(msg2, args);
         assertEquals(msg2, result);
 
-        result = LoggerMessageHelper.format(msg3, args);
+        result = IgniteStringFormatter.format(msg3, args);
         assertEquals(msg3, result);
     }
 
@@ -191,25 +191,25 @@ public class LoggerHelperTest {
      */
     @Test
     public void testArrayFormat() {
-        result = LoggerMessageHelper.format("Value {} is smaller than {} and 
{}.", ia0);
+        result = IgniteStringFormatter.format("Value {} is smaller than {} and 
{}.", ia0);
         assertEquals("Value 1 is smaller than 2 and 3.", result);
 
-        result = LoggerMessageHelper.format("{}{}{}", ia0);
+        result = IgniteStringFormatter.format("{}{}{}", ia0);
         assertEquals("123", result);
 
-        result = LoggerMessageHelper.format("Value {} is smaller than {}.", 
ia0);
+        result = IgniteStringFormatter.format("Value {} is smaller than {}.", 
ia0);
         assertEquals("Value 1 is smaller than 2.", result);
 
-        result = LoggerMessageHelper.format("Value {} is smaller than {}", 
ia0);
+        result = IgniteStringFormatter.format("Value {} is smaller than {}", 
ia0);
         assertEquals("Value 1 is smaller than 2", result);
 
-        result = LoggerMessageHelper.format("Val={}, {, Val={}", ia0);
+        result = IgniteStringFormatter.format("Val={}, {, Val={}", ia0);
         assertEquals("Val=1, {, Val=2", result);
 
-        result = LoggerMessageHelper.format("Val={}, {, Val={}", ia0);
+        result = IgniteStringFormatter.format("Val={}, {, Val={}", ia0);
         assertEquals("Val=1, {, Val=2", result);
 
-        result = LoggerMessageHelper.format("Val1={}, Val2={", ia0);
+        result = IgniteStringFormatter.format("Val1={}, Val2={", ia0);
         assertEquals("Val1=1, Val2={", result);
     }
 
@@ -218,50 +218,50 @@ public class LoggerHelperTest {
         Integer p0 = i1;
         Integer[] p1 = new Integer[]{i2, i3};
 
-        result = LoggerMessageHelper.format("{}{}", p0, p1);
+        result = IgniteStringFormatter.format("{}{}", p0, p1);
         assertEquals("1[2, 3]", result);
 
         // Integer[]
-        result = LoggerMessageHelper.format("{}{}", new Object[]{"a", p1});
+        result = IgniteStringFormatter.format("{}{}", new Object[]{"a", p1});
         assertEquals("a[2, 3]", result);
 
         // byte[]
-        result = LoggerMessageHelper.format("{}{}", new Object[]{"a", new 
byte[]{1, 2}});
+        result = IgniteStringFormatter.format("{}{}", new Object[]{"a", new 
byte[]{1, 2}});
         assertEquals("a[1, 2]", result);
 
         // int[]
-        result = LoggerMessageHelper.format("{}{}", new Object[]{"a", new 
int[]{1, 2}});
+        result = IgniteStringFormatter.format("{}{}", new Object[]{"a", new 
int[]{1, 2}});
         assertEquals("a[1, 2]", result);
 
         // float[]
-        result = LoggerMessageHelper.format("{}{}", new Object[]{"a", new 
float[]{1, 2}});
+        result = IgniteStringFormatter.format("{}{}", new Object[]{"a", new 
float[]{1, 2}});
         assertEquals("a[1.0, 2.0]", result);
 
         // double[]
-        result = LoggerMessageHelper.format("{}{}", new Object[]{"a", new 
double[]{1, 2}});
+        result = IgniteStringFormatter.format("{}{}", new Object[]{"a", new 
double[]{1, 2}});
         assertEquals("a[1.0, 2.0]", result);
     }
 
     @Test
     public void testMultiDimensionalArrayValues() {
         Integer[][] multiIntegerA = new Integer[][]{ia0, ia1};
-        result = LoggerMessageHelper.format("{}{}", new Object[]{"a", 
multiIntegerA});
+        result = IgniteStringFormatter.format("{}{}", new Object[]{"a", 
multiIntegerA});
         assertEquals("a[[1, 2, 3], [10, 20, 30]]", result);
 
         int[][] multiIntA = new int[][]{{1, 2}, {10, 20}};
-        result = LoggerMessageHelper.format("{}{}", new Object[]{"a", 
multiIntA});
+        result = IgniteStringFormatter.format("{}{}", new Object[]{"a", 
multiIntA});
         assertEquals("a[[1, 2], [10, 20]]", result);
 
         float[][] multiFloatA = new float[][]{{1, 2}, {10, 20}};
-        result = LoggerMessageHelper.format("{}{}", new Object[]{"a", 
multiFloatA});
+        result = IgniteStringFormatter.format("{}{}", new Object[]{"a", 
multiFloatA});
         assertEquals("a[[1.0, 2.0], [10.0, 20.0]]", result);
 
         Object[][] multiOa = new Object[][]{ia0, ia1};
-        result = LoggerMessageHelper.format("{}{}", new Object[]{"a", 
multiOa});
+        result = IgniteStringFormatter.format("{}{}", new Object[]{"a", 
multiOa});
         assertEquals("a[[1, 2, 3], [10, 20, 30]]", result);
 
         Object[][][] multiOa3 = new Object[][][]{multiOa, multiOa};
-        result = LoggerMessageHelper.format("{}{}", new Object[]{"a", 
multiOa3});
+        result = IgniteStringFormatter.format("{}{}", new Object[]{"a", 
multiOa3});
         assertEquals("a[[[1, 2, 3], [10, 20, 30]], [[1, 2, 3], [10, 20, 
30]]]", result);
     }
 
@@ -269,14 +269,14 @@ public class LoggerHelperTest {
     public void testCyclicArrays() {
         Object[] cyclicA = new Object[1];
         cyclicA[0] = cyclicA;
-        assertEquals("[[...]]", LoggerMessageHelper.format("{}", cyclicA));
+        assertEquals("[[...]]", IgniteStringFormatter.format("{}", cyclicA));
 
         Object[] a = new Object[2];
         a[0] = i1;
         Object[] c = new Object[]{i3, a};
         Object[] b = new Object[]{i2, c};
         a[1] = b;
-        assertEquals("1[2, [3, [1, [...]]]]", 
LoggerMessageHelper.format("{}{}", a));
+        assertEquals("1[2, [3, [1, [...]]]]", 
IgniteStringFormatter.format("{}{}", a));
 
     }
 }
diff --git 
a/modules/raft/src/main/java/org/apache/ignite/internal/raft/Loza.java 
b/modules/raft/src/main/java/org/apache/ignite/internal/raft/Loza.java
index c73790d..48bb9e4 100644
--- a/modules/raft/src/main/java/org/apache/ignite/internal/raft/Loza.java
+++ b/modules/raft/src/main/java/org/apache/ignite/internal/raft/Loza.java
@@ -35,7 +35,7 @@ import org.apache.ignite.internal.thread.NamedThreadFactory;
 import org.apache.ignite.internal.util.IgniteSpinBusyLock;
 import org.apache.ignite.internal.util.IgniteUtils;
 import org.apache.ignite.lang.IgniteInternalException;
-import org.apache.ignite.lang.LoggerMessageHelper;
+import org.apache.ignite.lang.IgniteStringFormatter;
 import org.apache.ignite.lang.NodeStoppingException;
 import org.apache.ignite.network.ClusterNode;
 import org.apache.ignite.network.ClusterService;
@@ -193,7 +193,7 @@ public class Loza implements IgniteComponent {
 
         if (hasLocalRaft) {
             if (!raftServer.startRaftGroup(groupId, lsnrSupplier.get(), 
peers)) {
-                throw new IgniteInternalException(LoggerMessageHelper.format(
+                throw new IgniteInternalException(IgniteStringFormatter.format(
                         "Raft group on the node is already started [node={}, 
raftGrp={}]",
                         locNodeName,
                         groupId
@@ -262,7 +262,7 @@ public class Loza implements IgniteComponent {
 
         if (deltaNodes.stream().anyMatch(n -> locNodeName.equals(n.name()))) {
             if (!raftServer.startRaftGroup(groupId, lsnrSupplier.get(), 
peers)) {
-                throw new IgniteInternalException(LoggerMessageHelper.format(
+                throw new IgniteInternalException(IgniteStringFormatter.format(
                         "Raft group on the node is already started [node={}, 
raftGrp={}]",
                         locNodeName,
                         groupId
diff --git 
a/modules/raft/src/main/java/org/apache/ignite/internal/raft/server/impl/JraftServerImpl.java
 
b/modules/raft/src/main/java/org/apache/ignite/internal/raft/server/impl/JraftServerImpl.java
index 30f2c01..d3a0131 100644
--- 
a/modules/raft/src/main/java/org/apache/ignite/internal/raft/server/impl/JraftServerImpl.java
+++ 
b/modules/raft/src/main/java/org/apache/ignite/internal/raft/server/impl/JraftServerImpl.java
@@ -34,7 +34,7 @@ import java.util.stream.Collectors;
 import org.apache.ignite.internal.raft.server.RaftServer;
 import org.apache.ignite.internal.thread.NamedThreadFactory;
 import org.apache.ignite.lang.IgniteInternalException;
-import org.apache.ignite.lang.LoggerMessageHelper;
+import org.apache.ignite.lang.IgniteStringFormatter;
 import org.apache.ignite.network.ClusterNode;
 import org.apache.ignite.network.ClusterService;
 import org.apache.ignite.network.NetworkAddress;
@@ -210,7 +210,7 @@ public class JraftServerImpl implements RaftServer {
     /** {@inheritDoc} */
     @Override
     public void stop() {
-        assert groups.isEmpty() : LoggerMessageHelper.format("Raft groups are 
still running {}", groups.keySet());
+        assert groups.isEmpty() : IgniteStringFormatter.format("Raft groups 
are still running {}", groups.keySet());
 
         rpcServer.shutdown();
 
diff --git 
a/modules/raft/src/main/java/org/apache/ignite/raft/jraft/disruptor/StripedDisruptor.java
 
b/modules/raft/src/main/java/org/apache/ignite/raft/jraft/disruptor/StripedDisruptor.java
index 2a95fea..ee67d0f 100644
--- 
a/modules/raft/src/main/java/org/apache/ignite/raft/jraft/disruptor/StripedDisruptor.java
+++ 
b/modules/raft/src/main/java/org/apache/ignite/raft/jraft/disruptor/StripedDisruptor.java
@@ -16,9 +16,8 @@
  */
 package org.apache.ignite.raft.jraft.disruptor;
 
-import java.util.ArrayList;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.function.BiConsumer;
+import static org.apache.ignite.lang.IgniteStringFormatter.format;
+
 import com.lmax.disruptor.BlockingWaitStrategy;
 import com.lmax.disruptor.EventFactory;
 import com.lmax.disruptor.EventHandler;
@@ -26,11 +25,12 @@ import com.lmax.disruptor.ExceptionHandler;
 import com.lmax.disruptor.RingBuffer;
 import com.lmax.disruptor.dsl.Disruptor;
 import com.lmax.disruptor.dsl.ProducerType;
+import java.util.ArrayList;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.function.BiConsumer;
 import org.apache.ignite.internal.thread.NamedThreadFactory;
 import org.apache.ignite.lang.IgniteLogger;
 
-import static org.apache.ignite.lang.LoggerMessageHelper.format;
-
 /**
  * Stripe Disruptor is a set of queues which process several independent 
groups in one queue (in the stripe).
  * It makes fewer threads that the groups and gives the same sequential 
guaranties and a close performance.
diff --git 
a/modules/raft/src/test/java/org/apache/ignite/disruptor/StripedDisruptorTest.java
 
b/modules/raft/src/test/java/org/apache/ignite/disruptor/StripedDisruptorTest.java
index 8cdd51e..496621b 100644
--- 
a/modules/raft/src/test/java/org/apache/ignite/disruptor/StripedDisruptorTest.java
+++ 
b/modules/raft/src/test/java/org/apache/ignite/disruptor/StripedDisruptorTest.java
@@ -25,7 +25,7 @@ import com.lmax.disruptor.RingBuffer;
 import java.util.ArrayList;
 import org.apache.ignite.internal.testframework.IgniteAbstractTest;
 import org.apache.ignite.internal.testframework.IgniteTestUtils;
-import org.apache.ignite.lang.LoggerMessageHelper;
+import org.apache.ignite.lang.IgniteStringFormatter;
 import org.apache.ignite.raft.jraft.disruptor.GroupAware;
 import org.apache.ignite.raft.jraft.disruptor.StripedDisruptor;
 import org.junit.jupiter.api.Test;
@@ -70,10 +70,10 @@ public class StripedDisruptorTest extends 
IgniteAbstractTest {
 
             if (i % 10 == 0) {
                 assertTrue(IgniteTestUtils.waitForCondition(() -> 
handler1.applied == finalInt + 1, 10_000),
-                        LoggerMessageHelper.format("Batch was not commited 
[applied={}, expected={}, buffered={}]",
+                        IgniteStringFormatter.format("Batch was not commited 
[applied={}, expected={}, buffered={}]",
                                 handler1.applied, finalInt + 1, 
handler1.batch));
                 assertTrue(IgniteTestUtils.waitForCondition(() -> 
handler2.applied == finalInt + 1, 10_000),
-                        LoggerMessageHelper.format("Batch was not commited 
[applied={}, expected={}, buffered={}]",
+                        IgniteStringFormatter.format("Batch was not commited 
[applied={}, expected={}, buffered={}]",
                                 handler2.applied, finalInt + 1, 
handler2.batch));
             }
         }
diff --git 
a/modules/raft/src/test/java/org/apache/ignite/internal/raft/server/impl/RaftServerImpl.java
 
b/modules/raft/src/test/java/org/apache/ignite/internal/raft/server/impl/RaftServerImpl.java
index f06911a..6c2b314 100644
--- 
a/modules/raft/src/test/java/org/apache/ignite/internal/raft/server/impl/RaftServerImpl.java
+++ 
b/modules/raft/src/test/java/org/apache/ignite/internal/raft/server/impl/RaftServerImpl.java
@@ -29,7 +29,7 @@ import java.util.concurrent.ConcurrentMap;
 import java.util.function.BiConsumer;
 import org.apache.ignite.internal.raft.server.RaftServer;
 import org.apache.ignite.lang.IgniteLogger;
-import org.apache.ignite.lang.LoggerMessageHelper;
+import org.apache.ignite.lang.IgniteStringFormatter;
 import org.apache.ignite.lang.NodeStoppingException;
 import org.apache.ignite.network.ClusterService;
 import org.apache.ignite.network.NetworkAddress;
@@ -140,7 +140,7 @@ public class RaftServerImpl implements RaftServer {
     /** {@inheritDoc} */
     @Override
     public void stop() throws NodeStoppingException {
-        assert listeners.isEmpty() : LoggerMessageHelper.format("Raft groups 
are still running {}", listeners.keySet());
+        assert listeners.isEmpty() : IgniteStringFormatter.format("Raft groups 
are still running {}", listeners.keySet());
 
         if (readWorker != null) {
             readWorker.interrupt();
diff --git 
a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/calcite/AbstractBasicIntegrationTest.java
 
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/calcite/AbstractBasicIntegrationTest.java
index 92cf327..4675fd0 100644
--- 
a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/calcite/AbstractBasicIntegrationTest.java
+++ 
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/calcite/AbstractBasicIntegrationTest.java
@@ -22,9 +22,7 @@ import static 
org.apache.ignite.internal.calcite.util.Commons.getAllFromCursor;
 import java.nio.file.Path;
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.LinkedHashMap;
 import java.util.List;
-import java.util.Map;
 import org.apache.ignite.Ignite;
 import org.apache.ignite.IgnitionManager;
 import org.apache.ignite.internal.ItUtils;
@@ -32,10 +30,13 @@ import org.apache.ignite.internal.app.IgniteImpl;
 import org.apache.ignite.internal.calcite.util.QueryChecker;
 import org.apache.ignite.internal.processors.query.calcite.QueryProcessor;
 import 
org.apache.ignite.internal.schema.configuration.SchemaConfigurationConverter;
+import org.apache.ignite.internal.testframework.BaseIgniteAbstractTest;
+import org.apache.ignite.internal.testframework.IgniteTestUtils;
 import org.apache.ignite.internal.testframework.WorkDirectory;
 import org.apache.ignite.internal.testframework.WorkDirectoryExtension;
 import org.apache.ignite.internal.util.IgniteUtils;
 import org.apache.ignite.lang.IgniteLogger;
+import org.apache.ignite.lang.IgniteStringFormatter;
 import org.apache.ignite.schema.SchemaBuilders;
 import org.apache.ignite.schema.definition.ColumnType;
 import org.apache.ignite.schema.definition.TableDefinition;
@@ -44,7 +45,10 @@ import org.apache.ignite.table.RecordView;
 import org.apache.ignite.table.Table;
 import org.apache.ignite.table.Tuple;
 import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.TestInfo;
 import org.junit.jupiter.api.TestInstance;
 import org.junit.jupiter.api.extension.ExtendWith;
 
@@ -53,49 +57,24 @@ import org.junit.jupiter.api.extension.ExtendWith;
  */
 @ExtendWith(WorkDirectoryExtension.class)
 @TestInstance(TestInstance.Lifecycle.PER_CLASS)
-public class AbstractBasicIntegrationTest {
+public class AbstractBasicIntegrationTest extends BaseIgniteAbstractTest {
     private static final IgniteLogger LOG = 
IgniteLogger.forClass(AbstractBasicIntegrationTest.class);
 
-    /** Nodes bootstrap configuration. */
-    private static final Map<String, String> NODES_BOOTSTRAP_CFG = new 
LinkedHashMap<>() {
-        {
-            put("node0", "{\n"
-                    + "  \"node\": {\n"
-                    + "    \"metastorageNodes\":[ \"node0\" ]\n"
-                    + "  },\n"
-                    + "  \"network\": {\n"
-                    + "    \"port\":3344,\n"
-                    + "    \"nodeFinder\": {\n"
-                    + "      \"netClusterNodes\": [ \"localhost:3344\", 
\"localhost:3345\", \"localhost:3346\" ]\n"
-                    + "    }\n"
-                    + "  }\n"
-                    + "}");
-
-            put("node1", "{\n"
-                    + "  \"node\": {\n"
-                    + "    \"metastorageNodes\":[ \"node0\" ]\n"
-                    + "  },\n"
-                    + "  \"network\": {\n"
-                    + "    \"port\":3345,\n"
-                    + "    \"nodeFinder\":{\n"
-                    + "      \"netClusterNodes\": [ \"localhost:3344\", 
\"localhost:3345\", \"localhost:3346\" ]\n"
-                    + "    }\n"
-                    + "  }\n"
-                    + "}");
-
-            put("node2", "{\n"
-                    + "  \"node\": {\n"
-                    + "    \"metastorageNodes\":[ \"node0\" ]\n"
-                    + "  },\n"
-                    + "  \"network\": {\n"
-                    + "    \"port\":3346,\n"
-                    + "    \"nodeFinder\":{\n"
-                    + "      \"netClusterNodes\": [ \"localhost:3344\", 
\"localhost:3345\", \"localhost:3346\" ]\n"
-                    + "    }\n"
-                    + "  }\n"
-                    + "}");
-        }
-    };
+    /** Base port number. */
+    private static final int BASE_PORT = 3344;
+
+    /** Nodes bootstrap configuration pattern. */
+    private static final String NODE_BOOTSTRAP_CFG = "{\n"
+            + "  \"node\": {\n"
+            + "    \"metastorageNodes\":[ {} ]\n"
+            + "  },\n"
+            + "  \"network\": {\n"
+            + "    \"port\":{},\n"
+            + "    \"nodeFinder\":{\n"
+            + "      \"netClusterNodes\": [ {} ]\n"
+            + "    }\n"
+            + "  }\n"
+            + "}";
 
     /** Cluster nodes. */
     protected static final List<Ignite> CLUSTER_NODES = new ArrayList<>();
@@ -106,19 +85,41 @@ public class AbstractBasicIntegrationTest {
 
     /**
      * Before all.
+     *
+     * @param testInfo Test information oject.
      */
     @BeforeAll
-    static void startNodes() {
-        NODES_BOOTSTRAP_CFG.forEach((nodeName, configStr) ->
-                CLUSTER_NODES.add(IgnitionManager.start(nodeName, configStr, 
WORK_DIR.resolve(nodeName)))
-        );
+    void startNodes(TestInfo testInfo) {
+        //TODO: IGNITE-16034 Here we assume that Metastore consists into one 
node, and it starts at first.
+        String metastorageNodes = '\"' + 
IgniteTestUtils.testNodeName(testInfo, 0) + '\"';
+
+        String connectNodeAddr = "\"localhost:" + BASE_PORT + '\"';
+
+        for (int i = 0; i < nodes(); i++) {
+            String curNodeName = IgniteTestUtils.testNodeName(testInfo, i);
+
+            CLUSTER_NODES.add(IgnitionManager.start(curNodeName, 
IgniteStringFormatter.format(NODE_BOOTSTRAP_CFG,
+                    metastorageNodes,
+                    BASE_PORT + i,
+                    connectNodeAddr
+            ), WORK_DIR.resolve(curNodeName)));
+        }
+    }
+
+    /**
+     * Get a count of nodes in the Ignite cluster.
+     *
+     * @return Count of nodes.
+     */
+    protected int nodes() {
+        return 3;
     }
 
     /**
      * After all.
      */
     @AfterAll
-    static void stopNodes() throws Exception {
+    void stopNodes() throws Exception {
         LOG.info("Start tearDown()");
 
         IgniteUtils.closeAll(ItUtils.reverse(CLUSTER_NODES));
@@ -128,6 +129,28 @@ public class AbstractBasicIntegrationTest {
         LOG.info("End tearDown()");
     }
 
+    /**
+     * Invokes before the test will start.
+     *
+     * @param testInfo Test information oject.
+     * @throws Exception If failed.
+     */
+    @BeforeEach
+    public void setup(TestInfo testInfo) throws Exception {
+        setupBase(testInfo, WORK_DIR);
+    }
+
+    /**
+     * Invokes after the test has finished.
+     *
+     * @param testInfo Test information oject.
+     * @throws Exception If failed.
+     */
+    @AfterEach
+    public void tearDown(TestInfo testInfo) throws Exception {
+        tearDownBase(testInfo);
+    }
+
     protected static QueryChecker assertQuery(String qry) {
         return new QueryChecker(qry) {
             @Override
diff --git 
a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/calcite/ItFunctionsTest.java
 
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/calcite/ItFunctionsTest.java
index ff8ba2f..ad92262 100644
--- 
a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/calcite/ItFunctionsTest.java
+++ 
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/calcite/ItFunctionsTest.java
@@ -28,7 +28,7 @@ import java.util.List;
 import java.util.function.LongFunction;
 import 
org.apache.ignite.internal.schema.configuration.SchemaConfigurationConverter;
 import org.apache.ignite.lang.IgniteException;
-import org.apache.ignite.lang.LoggerMessageHelper;
+import org.apache.ignite.lang.IgniteStringFormatter;
 import org.apache.ignite.schema.SchemaBuilders;
 import org.apache.ignite.schema.definition.ColumnType;
 import org.apache.ignite.schema.definition.TableDefinition;
@@ -123,7 +123,7 @@ public class ItFunctionsTest extends 
AbstractBasicIntegrationTest {
 
         assertTrue(
                 ex.getCause() instanceof IllegalArgumentException,
-                LoggerMessageHelper.format(
+                IgniteStringFormatter.format(
                         "Expected cause is {}, but was {}",
                         IllegalArgumentException.class.getSimpleName(),
                         ex.getCause() == null ? null : 
ex.getCause().getClass().getSimpleName()
diff --git 
a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/ItIgniteNodeRestartTest.java
 
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/ItIgniteNodeRestartTest.java
index 9d9ffe4..085cdf9 100644
--- 
a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/ItIgniteNodeRestartTest.java
+++ 
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/ItIgniteNodeRestartTest.java
@@ -173,7 +173,7 @@ public class ItIgniteNodeRestartTest extends 
IgniteAbstractTest {
                         .build()
         ).build();
 
-        Table table = ignite.tables().createTableIfNotExists(
+        Table table = ignite.tables().createTable(
                 scmTbl1.canonicalName(), tbl -> 
SchemaConfigurationConverter.convert(scmTbl1, tbl).changePartitions(10));
 
         for (int i = 0; i < 100; i++) {
diff --git 
a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/ItTableApiContractTest.java
 
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/ItTableApiContractTest.java
new file mode 100644
index 0000000..6402124
--- /dev/null
+++ 
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/ItTableApiContractTest.java
@@ -0,0 +1,279 @@
+/*
+ * 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.internal.runner.app;
+
+import static 
org.apache.ignite.internal.schema.configuration.SchemaConfigurationConverter.convert;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+import org.apache.ignite.Ignite;
+import org.apache.ignite.internal.calcite.AbstractBasicIntegrationTest;
+import org.apache.ignite.lang.TableAlreadyExistsException;
+import org.apache.ignite.lang.TableNotFoundException;
+import org.apache.ignite.schema.SchemaBuilders;
+import org.apache.ignite.schema.definition.ColumnType;
+import org.apache.ignite.table.Table;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInfo;
+
+/**
+ * There are tests which check a table managment contract.
+ * <ul>
+ * <li>When a table is already created other tries to create the table have to 
fail {@link TableAlreadyExistsException}.</li>
+ * <li>When a table is not existed, tries to alter or drop the table have to 
failed {@link TableNotFoundException}.</li>
+ * </ul>
+ */
+public class ItTableApiContractTest extends AbstractBasicIntegrationTest {
+    /** Schema name. */
+    public static final String SCHEMA = "PUBLIC";
+
+    /** Short table name. */
+    public static final String SHORT_TABLE_NAME = "tbl1";
+
+    /** Table name. */
+    public static final String TABLE_NAME = SCHEMA + "." + SHORT_TABLE_NAME;
+
+    /** Cluster nodes. */
+    private static Ignite ignite;
+
+    /** {@inheritDoc} */
+    @Override
+    public int nodes() {
+        return 1;
+    }
+
+    /**
+     * Before all tests.
+     */
+    @BeforeAll
+    static void beforeAll(TestInfo testInfo) throws Exception {
+        ignite = CLUSTER_NODES.get(0);
+    }
+
+    /**
+     * Executes after each test.
+     */
+    @AfterEach
+    void afterTest() {
+        if (ignite.tables().table(TABLE_NAME) != null) {
+            ignite.tables().dropTable(TABLE_NAME);
+        }
+    }
+
+    /**
+     * Checks a contract for dropping table.
+     *
+     * @throws Exception If failed.
+     */
+    @Test
+    public void testDropTable() throws Exception {
+        ignite.tables().createTable(TABLE_NAME, tableChange -> 
convert(SchemaBuilders.tableBuilder(SCHEMA, SHORT_TABLE_NAME)
+                .columns(
+                        SchemaBuilders.column("key", ColumnType.INT64).build(),
+                        SchemaBuilders.column("val", 
ColumnType.string()).build())
+                .withPrimaryKey("key")
+                .build(), tableChange)
+                .changeReplicas(2)
+                .changePartitions(10));
+
+        ignite.tables().dropTable(TABLE_NAME);
+
+        assertNull(ignite.tables().table(TABLE_NAME));
+
+        assertThrows(TableNotFoundException.class, () -> 
ignite.tables().dropTable(TABLE_NAME));
+    }
+
+    /**
+     * Checks a contract for asynchronous dropping table.
+     *
+     * @throws Exception If fialed.
+     */
+    @Test
+    public void testDropTableAsync() throws Exception {
+        ignite.tables().createTable(TABLE_NAME, tableChange -> 
convert(SchemaBuilders.tableBuilder(SCHEMA, SHORT_TABLE_NAME)
+                .columns(
+                        SchemaBuilders.column("key", ColumnType.INT64).build(),
+                        SchemaBuilders.column("val", 
ColumnType.string()).build())
+                .withPrimaryKey("key")
+                .build(), tableChange)
+                .changeReplicas(2)
+                .changePartitions(10));
+
+        CompletableFuture<Void> dropTblFut1 =  
ignite.tables().dropTableAsync(TABLE_NAME);
+
+        CompletableFuture<Void> dropTblFut2 = 
ignite.tables().dropTableAsync(TABLE_NAME);
+
+        assertNull(ignite.tables().table(TABLE_NAME));
+
+        dropTblFut1.get();
+
+        assertThrows(TableNotFoundException.class, () -> 
futureResult(dropTblFut2));
+    }
+
+    /**
+     * Checks a contract for altering table.
+     *
+     * @throws Exception If failed.
+     */
+    @Test
+    public void testAlterTable() throws Exception {
+        ignite.tables().createTable(TABLE_NAME, tableChange -> 
convert(SchemaBuilders.tableBuilder(SCHEMA, SHORT_TABLE_NAME)
+                .columns(
+                        SchemaBuilders.column("key", ColumnType.INT64).build(),
+                        SchemaBuilders.column("val", 
ColumnType.string()).build())
+                .withPrimaryKey("key")
+                .build(), tableChange)
+                .changeReplicas(2)
+                .changePartitions(10));
+
+        ignite.tables().alterTable(TABLE_NAME,
+                chng -> chng.changeColumns(cols -> {
+                    cols.create("name", colChg -> 
convert(SchemaBuilders.column("name", ColumnType.string()).asNullable(true)
+                            .withDefaultValueExpression("default").build(), 
colChg));
+                }));
+
+        assertNotNull(ignite.tables().table(TABLE_NAME));
+
+        assertNull(ignite.tables().table(TABLE_NAME + "_not_exist"));
+
+        assertThrows(TableNotFoundException.class, () -> 
ignite.tables().alterTable(TABLE_NAME + "_not_exist",
+                chng -> chng.changeColumns(cols -> {
+                    cols.create("name", colChg -> 
convert(SchemaBuilders.column("name", ColumnType.string()).asNullable(true)
+                            .withDefaultValueExpression("default").build(), 
colChg));
+                })));
+    }
+
+    /**
+     * Checks a contract for asynchronous altering table.
+     *
+     * @throws Exception If fialed.
+     */
+    @Test
+    public void testAlterTableAsync() throws Exception {
+        ignite.tables().createTable(TABLE_NAME, tableChange -> 
convert(SchemaBuilders.tableBuilder(SCHEMA, SHORT_TABLE_NAME)
+                .columns(
+                        SchemaBuilders.column("key", ColumnType.INT64).build(),
+                        SchemaBuilders.column("val", 
ColumnType.string()).build())
+                .withPrimaryKey("key")
+                .build(), tableChange)
+                .changeReplicas(2)
+                .changePartitions(10));
+
+        CompletableFuture<Void> altTblFut1 = 
ignite.tables().alterTableAsync(TABLE_NAME,
+                chng -> chng.changeColumns(cols -> {
+                    cols.create("name", colChg -> 
convert(SchemaBuilders.column("name", ColumnType.string()).asNullable(true)
+                            .withDefaultValueExpression("default").build(), 
colChg));
+                }));
+
+        CompletableFuture<Void> altTblFut2 = 
ignite.tables().alterTableAsync(TABLE_NAME + "_not_exist",
+                chng -> chng.changeColumns(cols -> {
+                    cols.create("name", colChg -> 
convert(SchemaBuilders.column("name", ColumnType.string()).asNullable(true)
+                            .withDefaultValueExpression("default").build(), 
colChg));
+                }));
+
+        assertNotNull(ignite.tables().table(TABLE_NAME));
+
+        assertNull(ignite.tables().table(TABLE_NAME + "_not_exist"));
+
+        altTblFut1.get();
+
+        assertThrows(TableNotFoundException.class, () -> 
futureResult(altTblFut2));
+    }
+
+    /**
+     * Checks a contract for table creation.
+     *
+     * @throws Exception If failed.
+     */
+    @Test
+    public void testCreateTable() throws Exception {
+        Table table = ignite.tables().createTable(TABLE_NAME, tableChange -> 
convert(SchemaBuilders.tableBuilder(SCHEMA, SHORT_TABLE_NAME)
+                .columns(
+                        SchemaBuilders.column("key", ColumnType.INT64).build(),
+                        SchemaBuilders.column("val", 
ColumnType.string()).build())
+                .withPrimaryKey("key")
+                .build(), tableChange)
+                .changeReplicas(2)
+                .changePartitions(10));
+
+        assertNotNull(table);
+
+        assertThrows(TableAlreadyExistsException.class,
+                () -> ignite.tables().createTable(TABLE_NAME, tableChange -> 
convert(SchemaBuilders.tableBuilder(SCHEMA, SHORT_TABLE_NAME)
+                        .columns(
+                                SchemaBuilders.column("new_key", 
ColumnType.INT64).build(),
+                                SchemaBuilders.column("new_val", 
ColumnType.string()).build())
+                        .withPrimaryKey("new_key")
+                        .build(), tableChange)
+                        .changeReplicas(2)
+                        .changePartitions(10)));
+    }
+
+    /**
+     * Checks a contract for asynchronous table creation.
+     *
+     * @throws Exception If failed.
+     */
+    @Test
+    public void testCreateTableAsync() throws Exception {
+        CompletableFuture<Table> tableFut1 = ignite.tables()
+                .createTableAsync(TABLE_NAME, tableChange -> 
convert(SchemaBuilders.tableBuilder(SCHEMA, SHORT_TABLE_NAME)
+                        .columns(
+                                SchemaBuilders.column("key", 
ColumnType.INT64).build(),
+                                SchemaBuilders.column("val", 
ColumnType.string()).build())
+                        .withPrimaryKey("key")
+                        .build(), tableChange)
+                        .changeReplicas(2)
+                        .changePartitions(10));
+
+        CompletableFuture<Table> tableFut2 = ignite.tables()
+                .createTableAsync(TABLE_NAME, tableChange -> 
convert(SchemaBuilders.tableBuilder(SCHEMA, SHORT_TABLE_NAME)
+                        .columns(
+                                SchemaBuilders.column("new_key", 
ColumnType.INT64).build(),
+                                SchemaBuilders.column("new_val", 
ColumnType.string()).build())
+                        .withPrimaryKey("new_key")
+                        .build(), tableChange)
+                        .changeReplicas(2)
+                        .changePartitions(10));
+
+        assertNotNull(tableFut1.get());
+
+        assertThrows(TableAlreadyExistsException.class, () -> 
futureResult(tableFut2));
+    }
+
+    /**
+     * Gets future result and unwrap exception if it was thrown.
+     *
+     * @param fut Some future.
+     * @param <T> Expected future result parameter.
+     * @return Future result.
+     * @throws Throwable If future completed with an exception.
+     */
+    private <T> T futureResult(CompletableFuture<T> fut) throws Throwable {
+        try {
+            return fut.get();
+        } catch (ExecutionException e) {
+            throw e.getCause();
+        }
+    }
+}
diff --git 
a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/ItTablesApiTest.java
 
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/ItTablesApiTest.java
index ea0a517..96260ff 100644
--- 
a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/ItTablesApiTest.java
+++ 
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/ItTablesApiTest.java
@@ -48,6 +48,7 @@ import org.apache.ignite.lang.IgniteUuid;
 import org.apache.ignite.lang.IndexAlreadyExistsException;
 import org.apache.ignite.lang.NodeStoppingException;
 import org.apache.ignite.lang.TableAlreadyExistsException;
+import org.apache.ignite.lang.TableNotFoundException;
 import org.apache.ignite.schema.SchemaBuilders;
 import org.apache.ignite.schema.definition.ColumnDefinition;
 import org.apache.ignite.schema.definition.ColumnType;
@@ -347,8 +348,9 @@ public class ItTablesApiTest extends IgniteAbstractTest {
     }
 
     /**
-     * Checks that if a table would be created/dropped into any cluster node, 
this is visible to all
-     * other nodes.
+     * Checks that if a table would be created/dropped in any cluster node, 
this action reflects on all others.
+     * Table management operations should pass in linearize order: if an 
action completed in one node,
+     * the result has to be visible to another one.
      *
      * @throws Exception If failed.
      */
@@ -406,6 +408,10 @@ public class ItTablesApiTest extends IgniteAbstractTest {
             assertNull(ignite.tables().table(TABLE_NAME));
 
             assertNull(((IgniteTablesInternal) ignite.tables()).table(tblId));
+
+            assertThrows(TableNotFoundException.class, () -> dropTable(ignite, 
SCHEMA, SHORT_TABLE_NAME));
+
+            dropTableIfExists(ignite, SCHEMA, SHORT_TABLE_NAME);
         }
 
         ignite1Inhibitor.stopInhibit();
@@ -427,7 +433,7 @@ public class ItTablesApiTest extends IgniteAbstractTest {
         return node.tables().createTable(
                 schemaName + "." + shortTableName,
                 tblCh -> convert(SchemaBuilders.tableBuilder(schemaName, 
shortTableName).columns(
-                    cols).withPrimaryKey("key").build(), 
tblCh).changeReplicas(2).changePartitions(10)
+                        cols).withPrimaryKey("key").build(), 
tblCh).changeReplicas(2).changePartitions(10)
         );
     }
 
@@ -439,16 +445,48 @@ public class ItTablesApiTest extends IgniteAbstractTest {
      * @param shortTableName Table name.
      */
     protected Table createTableIfNotExists(Ignite node, String schemaName, 
String shortTableName) {
-        return node.tables().createTableIfNotExists(
-                schemaName + "." + shortTableName,
-                tblCh -> convert(SchemaBuilders.tableBuilder(schemaName, 
shortTableName).columns(Arrays.asList(
-                        SchemaBuilders.column("key", ColumnType.INT64).build(),
-                        SchemaBuilders.column("valInt", 
ColumnType.INT32).asNullable(true).build(),
-                        SchemaBuilders.column("valStr", ColumnType.string())
-                                .withDefaultValueExpression("default").build()
-                        )).withPrimaryKey("key").build(),
-                        tblCh).changeReplicas(2).changePartitions(10)
-        );
+        try {
+            return node.tables().createTable(
+                    schemaName + "." + shortTableName,
+                    tblCh -> convert(SchemaBuilders.tableBuilder(schemaName, 
shortTableName).columns(Arrays.asList(
+                            SchemaBuilders.column("key", 
ColumnType.INT64).build(),
+                            SchemaBuilders.column("valInt", 
ColumnType.INT32).asNullable(true).build(),
+                            SchemaBuilders.column("valStr", 
ColumnType.string())
+                                    
.withDefaultValueExpression("default").build()
+                            )).withPrimaryKey("key").build(),
+                            tblCh).changeReplicas(2).changePartitions(10)
+            );
+        } catch (TableAlreadyExistsException ex) {
+            return node.tables().table(schemaName + "." + shortTableName);
+        }
+    }
+
+    /**
+     * Drops the table which name is specified.
+     * If the table does not exist, an exception will be thrown.
+     *
+     * @param node Cluster node.
+     * @param schemaName Schema name.
+     * @param shortTableName Table name.
+     */
+    protected void dropTable(Ignite node, String schemaName, String 
shortTableName) {
+        node.tables().dropTable(schemaName + "." + shortTableName);
+    }
+
+    /**
+     * Drops the table which name is specified.
+     * If the table did not exist, a dropping would ignore.
+     *
+     * @param node Cluster node.
+     * @param schemaName Schema name.
+     * @param shortTableName Table name.
+     */
+    protected void dropTableIfExists(Ignite node, String schemaName, String 
shortTableName) {
+        try {
+            node.tables().dropTable(schemaName + "." + shortTableName);
+        } catch (TableNotFoundException ex) {
+            log.info("Dropping the table ignored.", ex);
+        }
     }
 
     /**
@@ -468,10 +506,10 @@ public class ItTablesApiTest extends IgniteAbstractTest {
     /**
      * Adds a column according to the column definition.
      *
-     * @param node Ignite node.
-     * @param schemaName Schema name.
+     * @param node           Ignite node.
+     * @param schemaName     Schema name.
      * @param shortTableName Table name.
-     * @param colDefinition Column defenition.
+     * @param colDefinition  Column defenition.
      */
     private void addColumnInternal(Ignite node, String schemaName, String 
shortTableName, ColumnDefinition colDefinition) {
         node.tables().alterTable(
@@ -488,8 +526,8 @@ public class ItTablesApiTest extends IgniteAbstractTest {
     /**
      * Adds a column if it does not exist.
      *
-     * @param node Ignite node.
-     * @param schemaName Schema name.
+     * @param node           Ignite node.
+     * @param schemaName     Schema name.
      * @param shortTableName Table name.
      */
     protected void addColumnIfNotExists(Ignite node, String schemaName, String 
shortTableName) {
diff --git 
a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/ItThinClientConnectionTest.java
 
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/ItThinClientConnectionTest.java
index 95c8fdf..ef3ab59 100644
--- 
a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/ItThinClientConnectionTest.java
+++ 
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/ItThinClientConnectionTest.java
@@ -159,7 +159,7 @@ public class ItThinClientConnectionTest extends 
IgniteAbstractTest {
 
     private static class TestPojo {
         public TestPojo() {
-            // No-op.
+            //No-op.
         }
 
         public TestPojo(int key) {
diff --git 
a/modules/runner/src/main/java/org/apache/ignite/internal/app/IgnitionImpl.java 
b/modules/runner/src/main/java/org/apache/ignite/internal/app/IgnitionImpl.java
index 0d3a81b..5241df7 100644
--- 
a/modules/runner/src/main/java/org/apache/ignite/internal/app/IgnitionImpl.java
+++ 
b/modules/runner/src/main/java/org/apache/ignite/internal/app/IgnitionImpl.java
@@ -29,7 +29,7 @@ import org.apache.ignite.Ignite;
 import org.apache.ignite.Ignition;
 import org.apache.ignite.lang.IgniteException;
 import org.apache.ignite.lang.IgniteLogger;
-import org.apache.ignite.lang.LoggerMessageHelper;
+import org.apache.ignite.lang.IgniteStringFormatter;
 import org.apache.ignite.utils.IgniteProperties;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
@@ -189,6 +189,6 @@ public class IgnitionImpl implements Ignition {
 
         String banner = String.join("\n", BANNER);
 
-        LOG.info(() -> LoggerMessageHelper.format("{}\n" + " ".repeat(22) + 
"Apache Ignite ver. {}\n", banner, ver), null);
+        LOG.info(() -> IgniteStringFormatter.format("{}\n" + " ".repeat(22) + 
"Apache Ignite ver. {}\n", banner, ver), null);
     }
 }
diff --git 
a/modules/schema/src/main/java/org/apache/ignite/internal/schema/SchemaUtils.java
 
b/modules/schema/src/main/java/org/apache/ignite/internal/schema/SchemaUtils.java
index 8602b40..bb52c3a 100644
--- 
a/modules/schema/src/main/java/org/apache/ignite/internal/schema/SchemaUtils.java
+++ 
b/modules/schema/src/main/java/org/apache/ignite/internal/schema/SchemaUtils.java
@@ -26,7 +26,7 @@ import 
org.apache.ignite.internal.schema.configuration.SchemaConfigurationConver
 import 
org.apache.ignite.internal.schema.configuration.SchemaDescriptorConverter;
 import org.apache.ignite.internal.schema.mapping.ColumnMapper;
 import org.apache.ignite.internal.schema.mapping.ColumnMapping;
-import org.apache.ignite.lang.LoggerMessageHelper;
+import org.apache.ignite.lang.IgniteStringFormatter;
 import org.apache.ignite.schema.definition.TableDefinition;
 
 /**
@@ -117,7 +117,7 @@ public class SchemaUtils {
         // TODO: IGNITE-15774 Assertion just in case, proper validation should 
be implemented with the help of
         // TODO: configuration validators.
         assert droppedKeyCol.isEmpty() :
-                LoggerMessageHelper.format(
+                IgniteStringFormatter.format(
                         "Dropping of key column is forbidden: [schemaVer={}, 
col={}]",
                         newDesc.version(),
                         droppedKeyCol.get()
diff --git 
a/modules/table/src/main/java/org/apache/ignite/internal/table/distributed/TableManager.java
 
b/modules/table/src/main/java/org/apache/ignite/internal/table/distributed/TableManager.java
index 3190345..b5bba99 100644
--- 
a/modules/table/src/main/java/org/apache/ignite/internal/table/distributed/TableManager.java
+++ 
b/modules/table/src/main/java/org/apache/ignite/internal/table/distributed/TableManager.java
@@ -84,11 +84,12 @@ import org.apache.ignite.internal.util.IgniteSpinBusyLock;
 import org.apache.ignite.lang.IgniteException;
 import org.apache.ignite.lang.IgniteInternalException;
 import org.apache.ignite.lang.IgniteLogger;
+import org.apache.ignite.lang.IgniteStringFormatter;
 import org.apache.ignite.lang.IgniteUuid;
 import org.apache.ignite.lang.IgniteUuidGenerator;
-import org.apache.ignite.lang.LoggerMessageHelper;
 import org.apache.ignite.lang.NodeStoppingException;
 import org.apache.ignite.lang.TableAlreadyExistsException;
+import org.apache.ignite.lang.TableNotFoundException;
 import org.apache.ignite.network.ClusterNode;
 import org.apache.ignite.network.NetworkAddress;
 import org.apache.ignite.network.TopologyService;
@@ -227,7 +228,7 @@ public class TableManager extends Producer<TableEvent, 
TableEventParameters> imp
                         // Empty assignments might be a valid case if tables 
are created from within cluster init HOCON
                         // configuration, which is not supported now.
                         assert ((ExtendedTableView) 
ctx.newValue()).assignments() != null :
-                                LoggerMessageHelper.format("Table [id={}, 
name={}] has empty assignments.", tblId, tblName);
+                                IgniteStringFormatter.format("Table [id={}, 
name={}] has empty assignments.", tblId, tblName);
 
                         // TODO: IGNITE-15409 Listener with any placeholder 
should be used instead.
                         ((ExtendedTableConfiguration) 
tablesCfg.tables().get(tblName)).schemas()
@@ -686,85 +687,87 @@ public class TableManager extends Producer<TableEvent, 
TableEventParameters> imp
             throw new IgniteException(new NodeStoppingException());
         }
         try {
-            return createTableAsync(name, tableInitChange, true);
+            return createTableAsyncInternal(name, tableInitChange);
         } finally {
             busyLock.leaveBusy();
         }
     }
 
     /**
-     * Creates a new table with the specified name or returns an existing 
table with the same name.
+     * Internal method that creates a new table with the given {@code name} 
asynchronously. If a table with the same name already exists,
+     * a future will be completed with {@link TableAlreadyExistsException}.
      *
-     * @param name Table name.
-     * @param tableInitChange Table configuration.
-     * @param exceptionWhenExist If the value is {@code true}, an exception 
will be thrown when the table already exists, {@code
-     *         false} means the existing table will be returned.
-     * @return A table instance.
+     * @param name            Table name.
+     * @param tableInitChange Table changer.
+     * @return Future representing pending completion of the operation.
+     * @throws IgniteException If an unspecified platform exception has 
happened internally. Is thrown when:
+     *                         <ul>
+     *                             <li>the node is stopping.</li>
+     *                         </ul>
+     * @see TableAlreadyExistsException
      */
-    private CompletableFuture<Table> createTableAsync(
-            String name,
-            Consumer<TableChange> tableInitChange,
-            boolean exceptionWhenExist
-    ) {
+    private CompletableFuture<Table> createTableAsyncInternal(String name, 
Consumer<TableChange> tableInitChange) {
         CompletableFuture<Table> tblFut = new CompletableFuture<>();
 
-        IgniteUuid tblId = TABLE_ID_GENERATOR.randomUuid();
+        tableAsync(name, true).thenAccept(tbl -> {
+            if (tbl != null) {
+                tblFut.completeExceptionally(new 
TableAlreadyExistsException(name));
+            } else {
+                IgniteUuid tblId = TABLE_ID_GENERATOR.randomUuid();
 
-        tablesCfg.tables().change(change -> {
-            if (change.get(name) != null) {
-                throw new TableAlreadyExistsException(name);
-            }
+                tablesCfg.tables().change(change -> {
+                    if (change.get(name) != null) {
+                        throw new TableAlreadyExistsException(name);
+                    }
 
-            change.create(name, (ch) -> {
-                        tableInitChange.accept(ch);
-
-                        ((ExtendedTableChange) ch)
-                                // Table id specification.
-                                .changeId(tblId.toString())
-                                // Affinity assignments calculation.
-                                
.changeAssignments(ByteUtils.toBytes(AffinityUtils.calculateAssignments(
-                                        baselineMgr.nodes(),
-                                        ch.partitions(),
-                                        ch.replicas())))
-                                // Table schema preparation.
-                                .changeSchemas(schemasCh -> schemasCh.create(
-                                        String.valueOf(INITIAL_SCHEMA_VERSION),
-                                        schemaCh -> {
-                                            SchemaDescriptor schemaDesc;
-
-                                            //TODO IGNITE-15747 Remove 
try-catch and force configuration
-                                            // validation here to ensure a 
valid configuration passed to
-                                            // prepareSchemaDescriptor() 
method.
-                                            try {
-                                                schemaDesc = 
SchemaUtils.prepareSchemaDescriptor(
-                                                        ((ExtendedTableView) 
ch).schemas().size(),
-                                                        ch);
-                                            } catch (IllegalArgumentException 
ex) {
-                                                throw new 
ConfigurationValidationException(ex.getMessage());
-                                            }
+                    change.create(name, (ch) -> {
+                                tableInitChange.accept(ch);
+
+                                ((ExtendedTableChange) ch)
+                                        // Table id specification.
+                                        .changeId(tblId.toString())
+                                        // Affinity assignments calculation.
+                                        
.changeAssignments(ByteUtils.toBytes(AffinityUtils.calculateAssignments(
+                                                baselineMgr.nodes(),
+                                                ch.partitions(),
+                                                ch.replicas())))
+                                        // Table schema preparation.
+                                        .changeSchemas(schemasCh -> 
schemasCh.create(
+                                                
String.valueOf(INITIAL_SCHEMA_VERSION),
+                                                schemaCh -> {
+                                                    SchemaDescriptor 
schemaDesc;
+
+                                                    //TODO IGNITE-15747 Remove 
try-catch and force configuration
+                                                    // validation here to 
ensure a valid configuration passed to
+                                                    // 
prepareSchemaDescriptor() method.
+                                                    try {
+                                                        schemaDesc = 
SchemaUtils.prepareSchemaDescriptor(
+                                                                
((ExtendedTableView) ch).schemas().size(),
+                                                                ch);
+                                                    } catch 
(IllegalArgumentException ex) {
+                                                        throw new 
ConfigurationValidationException(ex.getMessage());
+                                                    }
+
+                                                    
schemaCh.changeSchema(SchemaSerializerImpl.INSTANCE.serialize(schemaDesc));
+                                                }
+                                        ));
+                            }
+                    );
+                }).whenComplete((res, t) -> {
+                    if (t != null) {
+                        Throwable ex = getRootCause(t);
 
-                                            
schemaCh.changeSchema(SchemaSerializerImpl.INSTANCE.serialize(schemaDesc));
-                                        }
-                                ));
-                    }
-            );
-        }).whenComplete((res, t) -> {
-            if (t != null) {
-                Throwable ex = getRootCause(t);
+                        if (ex instanceof TableAlreadyExistsException) {
+                            tblFut.completeExceptionally(ex);
+                        } else {
+                            LOG.error(IgniteStringFormatter.format("Table 
wasn't created [name={}]", name), ex);
 
-                if (ex instanceof TableAlreadyExistsException) {
-                    if (exceptionWhenExist) {
-                        tblFut.completeExceptionally(ex);
+                            tblFut.completeExceptionally(ex);
+                        }
                     } else {
                         tblFut.complete(tables.get(name));
                     }
-                } else {
-                    LOG.error(LoggerMessageHelper.format("Table wasn't created 
[name={}]", name), ex);
-
-                    tblFut.completeExceptionally(ex);
-                }
-            } else {
-                tblFut.complete(tables.get(name));
+                });
             }
         });
 
@@ -773,25 +776,6 @@ public class TableManager extends Producer<TableEvent, 
TableEventParameters> imp
 
     /** {@inheritDoc} */
     @Override
-    public Table createTableIfNotExists(String name, Consumer<TableChange> 
tableInitChange) {
-        return join(createTableIfNotExistsAsync(name, tableInitChange));
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public CompletableFuture<Table> createTableIfNotExistsAsync(String name, 
Consumer<TableChange> tableInitChange) {
-        if (!busyLock.enterBusy()) {
-            throw new IgniteException(new NodeStoppingException());
-        }
-        try {
-            return createTableAsync(name, tableInitChange, false);
-        } finally {
-            busyLock.leaveBusy();
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override
     public void alterTable(String name, Consumer<TableChange> tableChange) {
         join(alterTableAsync(name, tableChange));
     }
@@ -810,11 +794,17 @@ public class TableManager extends Producer<TableEvent, 
TableEventParameters> imp
     }
 
     /**
-     * Internal method for creating table asynchronously.
+     * Internal method that alters a cluster table. If an appropriate table 
does not exist, a future will be
+     * completed with {@link TableNotFoundException}.
      *
-     * @param name Table name.
-     * @param tableChange Table cahnger.
+     * @param name        Table name.
+     * @param tableChange Table changer.
      * @return Future representing pending completion of the operation.
+     * @throws IgniteException If an unspecified platform exception has 
happened internally. Is thrown when:
+     *                         <ul>
+     *                             <li>the node is stopping.</li>
+     *                         </ul>
+     * @see TableNotFoundException
      */
     @NotNull
     private CompletableFuture<Void> alterTableAsyncInternal(String name, 
Consumer<TableChange> tableChange) {
@@ -822,54 +812,63 @@ public class TableManager extends Producer<TableEvent, 
TableEventParameters> imp
 
         tableAsync(name, true).thenAccept(tbl -> {
             if (tbl == null) {
-                tblFut.completeExceptionally(new IgniteException(
-                        LoggerMessageHelper.format("Table [name={}] does not 
exist and cannot be altered", name)));
+                tblFut.completeExceptionally(new TableNotFoundException(name));
             } else {
                 IgniteUuid tblId = ((TableImpl) tbl).tableId();
 
-                tablesCfg.tables().change(ch -> ch.createOrUpdate(name, tblCh 
-> {
-                            tableChange.accept(tblCh);
+                tablesCfg.tables().change(ch -> {
+                    if (ch.get(name) == null) {
+                        throw new TableNotFoundException(name);
+                    }
+
+                    ch.update(name, tblCh -> {
+                                tableChange.accept(tblCh);
 
-                            ((ExtendedTableChange) 
tblCh).changeSchemas(schemasCh ->
-                                    
schemasCh.createOrUpdate(String.valueOf(schemasCh.size() + 1), schemaCh -> {
-                                        ExtendedTableView currTableView = 
(ExtendedTableView) tablesCfg.tables().get(name).value();
+                                ((ExtendedTableChange) 
tblCh).changeSchemas(schemasCh ->
+                                        
schemasCh.createOrUpdate(String.valueOf(schemasCh.size() + 1), schemaCh -> {
+                                            ExtendedTableView currTableView = 
(ExtendedTableView) tablesCfg.tables().get(name).value();
 
-                                        SchemaDescriptor descriptor;
+                                            SchemaDescriptor descriptor;
 
-                                        //TODO IGNITE-15747 Remove try-catch 
and force configuration validation
-                                        // here to ensure a valid 
configuration passed to prepareSchemaDescriptor() method.
-                                        try {
-                                            descriptor = 
SchemaUtils.prepareSchemaDescriptor(
-                                                    ((ExtendedTableView) 
tblCh).schemas().size(),
-                                                    tblCh);
-
-                                            
descriptor.columnMapping(SchemaUtils.columnMapper(
-                                                    
tablesById.get(tblId).schemaView().schema(currTableView.schemas().size()),
-                                                    currTableView,
-                                                    descriptor,
-                                                    tblCh));
-                                        } catch (IllegalArgumentException ex) {
-                                            // Convert unexpected exceptions 
here,
-                                            // because validation actually 
happens later,
-                                            // when bulk configuration update 
is applied.
-                                            ConfigurationValidationException e 
=
-                                                    new 
ConfigurationValidationException(ex.getMessage());
-
-                                            e.addSuppressed(ex);
-
-                                            throw e;
-                                        }
+                                            //TODO IGNITE-15747 Remove 
try-catch and force configuration validation
+                                            // here to ensure a valid 
configuration passed to prepareSchemaDescriptor() method.
+                                            try {
+                                                descriptor = 
SchemaUtils.prepareSchemaDescriptor(
+                                                        ((ExtendedTableView) 
tblCh).schemas().size(),
+                                                        tblCh);
+
+                                                
descriptor.columnMapping(SchemaUtils.columnMapper(
+                                                        
tablesById.get(tblId).schemaView().schema(currTableView.schemas().size()),
+                                                        currTableView,
+                                                        descriptor,
+                                                        tblCh));
+                                            } catch (IllegalArgumentException 
ex) {
+                                                // Convert unexpected 
exceptions here,
+                                                // because validation actually 
happens later,
+                                                // when bulk configuration 
update is applied.
+                                                
ConfigurationValidationException e =
+                                                        new 
ConfigurationValidationException(ex.getMessage());
 
-                                        
schemaCh.changeSchema(SchemaSerializerImpl.INSTANCE.serialize(descriptor));
-                                    }));
-                        }
-                )).whenComplete((res, t) -> {
+                                                e.addSuppressed(ex);
+
+                                                throw e;
+                                            }
+
+                                            
schemaCh.changeSchema(SchemaSerializerImpl.INSTANCE.serialize(descriptor));
+                                        }));
+                            }
+                    );
+                }).whenComplete((res, t) -> {
                     if (t != null) {
                         Throwable ex = getRootCause(t);
 
-                        LOG.error(LoggerMessageHelper.format("Table wasn't 
altered [name={}]", name), ex);
+                        if (ex instanceof TableNotFoundException) {
+                            tblFut.completeExceptionally(ex);
+                        } else {
+                            LOG.error(IgniteStringFormatter.format("Table 
wasn't altered [name={}]", name), ex);
 
-                        tblFut.completeExceptionally(ex);
+                            tblFut.completeExceptionally(ex);
+                        }
                     } else {
                         tblFut.complete(res);
                     }
@@ -924,10 +923,16 @@ public class TableManager extends Producer<TableEvent, 
TableEventParameters> imp
     }
 
     /**
-     * Internal method for drop the table asynchronously.
+     * Internal method that drops a table with the name specified. If 
appropriate table does not be found, a future will be
+     * completed with {@link TableNotFoundException}.
      *
      * @param name Table name.
      * @return Future representing pending completion of the operation.
+     * @throws IgniteException If an unspecified platform exception has 
happened internally. Is thrown when:
+     *                         <ul>
+     *                             <li>the node is stopping.</li>
+     *                         </ul>
+     * @see TableNotFoundException
      */
     @NotNull
     private CompletableFuture<Void> dropTableAsyncInternal(String name) {
@@ -937,17 +942,27 @@ public class TableManager extends Producer<TableEvent, 
TableEventParameters> imp
             // In case of drop it's an optimization that allows not to fire 
drop-change-closure if there's no such
             // distributed table and the local config has lagged behind.
             if (tbl == null) {
-                dropTblFut.complete(null);
+                dropTblFut.completeExceptionally(new 
TableNotFoundException(name));
             } else {
                 tablesCfg.tables()
-                        .change(change -> change.delete(name))
+                        .change(change -> {
+                            if (change.get(name) == null) {
+                                throw new TableNotFoundException(name);
+                            }
+
+                            change.delete(name);
+                        })
                         .whenComplete((res, t) -> {
                             if (t != null) {
                                 Throwable ex = getRootCause(t);
 
-                                LOG.error(LoggerMessageHelper.format("Table 
wasn't dropped [name={}]", name), ex);
+                                if (ex instanceof TableNotFoundException) {
+                                    dropTblFut.completeExceptionally(ex);
+                                } else {
+                                    
LOG.error(IgniteStringFormatter.format("Table wasn't dropped [name={}]", name), 
ex);
 
-                                dropTblFut.completeExceptionally(ex);
+                                    dropTblFut.completeExceptionally(ex);
+                                }
                             } else {
                                 dropTblFut.complete(res);
                             }
diff --git 
a/modules/table/src/main/java/org/apache/ignite/internal/table/distributed/raft/PartitionListener.java
 
b/modules/table/src/main/java/org/apache/ignite/internal/table/distributed/raft/PartitionListener.java
index fbcf3b3..65919a6 100644
--- 
a/modules/table/src/main/java/org/apache/ignite/internal/table/distributed/raft/PartitionListener.java
+++ 
b/modules/table/src/main/java/org/apache/ignite/internal/table/distributed/raft/PartitionListener.java
@@ -17,7 +17,7 @@
 
 package org.apache.ignite.internal.table.distributed.raft;
 
-import static org.apache.ignite.lang.LoggerMessageHelper.format;
+import static org.apache.ignite.lang.IgniteStringFormatter.format;
 
 import java.nio.file.Path;
 import java.util.ArrayList;
diff --git 
a/modules/table/src/main/java/org/apache/ignite/internal/table/distributed/storage/InternalTableImpl.java
 
b/modules/table/src/main/java/org/apache/ignite/internal/table/distributed/storage/InternalTableImpl.java
index 399c61c..1021531 100644
--- 
a/modules/table/src/main/java/org/apache/ignite/internal/table/distributed/storage/InternalTableImpl.java
+++ 
b/modules/table/src/main/java/org/apache/ignite/internal/table/distributed/storage/InternalTableImpl.java
@@ -60,9 +60,9 @@ import 
org.apache.ignite.internal.table.distributed.command.scan.ScanRetrieveBat
 import org.apache.ignite.internal.tx.InternalTransaction;
 import org.apache.ignite.internal.tx.TxManager;
 import org.apache.ignite.lang.IgniteLogger;
+import org.apache.ignite.lang.IgniteStringFormatter;
 import org.apache.ignite.lang.IgniteUuid;
 import org.apache.ignite.lang.IgniteUuidGenerator;
-import org.apache.ignite.lang.LoggerMessageHelper;
 import org.apache.ignite.network.NetworkAddress;
 import org.apache.ignite.raft.client.Command;
 import org.apache.ignite.raft.client.Peer;
@@ -347,7 +347,7 @@ public class InternalTableImpl implements InternalTable {
     public @NotNull Publisher<BinaryRow> scan(int p, @Nullable 
InternalTransaction tx) {
         if (p < 0 || p >= partitions) {
             throw new IllegalArgumentException(
-                    LoggerMessageHelper.format(
+                    IgniteStringFormatter.format(
                             "Invalid partition [partition={}, minValue={}, 
maxValue={}].",
                             p,
                             0,
@@ -559,7 +559,7 @@ public class InternalTableImpl implements InternalTable {
                 if (n <= 0) {
                     cancel();
 
-                    subscriber.onError(new 
IllegalArgumentException(LoggerMessageHelper
+                    subscriber.onError(new 
IllegalArgumentException(IgniteStringFormatter
                             .format("Invalid requested amount of items 
[requested={}, minValue=1]", n))
                     );
                 }
diff --git 
a/modules/table/src/test/java/org/apache/ignite/internal/table/TableManagerTest.java
 
b/modules/table/src/test/java/org/apache/ignite/internal/table/TableManagerTest.java
index 0418ad4..095c25a 100644
--- 
a/modules/table/src/test/java/org/apache/ignite/internal/table/TableManagerTest.java
+++ 
b/modules/table/src/test/java/org/apache/ignite/internal/table/TableManagerTest.java
@@ -268,9 +268,6 @@ public class TableManagerTest extends IgniteAbstractTest {
         assertThrows(IgniteException.class, () -> 
igniteTables.createTable(tblFullName, createTableChange));
         assertThrows(IgniteException.class, () -> 
igniteTables.createTableAsync(tblFullName, createTableChange));
 
-        assertThrows(IgniteException.class, () -> 
igniteTables.createTableIfNotExists(tblFullName, createTableChange));
-        assertThrows(IgniteException.class, () -> 
igniteTables.createTableIfNotExistsAsync(tblFullName, createTableChange));
-
         assertThrows(IgniteException.class, () -> 
igniteTables.alterTable(tblFullName, addColumnChange));
         assertThrows(IgniteException.class, () -> 
igniteTables.alterTableAsync(tblFullName, addColumnChange));
 
@@ -396,10 +393,7 @@ public class TableManagerTest extends IgniteAbstractTest {
                         .changeReplicas(REPLICAS)
                         .changePartitions(PARTITIONS)));
 
-        assertSame(table, tblManagerFut.join()
-                .createTableIfNotExists(scmTbl.canonicalName(), tblCh -> 
SchemaConfigurationConverter.convert(scmTbl, tblCh)
-                        .changeReplicas(REPLICAS)
-                        .changePartitions(PARTITIONS)));
+        assertSame(table, tblManagerFut.join().table(scmTbl.canonicalName()));
     }
 
     /**
diff --git 
a/modules/transactions/src/main/java/org/apache/ignite/internal/tx/impl/TxManagerImpl.java
 
b/modules/transactions/src/main/java/org/apache/ignite/internal/tx/impl/TxManagerImpl.java
index 5786e81..acc54dd 100644
--- 
a/modules/transactions/src/main/java/org/apache/ignite/internal/tx/impl/TxManagerImpl.java
+++ 
b/modules/transactions/src/main/java/org/apache/ignite/internal/tx/impl/TxManagerImpl.java
@@ -19,7 +19,7 @@ package org.apache.ignite.internal.tx.impl;
 
 import static java.util.concurrent.CompletableFuture.completedFuture;
 import static java.util.concurrent.CompletableFuture.failedFuture;
-import static org.apache.ignite.lang.LoggerMessageHelper.format;
+import static org.apache.ignite.lang.IgniteStringFormatter.format;
 
 import java.nio.ByteBuffer;
 import java.util.HashMap;

Reply via email to