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

nizhikov pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ignite.git


The following commit(s) were added to refs/heads/master by this push:
     new 21e5ba5  IGNITE-13450 Add event fired before SQL query execution 
(#8252)
21e5ba5 is described below

commit 21e5ba57db948c0d522f2066e66650c46185e7f3
Author: Дмитрий Рябов <somefire...@gmail.com>
AuthorDate: Tue Nov 24 10:00:40 2020 +0300

    IGNITE-13450 Add event fired before SQL query execution (#8252)
    
    Co-authored-by: Nikolay <nizhi...@apache.org>
---
 .../java/org/apache/ignite/events/EventType.java   |  10 ++
 .../ignite/events/SqlQueryExecutionEvent.java      | 138 +++++++++++++++++++++
 .../processors/query/h2/IgniteH2Indexing.java      |  24 +++-
 .../metric/SqlStatisticsUserQueriesFastTest.java   |   1 +
 .../metric/SqlStatisticsUserQueriesLongTest.java   |   4 +-
 .../internal/metric/UserQueriesTestBase.java       |  58 ++++++++-
 .../cache/IgniteCacheAbstractQuerySelfTest.java    |  71 +++++++++--
 7 files changed, 287 insertions(+), 19 deletions(-)

diff --git a/modules/core/src/main/java/org/apache/ignite/events/EventType.java 
b/modules/core/src/main/java/org/apache/ignite/events/EventType.java
index db1a88e..a51c25f 100644
--- a/modules/core/src/main/java/org/apache/ignite/events/EventType.java
+++ b/modules/core/src/main/java/org/apache/ignite/events/EventType.java
@@ -923,6 +923,16 @@ public interface EventType {
     public static final int EVT_CLUSTER_SNAPSHOT_FAILED = 151;
 
     /**
+     * Built-in event type: query execution.
+     * <p>
+     * NOTE: all types in range <b>from 1 to 1000 are reserved</b> for
+     * internal Ignite events and should not be used by user-defined events.
+     *
+     * @see SqlQueryExecutionEvent
+     */
+    public static final int EVT_SQL_QUERY_EXECUTION = 160;
+
+    /**
      * All cluster snapshot events. This array can be directly passed into
      * {@link IgniteEvents#localListen(IgnitePredicate, int...)} method to
      * subscribe to all cluster snapshot events.
diff --git 
a/modules/core/src/main/java/org/apache/ignite/events/SqlQueryExecutionEvent.java
 
b/modules/core/src/main/java/org/apache/ignite/events/SqlQueryExecutionEvent.java
new file mode 100644
index 0000000..0541dd8
--- /dev/null
+++ 
b/modules/core/src/main/java/org/apache/ignite/events/SqlQueryExecutionEvent.java
@@ -0,0 +1,138 @@
+/*
+ * 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.events;
+
+import java.util.UUID;
+import org.apache.ignite.cluster.ClusterNode;
+import org.apache.ignite.internal.util.tostring.GridToStringInclude;
+import org.apache.ignite.internal.util.typedef.internal.S;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.jetbrains.annotations.Nullable;
+
+import static org.apache.ignite.events.EventType.EVT_SQL_QUERY_EXECUTION;
+
+/**
+ * Query execution event.
+ * <p>
+ * Grid events are used for notification about what happens within the grid. 
Note that by
+ * design Ignite keeps all events generated on the local node locally and it 
provides
+ * APIs for performing a distributed queries across multiple nodes:
+ * <ul>
+ *      <li>
+ *          {@link 
org.apache.ignite.IgniteEvents#remoteQuery(org.apache.ignite.lang.IgnitePredicate,
 long, int...)} -
+ *          asynchronously querying events occurred on the nodes specified, 
including remote nodes.
+ *      </li>
+ *      <li>
+ *          {@link 
org.apache.ignite.IgniteEvents#localQuery(org.apache.ignite.lang.IgnitePredicate,
 int...)} -
+ *          querying only local events stored on this local node.
+ *      </li>
+ *      <li>
+ *          {@link 
org.apache.ignite.IgniteEvents#localListen(org.apache.ignite.lang.IgnitePredicate,
 int...)} -
+ *          listening to local grid events (events from remote nodes not 
included).
+ *      </li>
+ * </ul>
+ * User can also wait for events using method {@link 
org.apache.ignite.IgniteEvents#waitForLocal(org.apache.ignite.lang.IgnitePredicate,
 int...)}.
+ * <h1 class="header">Events and Performance</h1>
+ * Note that by default all events in Ignite are enabled and therefore 
generated and stored
+ * by whatever event storage SPI is configured. Ignite can and often does 
generate thousands events per seconds
+ * under the load and therefore it creates a significant additional load on 
the system. If these events are
+ * not needed by the application this load is unnecessary and leads to 
significant performance degradation.
+ * <p>
+ * It is <b>highly recommended</b> to enable only those events that your 
application logic requires
+ * by using {@link 
org.apache.ignite.configuration.IgniteConfiguration#getIncludeEventTypes()} 
method in Ignite configuration. Note that certain
+ * events are required for Ignite's internal operations and such events will 
still be generated but not stored by
+ * event storage SPI if they are disabled in Ignite configuration.
+ *
+ * @see EventType#EVT_SQL_QUERY_EXECUTION
+ */
+public class SqlQueryExecutionEvent extends EventAdapter {
+    /** */
+    private static final long serialVersionUID = 0L;
+
+    /** Query text. */
+    private final String text;
+
+    /** Query arguments. */
+    @GridToStringInclude
+    private final Object[] args;
+
+    /** Security subject ID. */
+    private final UUID subjId;
+
+    /**
+     * @param node Node where event was fired.
+     * @param msg Event message.
+     * @param text Query text.
+     * @param args Query arguments.
+     * @param subjId Security subject ID.
+     */
+    public SqlQueryExecutionEvent(
+        ClusterNode node,
+        String msg,
+        @Nullable String text,
+        @Nullable Object[] args,
+        @Nullable UUID subjId
+    ) {
+        super(node, msg, EVT_SQL_QUERY_EXECUTION);
+
+        this.text = text;
+        this.args = args;
+        this.subjId = subjId;
+    }
+
+    /**
+     * Gets query text.
+     * <p>
+     * Applicable for {@code SQL}, {@code SQL fields} queries.
+     *
+     * @return Query text.
+     */
+    @Nullable public String text() {
+        return text;
+    }
+
+    /**
+     * Gets query arguments.
+     * <p>
+     * Applicable for {@code SQL} and {@code SQL fields} queries.
+     *
+     * @return Query arguments.
+     */
+    @Nullable public Object[] arguments() {
+        return args.clone();
+    }
+
+    /**
+     * Gets security subject ID.
+     *
+     * @return Security subject ID.
+     */
+    @Nullable public UUID subjectId() {
+        return subjId;
+    }
+
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        return S.toString(SqlQueryExecutionEvent.class, this,
+            "nodeId8", U.id8(node().id()),
+            "msg", message(),
+            "type", name(),
+            "tstamp", timestamp());
+    }
+}
+
diff --git 
a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java
 
b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java
index 1154289..d06418c 100644
--- 
a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java
+++ 
b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java
@@ -51,6 +51,7 @@ import org.apache.ignite.cache.query.SqlQuery;
 import org.apache.ignite.cluster.ClusterNode;
 import org.apache.ignite.events.DiscoveryEvent;
 import org.apache.ignite.events.EventType;
+import org.apache.ignite.events.SqlQueryExecutionEvent;
 import org.apache.ignite.internal.GridKernalContext;
 import org.apache.ignite.internal.GridTopic;
 import org.apache.ignite.internal.IgniteInternalFuture;
@@ -200,6 +201,7 @@ import static java.util.Collections.singletonList;
 import static java.util.Objects.isNull;
 import static java.util.Objects.nonNull;
 import static 
org.apache.ignite.IgniteSystemProperties.IGNITE_MVCC_TX_SIZE_CACHING_THRESHOLD;
+import static org.apache.ignite.events.EventType.EVT_SQL_QUERY_EXECUTION;
 import static 
org.apache.ignite.internal.processors.cache.mvcc.MvccCachingManager.TX_SIZE_THRESHOLD;
 import static 
org.apache.ignite.internal.processors.cache.mvcc.MvccUtils.checkActive;
 import static 
org.apache.ignite.internal.processors.cache.mvcc.MvccUtils.mvccEnabled;
@@ -1019,7 +1021,7 @@ public class IgniteH2Indexing implements 
GridQueryIndexing {
                 IgniteQueryErrorCode.UNSUPPORTED_OPERATION);
         }
 
-        Long qryId = registerRunningQuery(qryDesc, null);
+        Long qryId = registerRunningQuery(qryDesc, qryParams, null);
 
         CommandResult res = null;
 
@@ -1202,7 +1204,7 @@ public class IgniteH2Indexing implements 
GridQueryIndexing {
     ) {
         IndexingQueryFilter filter = (qryDesc.local() ? backupFilter(null, 
qryParams.partitions()) : null);
 
-        Long qryId = registerRunningQuery(qryDesc, cancel);
+        Long qryId = registerRunningQuery(qryDesc, qryParams, cancel);
 
         Exception failReason = null;
 
@@ -1287,7 +1289,7 @@ public class IgniteH2Indexing implements 
GridQueryIndexing {
         assert cancel != null;
 
         // Register query.
-        Long qryId = registerRunningQuery(qryDesc, cancel);
+        Long qryId = registerRunningQuery(qryDesc, qryParams, cancel);
 
         try (TraceSurroundings ignored = 
MTC.support(ctx.tracing().create(SQL_CURSOR_OPEN, MTC.span()))) {
             GridNearTxLocal tx = null;
@@ -1546,17 +1548,29 @@ public class IgniteH2Indexing implements 
GridQueryIndexing {
      * Register running query.
      *
      * @param qryDesc Query descriptor.
+     * @param qryParams Query parameters.
      * @param cancel Query cancel state holder.
      * @return Id of registered query or {@code null} if query wasn't 
registered.
      */
-    private Long registerRunningQuery(QueryDescriptor qryDesc, GridQueryCancel 
cancel) {
-        return runningQryMgr.register(
+    private Long registerRunningQuery(QueryDescriptor qryDesc, QueryParameters 
qryParams, GridQueryCancel cancel) {
+        Long res = runningQryMgr.register(
             qryDesc.sql(),
             GridCacheQueryType.SQL_FIELDS,
             qryDesc.schemaName(),
             qryDesc.local(),
             cancel
         );
+
+        if (ctx.event().isRecordable(EVT_SQL_QUERY_EXECUTION)) {
+            ctx.event().record(new SqlQueryExecutionEvent(
+                ctx.discovery().localNode(),
+                GridCacheQueryType.SQL_FIELDS.name() + " query execution.",
+                qryDesc.sql(),
+                qryParams.arguments(),
+                ctx.security().enabled() ? 
ctx.security().securityContext().subject().id() : null));
+        }
+
+        return res;
     }
 
     /**
diff --git 
a/modules/indexing/src/test/java/org/apache/ignite/internal/metric/SqlStatisticsUserQueriesFastTest.java
 
b/modules/indexing/src/test/java/org/apache/ignite/internal/metric/SqlStatisticsUserQueriesFastTest.java
index 5368382..83e4c2e 100644
--- 
a/modules/indexing/src/test/java/org/apache/ignite/internal/metric/SqlStatisticsUserQueriesFastTest.java
+++ 
b/modules/indexing/src/test/java/org/apache/ignite/internal/metric/SqlStatisticsUserQueriesFastTest.java
@@ -301,6 +301,7 @@ public class SqlStatisticsUserQueriesFastTest extends 
UserQueriesTestBase {
     public void testLocalSelectCanceled() {
         assertMetricsIncrementedOnlyOnReducer(() ->
                 startAndKillQuery(new SqlFieldsQuery("SELECT * FROM TAB WHERE 
ID <> suspendHook(ID)").setLocal(true)),
+            2,
             "success",
             "failed",
             "canceled");
diff --git 
a/modules/indexing/src/test/java/org/apache/ignite/internal/metric/SqlStatisticsUserQueriesLongTest.java
 
b/modules/indexing/src/test/java/org/apache/ignite/internal/metric/SqlStatisticsUserQueriesLongTest.java
index 74b21cb..abe9afe 100644
--- 
a/modules/indexing/src/test/java/org/apache/ignite/internal/metric/SqlStatisticsUserQueriesLongTest.java
+++ 
b/modules/indexing/src/test/java/org/apache/ignite/internal/metric/SqlStatisticsUserQueriesLongTest.java
@@ -92,7 +92,7 @@ public class SqlStatisticsUserQueriesLongTest extends 
UserQueriesTestBase {
         SuspendQuerySqlFunctions.setProcessRowsToSuspend(1);
 
         assertMetricsIncrementedOnlyOnReducer(() ->
-            startAndKillQuery(new SqlFieldsQuery("SELECT * FROM TAB WHERE ID < 
200 AND suspendHook(ID) <> 5 ")),
+            startAndKillQuery(new SqlFieldsQuery("SELECT * FROM TAB WHERE ID < 
200 AND suspendHook(ID) <> 5 ")), 2,
             "success", "failed", "canceled");
     }
 
@@ -128,7 +128,7 @@ public class SqlStatisticsUserQueriesLongTest extends 
UserQueriesTestBase {
         SuspendQuerySqlFunctions.setProcessRowsToSuspend(1);
 
         assertMetricsIncrementedOnlyOnReducer(() ->
-                startAndKillQuery(new SqlFieldsQuery("SELECT * FROM TAB WHERE 
ID < 200 AND suspendHook(ID) <> 5 ")),
+                startAndKillQuery(new SqlFieldsQuery("SELECT * FROM TAB WHERE 
ID < 200 AND suspendHook(ID) <> 5 ")), 2,
             "success", "failed", "canceled");
     }
 
diff --git 
a/modules/indexing/src/test/java/org/apache/ignite/internal/metric/UserQueriesTestBase.java
 
b/modules/indexing/src/test/java/org/apache/ignite/internal/metric/UserQueriesTestBase.java
index 15a346d..611e284 100644
--- 
a/modules/indexing/src/test/java/org/apache/ignite/internal/metric/UserQueriesTestBase.java
+++ 
b/modules/indexing/src/test/java/org/apache/ignite/internal/metric/UserQueriesTestBase.java
@@ -18,21 +18,27 @@
 package org.apache.ignite.internal.metric;
 
 import java.util.Collection;
+import java.util.Collections;
 import java.util.Map;
 import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 import org.apache.ignite.cache.query.QueryCancelledException;
 import org.apache.ignite.cache.query.SqlFieldsQuery;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.events.SqlQueryExecutionEvent;
 import org.apache.ignite.internal.IgniteEx;
 import org.apache.ignite.internal.IgniteInternalFuture;
 import org.apache.ignite.internal.processors.metric.MetricRegistry;
 import org.apache.ignite.internal.processors.query.GridRunningQueryInfo;
+import org.apache.ignite.lang.IgnitePredicate;
 import org.apache.ignite.spi.metric.LongMetric;
 import org.apache.ignite.spi.metric.Metric;
 import org.apache.ignite.testframework.GridTestUtils;
 import org.junit.Assert;
 
+import static org.apache.ignite.events.EventType.EVT_SQL_QUERY_EXECUTION;
 import static 
org.apache.ignite.internal.processors.query.RunningQueryManager.SQL_USER_QUERIES_REG_NAME;
 
 /**
@@ -52,13 +58,36 @@ public class UserQueriesTestBase extends 
SqlStatisticsAbstractTest {
     /** The second node index. This node should execute only map parts of the 
queries. */
     protected static final int MAPPER_IDX = 1;
 
+    /** */
+    private static final AtomicInteger SQL_QRY_EXEC_EVT_CNTR = new 
AtomicInteger();
+
+    /** {@inheritDoc} */
+    @Override protected IgniteConfiguration getConfiguration(String 
igniteInstanceName) throws Exception {
+        IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName);
+
+        IgnitePredicate<SqlQueryExecutionEvent> lsnr = evt -> {
+            assertNotNull(evt.text());
+
+            SQL_QRY_EXEC_EVT_CNTR.incrementAndGet();
+
+            return true;
+        };
+
+        int[] evts = new int[] {EVT_SQL_QUERY_EXECUTION};
+
+        cfg.setIncludeEventTypes(evts);
+        cfg.setLocalEventListeners(Collections.singletonMap(lsnr, evts));
+
+        return cfg;
+    }
+
     /**
      * Verify that after specified action is performed, all metrics are left 
unchanged.
      *
      * @param act Action.
      */
     protected void assertMetricsRemainTheSame(Runnable act) {
-        assertMetricsAre(fetchAllMetrics(REDUCER_IDX), 
fetchAllMetrics(MAPPER_IDX), act);
+        assertMetricsAre(fetchAllMetrics(REDUCER_IDX), 
fetchAllMetrics(MAPPER_IDX), act, 0);
     }
 
     /**
@@ -68,6 +97,21 @@ public class UserQueriesTestBase extends 
SqlStatisticsAbstractTest {
      * @param incrementedMetrics array of metrics to check.
      */
     protected void assertMetricsIncrementedOnlyOnReducer(Runnable act, 
String... incrementedMetrics) {
+        assertMetricsIncrementedOnlyOnReducer(act, 1, incrementedMetrics);
+    }
+
+    /**
+     * Verify that after action is performed, specified metrics gets 
incremented only on reducer node.
+     *
+     * @param act action (callback) to perform.
+     * @param qryCnt Amount of queries.
+     * @param incrementedMetrics array of metrics to check.
+     */
+    protected void assertMetricsIncrementedOnlyOnReducer(
+        Runnable act,
+        int qryCnt,
+        String... incrementedMetrics
+    ) {
         Map<String, Long> expValuesMapper = fetchAllMetrics(MAPPER_IDX);
 
         Map<String, Long> expValuesReducer = fetchAllMetrics(REDUCER_IDX);
@@ -75,7 +119,7 @@ public class UserQueriesTestBase extends 
SqlStatisticsAbstractTest {
         for (String incMet : incrementedMetrics)
             expValuesReducer.compute(incMet, (name, val) -> val + 1);
 
-        assertMetricsAre(expValuesReducer, expValuesMapper, act);
+        assertMetricsAre(expValuesReducer, expValuesMapper, act, qryCnt);
     }
 
     /**
@@ -97,11 +141,16 @@ public class UserQueriesTestBase extends 
SqlStatisticsAbstractTest {
      * @param expMetricsReducer Expected metrics on reducer.
      * @param expMetricsMapper Expected metrics on mapper.
      * @param act callback to perform. Usually sql query execution.
+     * @param qryEvtCnt Expected sql query events.
      */
     private void assertMetricsAre(
         Map<String, Long> expMetricsReducer,
         Map<String, Long> expMetricsMapper,
-        Runnable act) {
+        Runnable act,
+        int qryEvtCnt
+    ) {
+        SQL_QRY_EXEC_EVT_CNTR.set(0);
+
         act.run();
 
         expMetricsReducer.forEach((mName, expVal) -> {
@@ -115,6 +164,9 @@ public class UserQueriesTestBase extends 
SqlStatisticsAbstractTest {
 
             Assert.assertEquals("Unexpected value for metric " + mName, 
(long)expVal, actVal);
         });
+
+        Assert.assertEquals("Unexpected records for SqlQueryExecutionEvent.",
+            qryEvtCnt, SQL_QRY_EXEC_EVT_CNTR.get());
     }
 
     /**
diff --git 
a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractQuerySelfTest.java
 
b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractQuerySelfTest.java
index 114c4aa..36e6d7a 100644
--- 
a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractQuerySelfTest.java
+++ 
b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractQuerySelfTest.java
@@ -46,6 +46,7 @@ import org.apache.ignite.Ignite;
 import org.apache.ignite.IgniteBinary;
 import org.apache.ignite.IgniteCache;
 import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.Ignition;
 import org.apache.ignite.binary.BinaryObject;
 import org.apache.ignite.cache.CacheAtomicityMode;
 import org.apache.ignite.cache.CacheMode;
@@ -63,7 +64,10 @@ import 
org.apache.ignite.cache.query.annotations.QuerySqlFunction;
 import org.apache.ignite.cache.query.annotations.QueryTextField;
 import org.apache.ignite.cache.store.CacheStore;
 import org.apache.ignite.cache.store.CacheStoreAdapter;
+import org.apache.ignite.client.Config;
+import org.apache.ignite.client.IgniteClient;
 import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.ClientConfiguration;
 import org.apache.ignite.configuration.DataStorageConfiguration;
 import org.apache.ignite.configuration.IgniteConfiguration;
 import org.apache.ignite.configuration.NearCacheConfiguration;
@@ -71,6 +75,7 @@ import org.apache.ignite.events.CacheQueryExecutedEvent;
 import org.apache.ignite.events.CacheQueryReadEvent;
 import org.apache.ignite.events.Event;
 import org.apache.ignite.events.EventType;
+import org.apache.ignite.events.SqlQueryExecutionEvent;
 import org.apache.ignite.internal.binary.BinaryMarshaller;
 import org.apache.ignite.internal.processors.cache.query.QueryCursorEx;
 import org.apache.ignite.internal.processors.query.GridQueryFieldMetadata;
@@ -95,6 +100,7 @@ import static 
org.apache.ignite.cache.CacheRebalanceMode.SYNC;
 import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_SYNC;
 import static org.apache.ignite.events.EventType.EVT_CACHE_QUERY_EXECUTED;
 import static org.apache.ignite.events.EventType.EVT_CACHE_QUERY_OBJECT_READ;
+import static org.apache.ignite.events.EventType.EVT_SQL_QUERY_EXECUTION;
 import static 
org.apache.ignite.internal.processors.cache.query.CacheQueryType.FULL_TEXT;
 import static 
org.apache.ignite.internal.processors.cache.query.CacheQueryType.SCAN;
 import static 
org.apache.ignite.testframework.GridTestUtils.assertThrowsWithCause;
@@ -1461,14 +1467,6 @@ public abstract class IgniteCacheAbstractQuerySelfTest 
extends GridCommonAbstrac
      * @throws Exception If failed.
      */
     @Test
-    public void testSqlQueryEvents() throws Exception {
-        checkSqlQueryEvents();
-    }
-
-    /**
-     * @throws Exception If failed.
-     */
-    @Test
     public void testFieldsQueryMetadata() throws Exception {
         IgniteCache<UUID, Person> cache = jcache(UUID.class, Person.class);
 
@@ -1491,7 +1489,8 @@ public abstract class IgniteCacheAbstractQuerySelfTest 
extends GridCommonAbstrac
     /**
      * @throws Exception If failed.
      */
-    private void checkSqlQueryEvents() throws Exception {
+    @Test
+    public void testSqlQueryEvents() throws Exception {
         final IgniteCache<Integer, Integer> cache = jcache(Integer.class, 
Integer.class);
         final boolean evtsDisabled = 
cache.getConfiguration(CacheConfiguration.class).isEventsDisabled();
         final CountDownLatch execLatch = new CountDownLatch(evtsDisabled ? 0 :
@@ -1549,6 +1548,60 @@ public abstract class IgniteCacheAbstractQuerySelfTest 
extends GridCommonAbstrac
      * @throws Exception If failed.
      */
     @Test
+    public void testClientQueryExecutedEvents() throws Exception {
+        CountDownLatch execLatch = new CountDownLatch(9);
+
+        IgnitePredicate<SqlQueryExecutionEvent> lsnr = evt -> {
+            assertNotNull(evt.text());
+
+            execLatch.countDown();
+
+            return true;
+        };
+
+        ignite().events().localListen(lsnr, EVT_SQL_QUERY_EXECUTION);
+
+        ClientConfiguration cc = new 
ClientConfiguration().setAddresses(Config.SERVER);
+
+        try (IgniteClient client = Ignition.startClient(cc)) {
+            client.query(new SqlFieldsQuery("create table TEST_TABLE(key int 
primary key, val int)"))
+                .getAll();
+
+            client.query(new SqlFieldsQuery("insert into TEST_TABLE values (?, 
?)").setArgs(1, 1))
+                .getAll();
+
+            client.query(new SqlFieldsQuery("update TEST_TABLE set val = ?2 
where key = ?1").setArgs(1, 2))
+                .getAll();
+
+            client.query(new SqlFieldsQuery("select * from TEST_TABLE"))
+                .getAll();
+
+            client.query(new SqlFieldsQuery("create index idx_1 on 
TEST_TABLE(key)"))
+                .getAll();
+
+            client.query(new SqlFieldsQuery("drop index idx_1"))
+                .getAll();
+
+            client.query(new SqlFieldsQuery("alter table TEST_TABLE add column 
val2 int"))
+                .getAll();
+
+            client.query(new SqlFieldsQuery("alter table TEST_TABLE drop 
val2"))
+                .getAll();
+
+            client.query(new SqlFieldsQuery("drop table TEST_TABLE"))
+                .getAll();
+
+            assert execLatch.await(3_000, MILLISECONDS);
+        }
+        finally {
+            ignite().events().stopLocalListen(lsnr, EVT_SQL_QUERY_EXECUTION);
+        }
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    @Test
     public void testScanQueryEvents() throws Exception {
         final Map<Integer, Integer> map = new ConcurrentHashMap<>();
         final IgniteCache<Integer, Integer> cache = jcache(Integer.class, 
Integer.class);

Reply via email to