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

samaitra 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 0140234  IGNITE-7285 Add default query timeout - Fixes #6490.
0140234 is described below

commit 014023453ac8c3bbdb5f9636a2b3d843de91d2f6
Author: samaitra <[email protected]>
AuthorDate: Fri Nov 15 18:40:49 2019 -0600

    IGNITE-7285 Add default query timeout - Fixes #6490.
    
    Signed-off-by: samaitra <[email protected]>
---
 .../apache/ignite/cache/query/SqlFieldsQuery.java  |   5 +-
 .../ignite/configuration/IgniteConfiguration.java  |  36 ++++
 .../processors/odbc/odbc/OdbcRequestHandler.java   |   4 +-
 .../cache/ClientCacheSqlFieldsQueryRequest.java    |   6 +-
 .../processors/query/h2/QueryParameters.java       |  39 +---
 .../internal/processors/query/h2/QueryParser.java  |  56 +++++-
 ...acheDistributedQueryDefaultTimeoutSelfTest.java | 197 +++++++++++++++++++++
 ...gniteCacheLocalQueryDefaultTimeoutSelfTest.java | 152 ++++++++++++++++
 .../IgniteBinaryCacheQueryTestSuite2.java          |   7 +-
 9 files changed, 453 insertions(+), 49 deletions(-)

diff --git 
a/modules/core/src/main/java/org/apache/ignite/cache/query/SqlFieldsQuery.java 
b/modules/core/src/main/java/org/apache/ignite/cache/query/SqlFieldsQuery.java
index f00d882..6d6e167 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/cache/query/SqlFieldsQuery.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/cache/query/SqlFieldsQuery.java
@@ -51,6 +51,9 @@ public class SqlFieldsQuery extends Query<List<?>> {
     /** Default value of the update internal batch size. */
     private static final int DFLT_UPDATE_BATCH_SIZE = 1;
 
+    /** Default value of Query timeout. Default is -1 means no timeout is set. 
*/
+    private static final int DFLT_QUERY_TIMEOUT = -1;
+
     /** Do not remove. For tests only. */
     @SuppressWarnings("NonConstantFieldWithUpperCaseName")
     private static boolean DFLT_LAZY;
@@ -66,7 +69,7 @@ public class SqlFieldsQuery extends Query<List<?>> {
     private boolean collocated;
 
     /** Query timeout in millis. */
-    private int timeout;
+    private int timeout = DFLT_QUERY_TIMEOUT;
 
     /** */
     private boolean enforceJoinOrder;
diff --git 
a/modules/core/src/main/java/org/apache/ignite/configuration/IgniteConfiguration.java
 
b/modules/core/src/main/java/org/apache/ignite/configuration/IgniteConfiguration.java
index 664fd12..ce30c3a 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/configuration/IgniteConfiguration.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/configuration/IgniteConfiguration.java
@@ -46,6 +46,7 @@ import org.apache.ignite.events.EventType;
 import org.apache.ignite.failure.FailureHandler;
 import 
org.apache.ignite.internal.managers.eventstorage.GridEventStorageManager;
 import org.apache.ignite.internal.processors.odbc.ClientListenerProcessor;
+import org.apache.ignite.internal.util.typedef.internal.A;
 import org.apache.ignite.internal.util.typedef.internal.S;
 import org.apache.ignite.lang.IgniteAsyncCallback;
 import org.apache.ignite.lang.IgniteInClosure;
@@ -242,6 +243,9 @@ public class IgniteConfiguration {
     /** Default SQL query history size. */
     public static final int DFLT_SQL_QUERY_HISTORY_SIZE = 1000;
 
+    /** Default query timeout. */
+    public static final long DFLT_QRY_TIMEOUT = 0;
+
     /** Optional local Ignite instance name. */
     private String igniteInstanceName;
 
@@ -293,6 +297,9 @@ public class IgniteConfiguration {
     /** SQL query history size. */
     private int sqlQryHistSize = DFLT_SQL_QUERY_HISTORY_SIZE;
 
+    /** Default query timeout. */
+    private long dfltQryTimeout = DFLT_QRY_TIMEOUT;
+
     /** Ignite installation folder. */
     private String igniteHome;
 
@@ -623,6 +630,7 @@ public class IgniteConfiguration {
         consistentId = cfg.getConsistentId();
         daemon = cfg.isDaemon();
         dataStreamerPoolSize = cfg.getDataStreamerThreadPoolSize();
+        dfltQryTimeout = cfg.getDefaultQueryTimeout();
         deployMode = cfg.getDeploymentMode();
         discoStartupDelay = cfg.getDiscoveryStartupDelay();
         execCfgs = cfg.getExecutorConfiguration();
@@ -1076,6 +1084,34 @@ public class IgniteConfiguration {
     }
 
     /**
+     * Defines the default query timeout.
+     *
+     * Defaults to {@link #DFLT_QRY_TIMEOUT}.
+     * {@code 0} means there is no timeout (this
+     * is a default value)
+     *
+     * @return Default query timeout.
+     */
+    public long getDefaultQueryTimeout() {
+        return dfltQryTimeout;
+    }
+
+    /**
+     * Sets timeout in milliseconds for default query timeout.
+     * {@code 0} means there is no timeout (this
+     * is a default value)
+     *
+     * @param dfltQryTimeout Timeout in milliseconds.
+     * @return {@code this} for chaining.
+     */
+    public IgniteConfiguration setDefaultQueryTimeout(long dfltQryTimeout) {
+        A.ensure(dfltQryTimeout >= 0 && dfltQryTimeout <= Integer.MAX_VALUE, 
"default query timeout value should be valid Integer.");
+        this.dfltQryTimeout = dfltQryTimeout;
+
+        return this;
+    }
+
+    /**
      * Sets thread pool size to use within grid.
      *
      * @param poolSize Thread pool size to use within grid.
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcRequestHandler.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcRequestHandler.java
index 887ee2e..d285ba2 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcRequestHandler.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcRequestHandler.java
@@ -338,9 +338,11 @@ public class OdbcRequestHandler implements 
ClientListenerRequestHandler {
         SqlFieldsQueryEx qry = makeQuery(schema, sql);
 
         qry.setArgs(args);
-        qry.setTimeout(timeout, TimeUnit.SECONDS);
         qry.setAutoCommit(autoCommit);
 
+        if (timeout >= 0)
+            qry.setTimeout(timeout, TimeUnit.SECONDS);
+
         return qry;
     }
 
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheSqlFieldsQueryRequest.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheSqlFieldsQueryRequest.java
index 4f18c08..7826d3c 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheSqlFieldsQueryRequest.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheSqlFieldsQueryRequest.java
@@ -82,8 +82,10 @@ public class ClientCacheSqlFieldsQueryRequest extends 
ClientCacheDataRequest imp
                 .setReplicatedOnly(replicatedOnly)
                 .setEnforceJoinOrder(enforceJoinOrder)
                 .setCollocated(collocated)
-                .setLazy(lazy)
-                .setTimeout(timeout, TimeUnit.MILLISECONDS);
+                .setLazy(lazy);
+
+        if (timeout >= 0)
+            qry.setTimeout(timeout, TimeUnit.MILLISECONDS);
 
         this.qry = qry;
     }
diff --git 
a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/QueryParameters.java
 
b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/QueryParameters.java
index 49a5658..d02518e 100644
--- 
a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/QueryParameters.java
+++ 
b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/QueryParameters.java
@@ -19,8 +19,6 @@
 package org.apache.ignite.internal.processors.query.h2;
 
 import java.util.List;
-import org.apache.ignite.cache.query.SqlFieldsQuery;
-import org.apache.ignite.internal.processors.cache.query.SqlFieldsQueryEx;
 import org.apache.ignite.internal.processors.query.NestedTxMode;
 
 /**
@@ -61,41 +59,7 @@ public class QueryParameters {
      */
     private final int updateBatchSize;
 
-    /**
-     * Create parameters from query.
-     *
-     * @param qry Query.
-     * @return Parameters.
-     */
-    public static QueryParameters fromQuery(SqlFieldsQuery qry) {
-        NestedTxMode nestedTxMode = NestedTxMode.DEFAULT;
-        boolean autoCommit = true;
-        List<Object[]> batchedArgs = null;
-
-        if (qry instanceof SqlFieldsQueryEx) {
-            SqlFieldsQueryEx qry0 = (SqlFieldsQueryEx)qry;
-
-            if (qry0.getNestedTxMode() != null)
-                nestedTxMode = qry0.getNestedTxMode();
-
-            autoCommit = qry0.isAutoCommit();
 
-            batchedArgs = qry0.batchedArguments();
-        }
-
-        return new QueryParameters(
-            qry.getArgs(),
-            qry.getPartitions(),
-            qry.getTimeout(),
-            qry.isLazy(),
-            qry.getPageSize(),
-            null,
-            nestedTxMode,
-            autoCommit,
-            batchedArgs,
-            qry.getUpdateBatchSize()
-        );
-    }
 
     /**
      * Constructor.
@@ -111,8 +75,7 @@ public class QueryParameters {
      * @param batchedArgs Batched arguments.
      * @param updateBatchSize Update internal batch size.
      */
-    @SuppressWarnings("AssignmentOrReturnOfFieldWithMutableType")
-    private QueryParameters(
+    @SuppressWarnings("AssignmentOrReturnOfFieldWithMutableType") 
QueryParameters(
         Object[] args,
         int[] parts,
         int timeout,
diff --git 
a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/QueryParser.java
 
b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/QueryParser.java
index 5ede3e4..6920e77 100644
--- 
a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/QueryParser.java
+++ 
b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/QueryParser.java
@@ -39,6 +39,7 @@ import 
org.apache.ignite.internal.processors.cache.query.SqlFieldsQueryEx;
 import org.apache.ignite.internal.processors.odbc.jdbc.JdbcParameterMeta;
 import org.apache.ignite.internal.processors.query.GridQueryFieldMetadata;
 import org.apache.ignite.internal.processors.query.IgniteSQLException;
+import org.apache.ignite.internal.processors.query.NestedTxMode;
 import org.apache.ignite.internal.processors.query.QueryUtils;
 import org.apache.ignite.internal.processors.query.h2.dml.DmlAstUtils;
 import org.apache.ignite.internal.processors.query.h2.dml.UpdatePlan;
@@ -135,6 +136,49 @@ public class QueryParser {
     }
 
     /**
+     * Create parameters from query.
+     *
+     * @param qry Query.
+     * @return Parameters.
+     */
+    public QueryParameters queryParameters(SqlFieldsQuery qry) {
+        NestedTxMode nestedTxMode = NestedTxMode.DEFAULT;
+        boolean autoCommit = true;
+        List<Object[]> batchedArgs = null;
+
+        if (qry instanceof SqlFieldsQueryEx) {
+            SqlFieldsQueryEx qry0 = (SqlFieldsQueryEx)qry;
+
+            if (qry0.getNestedTxMode() != null)
+                nestedTxMode = qry0.getNestedTxMode();
+
+            autoCommit = qry0.isAutoCommit();
+
+            batchedArgs = qry0.batchedArguments();
+        }
+
+        int timeout;
+
+        if (qry.getTimeout() >= 0)
+            timeout = qry.getTimeout();
+        else
+            timeout = 
(int)idx.kernalContext().config().getDefaultQueryTimeout();
+
+        return new QueryParameters(
+            qry.getArgs(),
+            qry.getPartitions(),
+            timeout,
+            qry.isLazy(),
+            qry.getPageSize(),
+            null,
+            nestedTxMode,
+            autoCommit,
+            batchedArgs,
+            qry.getUpdateBatchSize()
+        );
+    }
+
+    /**
      * Parse the query.
      *
      * @param schemaName schema name.
@@ -150,7 +194,7 @@ public class QueryParser {
         if (cached != null)
             return new QueryParserResult(
                 qryDesc,
-                QueryParameters.fromQuery(qry),
+                queryParameters(qry),
                 null,
                 cached.parametersMeta(),
                 cached.select(),
@@ -231,7 +275,7 @@ public class QueryParser {
 
             return new QueryParserResult(
                 newPlanKey,
-                QueryParameters.fromQuery(newQry),
+                queryParameters(newQry),
                 remainingQry,
                 Collections.emptyList(), // Currently none of native 
statements supports parameters.
                 null,
@@ -371,7 +415,7 @@ public class QueryParser {
 
                 return new QueryParserResult(
                     newQryDesc,
-                    QueryParameters.fromQuery(newQry),
+                    queryParameters(newQry),
                     remainingQry,
                     paramsMeta,
                     null,
@@ -384,7 +428,7 @@ public class QueryParser {
 
                 return new QueryParserResult(
                     newQryDesc,
-                    QueryParameters.fromQuery(newQry),
+                    queryParameters(newQry),
                     remainingQry,
                     paramsMeta,
                     null,
@@ -397,7 +441,7 @@ public class QueryParser {
 
                 return new QueryParserResult(
                     newQryDesc,
-                    QueryParameters.fromQuery(newQry),
+                    queryParameters(newQry),
                     remainingQry,
                     paramsMeta,
                     null,
@@ -526,7 +570,7 @@ public class QueryParser {
 
             return new QueryParserResult(
                 newQryDesc,
-                QueryParameters.fromQuery(newQry),
+                queryParameters(newQry),
                 remainingQry,
                 paramsMeta,
                 select,
diff --git 
a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/distributed/near/IgniteCacheDistributedQueryDefaultTimeoutSelfTest.java
 
b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/distributed/near/IgniteCacheDistributedQueryDefaultTimeoutSelfTest.java
new file mode 100644
index 0000000..82b8885
--- /dev/null
+++ 
b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/distributed/near/IgniteCacheDistributedQueryDefaultTimeoutSelfTest.java
@@ -0,0 +1,197 @@
+/*
+ * 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.processors.cache.distributed.near;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.TimeUnit;
+import javax.cache.CacheException;
+import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.cache.query.QueryCursor;
+import org.apache.ignite.cache.query.SqlFieldsQuery;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.internal.IgniteEx;
+import org.apache.ignite.cache.query.QueryCancelledException;
+import org.apache.ignite.internal.processors.GridProcessor;
+import org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing;
+import org.apache.ignite.internal.util.typedef.X;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+import org.junit.Test;
+
+/**
+ * Tests distributed SQL queries default timeouts.
+ */
+public class IgniteCacheDistributedQueryDefaultTimeoutSelfTest extends 
GridCommonAbstractTest {
+    /** Grids count. */
+    private static final int GRIDS_CNT = 3;
+
+    /** Cache size. */
+    public static final int CACHE_SIZE = 10_000;
+
+    /** Default query timeout */
+    private static final long DEFAULT_QUERY_TIMEOUT = 1000;
+
+    /** Value size. */
+    public static final int VAL_SIZE = 16;
+
+    /** */
+    private static final String QRY_1 = "select a._val, b._val from String a, 
String b";
+
+    /** */
+    private static final String QRY_2 = "select a._key, count(*) from String a 
group by a._key";
+
+    /** */
+    private static final String QRY_3 = "select a._val from String a";
+
+    /** {@inheritDoc} */
+    @Override protected void beforeTestsStarted() throws Exception {
+        super.beforeTestsStarted();
+
+        startGridsMultiThreaded(GRIDS_CNT);
+    }
+
+    /** {@inheritDoc} */
+    @Override protected IgniteConfiguration getConfiguration(String 
igniteInstanceName) throws Exception {
+        IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName);
+
+        CacheConfiguration<Integer, String> ccfg = new 
CacheConfiguration<>(DEFAULT_CACHE_NAME);
+        ccfg.setIndexedTypes(Integer.class, String.class);
+
+        cfg.setCacheConfiguration(ccfg);
+
+        if ("client".equals(igniteInstanceName))
+            cfg.setClientMode(true);
+
+        cfg.setDefaultQueryTimeout(DEFAULT_QUERY_TIMEOUT);
+
+        return cfg;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void afterTest() throws Exception {
+        super.afterTest();
+
+        grid(0).cache(DEFAULT_CACHE_NAME).removeAll();
+    }
+
+    /** */
+    @Test
+    public void testRemoteQueryExecutionTimeout() throws Exception {
+        testQueryCancel(CACHE_SIZE, VAL_SIZE, QRY_1, 500, 
TimeUnit.MILLISECONDS, true, true);
+    }
+
+    /** */
+    @Test
+    public void testRemoteQueryWithMergeTableTimeout() throws Exception {
+        testQueryCancel(CACHE_SIZE, VAL_SIZE, QRY_2, 500, 
TimeUnit.MILLISECONDS, true, false);
+    }
+
+    /** */
+    @Test
+    public void testRemoteQueryExecutionCancel0() throws Exception {
+        testQueryCancel(CACHE_SIZE, VAL_SIZE, QRY_1, 1, TimeUnit.MILLISECONDS, 
false, true);
+    }
+
+    /** */
+    private void testQueryCancel(int keyCnt, int valSize, String sql, int 
timeoutUnits, TimeUnit timeUnit,
+        boolean timeout, boolean checkCanceled) throws Exception {
+        try (Ignite client = startGrid("client")) {
+            IgniteCache<Object, Object> cache = 
client.cache(DEFAULT_CACHE_NAME);
+
+            assertEquals(0, cache.localSize());
+
+            int p = 1;
+            for (int i = 1; i <= keyCnt; i++) {
+                char[] tmp = new char[valSize];
+                Arrays.fill(tmp, ' ');
+                cache.put(i, new String(tmp));
+
+                if (i/(float)keyCnt >= p/10f) {
+                    log().info("Loaded " + i + " of " + keyCnt);
+
+                    p++;
+                }
+            }
+
+            assertEquals(0, cache.localSize());
+
+            SqlFieldsQuery qry = new SqlFieldsQuery(sql);
+
+            final QueryCursor<List<?>> cursor;
+            if (timeout) {
+                qry.setTimeout(timeoutUnits, timeUnit);
+
+                cursor = cache.query(qry);
+            }
+            else {
+                cursor = cache.query(qry);
+
+                client.scheduler().runLocal(new Runnable() {
+                    @Override public void run() {
+                        cursor.close();
+                    }
+                }, timeoutUnits, timeUnit);
+            }
+
+            try (QueryCursor<List<?>> ignored = cursor) {
+                cursor.getAll();
+
+                if (checkCanceled)
+                    fail("Query not canceled");
+            }
+            catch (CacheException ex) {
+                error("Got expected exception", ex);
+
+                assertNotNull("Must throw correct exception", X.cause(ex, 
QueryCancelledException.class));
+            }
+
+            // Give some time to clean up.
+            Thread.sleep(TimeUnit.MILLISECONDS.convert(timeoutUnits, timeUnit) 
+ 3_000);
+
+            checkCleanState();
+        }
+    }
+
+    /**
+     * Validates clean state on all participating nodes after query 
cancellation.
+     */
+    private void checkCleanState() throws IgniteCheckedException {
+        for (int i = 0; i < GRIDS_CNT; i++) {
+            IgniteEx grid = grid(i);
+
+            // Validate everything was cleaned up.
+            ConcurrentMap<UUID, ?> map = 
U.field(((IgniteH2Indexing)U.field((GridProcessor)U.field(
+                grid.context(), "qryProc"), "idx")).mapQueryExecutor(), 
"qryRess");
+
+            String msg = "Map executor state is not cleared";
+
+            for (Object result : map.values()) {
+                Map<Long, ?> m = U.field(result, "res");
+
+                assertEquals(msg, 0, m.size());
+            }
+        }
+    }
+}
diff --git 
a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/local/IgniteCacheLocalQueryDefaultTimeoutSelfTest.java
 
b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/local/IgniteCacheLocalQueryDefaultTimeoutSelfTest.java
new file mode 100644
index 0000000..de80105
--- /dev/null
+++ 
b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/local/IgniteCacheLocalQueryDefaultTimeoutSelfTest.java
@@ -0,0 +1,152 @@
+/*
+ * 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.processors.cache.local;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.cache.query.QueryCancelledException;
+import org.apache.ignite.cache.query.QueryCursor;
+import org.apache.ignite.cache.query.SqlFieldsQuery;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.internal.util.typedef.X;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+import org.junit.Test;
+
+import static org.apache.ignite.cache.CacheMode.LOCAL;
+
+/**
+ * Tests local query default timeouts.
+ */
+public class IgniteCacheLocalQueryDefaultTimeoutSelfTest extends 
GridCommonAbstractTest {
+    /** Cache size. */
+    private static final int CACHE_SIZE = 10_000;
+
+    /** Default query timeout */
+    private static final long DEFAULT_QUERY_TIMEOUT = 1000;
+
+    /** */
+    private static final String QUERY = "select a._val, b._val from String a, 
String b";
+
+    /** {@inheritDoc} */
+    @Override protected IgniteConfiguration getConfiguration(String 
igniteInstanceName) throws Exception {
+        IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName);
+
+        CacheConfiguration<Integer, String> ccfg = new 
CacheConfiguration<>(DEFAULT_CACHE_NAME);
+        ccfg.setIndexedTypes(Integer.class, String.class);
+        ccfg.setCacheMode(LOCAL);
+
+        cfg.setCacheConfiguration(ccfg);
+        cfg.setDefaultQueryTimeout(DEFAULT_QUERY_TIMEOUT);
+
+        return cfg;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void beforeTestsStarted() throws Exception {
+        super.beforeTestsStarted();
+
+        startGrid(0);
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void afterTest() throws Exception {
+        super.afterTest();
+
+        grid(0).cache(DEFAULT_CACHE_NAME).removeAll();
+    }
+
+    /**
+     * @param cache Cache.
+     */
+    private void loadCache(IgniteCache<Integer, String> cache) {
+        int p = 1;
+
+        for (int i = 1; i <= CACHE_SIZE; i++) {
+            char[] tmp = new char[256];
+            Arrays.fill(tmp, ' ');
+            cache.put(i, new String(tmp));
+
+            if (i / (float)CACHE_SIZE >= p / 10f) {
+                log().info("Loaded " + i + " of " + CACHE_SIZE);
+
+                p++;
+            }
+        }
+    }
+
+    /**
+     * Tests query execution with default query timeout.
+     */
+    @Test
+    public void testQueryDefaultTimeout() {
+        testQuery(false, 1, TimeUnit.MILLISECONDS);
+    }
+
+    /**
+     * Tests query execution with query timeout.
+     */
+    @Test
+    public void testQueryTimeout() {
+        testQuery(true, 1, TimeUnit.SECONDS);
+    }
+
+    /**
+     * Tests cancellation.
+     */
+    private void testQuery(boolean timeout, int timeoutUnits, TimeUnit 
timeUnit) {
+        Ignite ignite = grid(0);
+
+        IgniteCache<Integer, String> cache = ignite.cache(DEFAULT_CACHE_NAME);
+
+        loadCache(cache);
+
+        SqlFieldsQuery qry = new SqlFieldsQuery(QUERY);
+
+        final QueryCursor<List<?>> cursor;
+        if (timeout) {
+            qry.setTimeout(timeoutUnits, timeUnit);
+
+            cursor = cache.query(qry);
+        }
+        else {
+            cursor = cache.query(qry);
+
+            ignite.scheduler().runLocal(new Runnable() {
+                @Override public void run() {
+                    cursor.close();
+                }
+            }, timeoutUnits, timeUnit);
+        }
+
+        try (QueryCursor<List<?>> ignored = cursor) {
+            cursor.iterator();
+
+            fail("Expecting timeout");
+        }
+        catch (Exception e) {
+            assertNotNull("Must throw correct exception", X.cause(e, 
QueryCancelledException.class));
+        }
+
+        // Test must exit gracefully.
+    }
+}
+
diff --git 
a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteBinaryCacheQueryTestSuite2.java
 
b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteBinaryCacheQueryTestSuite2.java
index 682fd8f..7100117 100644
--- 
a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteBinaryCacheQueryTestSuite2.java
+++ 
b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteBinaryCacheQueryTestSuite2.java
@@ -27,6 +27,7 @@ import 
org.apache.ignite.internal.processors.cache.IgniteCacheSqlQueryMultiThrea
 import 
org.apache.ignite.internal.processors.cache.QueryJoinWithDifferentNodeFiltersTest;
 import 
org.apache.ignite.internal.processors.cache.distributed.near.GridCachePartitionedTxMultiNodeSelfTest;
 import 
org.apache.ignite.internal.processors.cache.distributed.near.IgniteCacheClientQueryReplicatedNodeRestartSelfTest;
+import 
org.apache.ignite.internal.processors.cache.distributed.near.IgniteCacheDistributedQueryDefaultTimeoutSelfTest;
 import 
org.apache.ignite.internal.processors.cache.distributed.near.IgniteCacheDistributedQueryStopOnCancelOrTimeoutSelfTest;
 import 
org.apache.ignite.internal.processors.cache.distributed.near.IgniteCacheQueryNodeFailTest;
 import 
org.apache.ignite.internal.processors.cache.distributed.near.IgniteCacheQueryNodeRestartDistributedJoinSelfTest;
@@ -44,6 +45,7 @@ import 
org.apache.ignite.internal.processors.cache.index.DynamicIndexPartitioned
 import 
org.apache.ignite.internal.processors.cache.index.DynamicIndexPartitionedTransactionalConcurrentSelfTest;
 import 
org.apache.ignite.internal.processors.cache.index.DynamicIndexReplicatedAtomicConcurrentSelfTest;
 import 
org.apache.ignite.internal.processors.cache.index.DynamicIndexReplicatedTransactionalConcurrentSelfTest;
+import 
org.apache.ignite.internal.processors.cache.local.IgniteCacheLocalQueryDefaultTimeoutSelfTest;
 import 
org.apache.ignite.internal.processors.cache.query.ScanQueryOffheapExpiryPolicySelfTest;
 import 
org.apache.ignite.internal.processors.database.baseline.IgniteChangingBaselineCacheQueryNodeRestartSelfTest;
 import 
org.apache.ignite.internal.processors.database.baseline.IgniteStableBaselineCacheQueryNodeRestartsSelfTest;
@@ -109,6 +111,7 @@ import org.junit.runners.Suite;
     IgniteCacheSqlQueryMultiThreadedSelfTest.class,
     IgniteCachePartitionedQueryMultiThreadedSelfTest.class,
     CacheScanPartitionQueryFallbackSelfTest.class,
+    IgniteCacheDistributedQueryDefaultTimeoutSelfTest.class,
     IgniteCacheDistributedQueryStopOnCancelOrTimeoutSelfTest.class,
     IgniteCacheObjectKeyIndexingSelfTest.class,
 
@@ -148,7 +151,9 @@ import org.junit.runners.Suite;
     GridCachePartitionedTxMultiNodeSelfTest.class,
     GridCacheReplicatedTxMultiNodeBasicTest.class,
 
-    SqlPartOfComplexPkLookupTest.class
+    SqlPartOfComplexPkLookupTest.class,
+
+    IgniteCacheLocalQueryDefaultTimeoutSelfTest.class
 })
 public class IgniteBinaryCacheQueryTestSuite2 {
 }

Reply via email to