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

timoninmaxim 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 fb80a121a46 IGNITE-20943 Fix deserializing cache entries for 
IndexQuery on server (#11453)
fb80a121a46 is described below

commit fb80a121a46d866c3aec064401e5f8d95b91f8e9
Author: Maksim Timonin <[email protected]>
AuthorDate: Thu Jul 25 10:48:20 2024 +0300

    IGNITE-20943 Fix deserializing cache entries for IndexQuery on server 
(#11453)
---
 .../client/cache/ClientCacheIndexQueryRequest.java |   3 +-
 .../ThinClientQueryTestApplication.java            | 164 +++++++++++++++++++++
 .../ignitetest/tests/thin_client_query_test.py     |  95 ++++++++++++
 3 files changed, 261 insertions(+), 1 deletion(-)

diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheIndexQueryRequest.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheIndexQueryRequest.java
index db86541fbb8..9d1a29cb730 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheIndexQueryRequest.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheIndexQueryRequest.java
@@ -155,7 +155,8 @@ public class ClientCacheIndexQueryRequest extends 
ClientCacheQueryRequest {
      * {@inheritDoc}
      */
     @Override public ClientResponse process(ClientConnectionContext ctx) {
-        IgniteCache<Object, Object> cache = !isKeepBinary() ? rawCache(ctx) : 
cache(ctx);
+        IgniteCache<Object, Object> cache = qry.getFilter() != null && 
!isKeepBinary() ?
+            rawCache(ctx) : cache(ctx);
 
         if (qry.getPartition() != null)
             updateAffinityMetrics(ctx, qry.getPartition());
diff --git 
a/modules/ducktests/src/main/java/org/apache/ignite/internal/ducktest/tests/thin_client_query_test/ThinClientQueryTestApplication.java
 
b/modules/ducktests/src/main/java/org/apache/ignite/internal/ducktest/tests/thin_client_query_test/ThinClientQueryTestApplication.java
new file mode 100644
index 00000000000..6581ceefc0f
--- /dev/null
+++ 
b/modules/ducktests/src/main/java/org/apache/ignite/internal/ducktest/tests/thin_client_query_test/ThinClientQueryTestApplication.java
@@ -0,0 +1,164 @@
+/*
+ * 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.ducktest.tests.thin_client_query_test;
+
+import java.util.LinkedHashMap;
+import java.util.List;
+import javax.cache.Cache;
+import com.fasterxml.jackson.databind.JsonNode;
+import org.apache.ignite.binary.BinaryObject;
+import org.apache.ignite.cache.QueryEntity;
+import org.apache.ignite.cache.QueryIndex;
+import org.apache.ignite.cache.query.IndexQuery;
+import org.apache.ignite.cache.query.ScanQuery;
+import org.apache.ignite.client.ClientCache;
+import org.apache.ignite.client.ClientCacheConfiguration;
+import org.apache.ignite.internal.ducktest.utils.IgniteAwareApplication;
+import org.apache.ignite.internal.util.typedef.F;
+
+/** Tests cache queries for thin client. */
+public class ThinClientQueryTestApplication extends IgniteAwareApplication {
+    /** */
+    private static final int CNT = 100;
+
+    /** */
+    @Override protected void run(JsonNode jsonNode) throws Exception {
+        markInitialized();
+
+        QueryEntity qe = new QueryEntity(Integer.class, EntityValue.class)
+            .setValueType(EntityValue.class.getName())
+            .setFields(new LinkedHashMap<>(F.asMap("val", 
Integer.class.getName())))
+            .setIndexes(F.asList(new QueryIndex("val", 
false).setName("VAL_IDX")));
+
+        ClientCacheConfiguration clnCacheCfg = new ClientCacheConfiguration()
+            .setName("testCache")
+            .setQueryEntities(qe);
+
+        ClientCache<Integer, EntityValue> cache = 
client.createCache(clnCacheCfg);
+
+        for (int i = 0; i < CNT; i++)
+            cache.put(i, new EntityValue(i));
+
+        boolean filter = jsonNode.get("filter").asBoolean();
+
+        testIndexQuery(cache, filter);
+        testBinaryIndexQuery(cache, filter);
+        testScanQuery(cache, filter);
+        testBinaryScanQuery(cache, filter);
+
+        markFinished();
+    }
+
+    /** */
+    private void testIndexQuery(ClientCache<Integer, EntityValue> cache, 
boolean filter) {
+        IndexQuery<Integer, EntityValue> idxQry = new 
IndexQuery<>(EntityValue.class.getName(), "VAL_IDX");
+
+        if (filter)
+            idxQry.setFilter((k, v) -> v.val < CNT / 2);
+
+        List<Cache.Entry<Integer, EntityValue>> result = 
cache.query(idxQry).getAll();
+
+        int cnt = filter ? CNT / 2 : CNT;
+
+        assert result.size() == cnt;
+
+        for (int i = 0; i < cnt; i++) {
+            Cache.Entry<Integer, EntityValue> e = result.get(i);
+
+            assert e.getKey() == i;
+            assert e.getValue().val == i;
+        }
+    }
+
+    /** */
+    private void testBinaryIndexQuery(ClientCache<Integer, EntityValue> cache, 
boolean filter) {
+        IndexQuery<Integer, BinaryObject> idxQry = new 
IndexQuery<>(EntityValue.class.getName(), "VAL_IDX");
+
+        if (filter)
+            idxQry.setFilter((k, v) -> (int)v.field("val") < CNT / 2);
+
+        List<Cache.Entry<Integer, BinaryObject>> result = 
cache.withKeepBinary().query(idxQry).getAll();
+
+        int cnt = filter ? CNT / 2 : CNT;
+
+        assert result.size() == cnt;
+
+        for (int i = 0; i < cnt; i++) {
+            Cache.Entry<Integer, BinaryObject> e = result.get(i);
+
+            assert e.getKey() == i;
+            assert (int)e.getValue().field("val") == i;
+        }
+    }
+
+    /** */
+    private void testScanQuery(ClientCache<Integer, EntityValue> cache, 
boolean filter) {
+        ScanQuery<Integer, EntityValue> scanQry = new ScanQuery<>();
+
+        if (filter)
+            scanQry.setFilter((k, v) -> v.val < CNT / 2);
+
+        List<Cache.Entry<Integer, EntityValue>> result = 
cache.query(scanQry).getAll();
+
+        int cnt = filter ? CNT / 2 : CNT;
+
+        assert result.size() == cnt;
+
+        for (int i = 0; i < cnt; i++) {
+            Cache.Entry<Integer, EntityValue> e = result.get(i);
+
+            assert e.getKey() == e.getValue().val;
+        }
+    }
+
+    /** */
+    private void testBinaryScanQuery(ClientCache<Integer, EntityValue> cache, 
boolean filter) {
+        ScanQuery<Integer, BinaryObject> scanQry = new ScanQuery<>();
+
+        if (filter)
+            scanQry.setFilter((k, v) -> (int)v.field("val") < CNT / 2);
+
+        List<Cache.Entry<Integer, BinaryObject>> result = 
cache.withKeepBinary().query(scanQry).getAll();
+
+        int cnt = filter ? CNT / 2 : CNT;
+
+        assert result.size() == cnt;
+
+        for (int i = 0; i < cnt; i++) {
+            Cache.Entry<Integer, BinaryObject> e = result.get(i);
+
+            assert e.getKey() == e.getValue().field("val");
+        }
+    }
+
+    /** */
+    private static class EntityValue {
+        /** */
+        private final int val;
+
+        /** */
+        public EntityValue(int val) {
+            this.val = val;
+        }
+
+        /** */
+        public String toString() {
+            return "EntityValue [val=" + val + "]";
+        }
+    }
+}
diff --git a/modules/ducktests/tests/ignitetest/tests/thin_client_query_test.py 
b/modules/ducktests/tests/ignitetest/tests/thin_client_query_test.py
new file mode 100644
index 00000000000..e008878159a
--- /dev/null
+++ b/modules/ducktests/tests/ignitetest/tests/thin_client_query_test.py
@@ -0,0 +1,95 @@
+# 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.
+
+"""
+This module contains client queries tests.
+"""
+from ducktape.mark import matrix
+
+from ignitetest.services.ignite import IgniteService
+from ignitetest.services.ignite_app import IgniteApplicationService
+from ignitetest.services.utils.ignite_configuration import 
IgniteConfiguration, IgniteThinClientConfiguration
+from ignitetest.services.utils.ignite_spec import IgniteNodeSpec
+from ignitetest.services.utils.ssl.client_connector_configuration import 
ClientConnectorConfiguration
+from ignitetest.utils import cluster, ignite_versions
+from ignitetest.utils.ignite_test import IgniteTest
+from ignitetest.utils.version import DEV_BRANCH, IgniteVersion
+
+
+class ThinClientQueryTest(IgniteTest):
+    """
+    cluster - cluster size.
+    JAVA_CLIENT_CLASS_NAME - running classname.
+    to use with ssl enabled:
+    export GLOBALS='{"ssl":{"enabled":true}}' .
+    """
+    @cluster(num_nodes=3)
+    @ignite_versions(str(DEV_BRANCH), version_prefix="server_version")
+    @matrix(filter=[False, True])
+    def test_thin_client_index_query(self, server_version, filter):
+        """
+        Thin client IndexQuery test.
+        :param server_version Ignite node version.
+        :param filter Whether to use filter for queries.
+        """
+
+        server_config = 
IgniteConfiguration(version=IgniteVersion(server_version),
+                                            
client_connector_configuration=ClientConnectorConfiguration())
+
+        ignite = IgniteService(self.test_context, server_config, 2)
+
+        if not filter:
+            ignite.spec = IgniteNodeSpecExcludeDucktests(service=ignite)
+
+        addresses = [ignite.nodes[0].account.hostname + ":" + 
str(server_config.client_connector_configuration.port)]
+
+        cls = 
"org.apache.ignite.internal.ducktest.tests.thin_client_query_test.ThinClientQueryTestApplication"
+
+        thin_clients = IgniteApplicationService(self.test_context,
+                                                IgniteThinClientConfiguration(
+                                                    addresses=addresses,
+                                                    
version=IgniteVersion(str(DEV_BRANCH))),
+                                                java_class_name=cls,
+                                                num_nodes=1,
+                                                params={"filter": filter})
+
+        ignite.start()
+        thin_clients.run()
+        ignite.stop()
+
+
+class IgniteNodeSpecExcludeDucktests(IgniteNodeSpec):
+    """
+    Ignite node specification that excludes module 'ducktests' from classpath.
+    """
+    def modules(self):
+        """
+        Exclude module from preparing USER_LIBS environment variable.
+        """
+        modules = super().modules()
+
+        modules.remove("ducktests")
+
+        return modules
+
+    def envs(self):
+        """
+        Skip the module target directory while building classpath.
+        """
+        envs = super().envs()
+
+        envs["EXCLUDE_MODULES"] = "ducktests"
+
+        return envs

Reply via email to