IGNITE-9487 Introduce IGNITE_REST_GETALL_AS_ARRAY to change getall output format. - Fixes #4756.
Signed-off-by: Alexey Kuznetsov <akuznet...@apache.org> Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/390c6a8c Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/390c6a8c Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/390c6a8c Branch: refs/heads/ignite-7251 Commit: 390c6a8cc94b9cdbaeaf3623e81f2c85a5222d45 Parents: 4b00242 Author: Ilya Kasnacheev <ilya.kasnach...@gmail.com> Authored: Mon Sep 17 20:07:59 2018 +0700 Committer: Alexey Kuznetsov <akuznet...@apache.org> Committed: Mon Sep 17 20:07:59 2018 +0700 ---------------------------------------------------------------------- .../client/suite/IgniteClientTestSuite.java | 4 + .../JettyRestProcessorGetAllAsArrayTest.java | 84 ++++++++++++++++++++ .../redis/RedisProtocolGetAllAsArrayTest.java | 39 +++++++++ .../apache/ignite/IgniteSystemProperties.java | 10 +++ .../http/jetty/GridJettyRestHandler.java | 16 ++++ 5 files changed, 153 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/390c6a8c/modules/clients/src/test/java/org/apache/ignite/internal/client/suite/IgniteClientTestSuite.java ---------------------------------------------------------------------- diff --git a/modules/clients/src/test/java/org/apache/ignite/internal/client/suite/IgniteClientTestSuite.java b/modules/clients/src/test/java/org/apache/ignite/internal/client/suite/IgniteClientTestSuite.java index 94b553b..657fda4 100644 --- a/modules/clients/src/test/java/org/apache/ignite/internal/client/suite/IgniteClientTestSuite.java +++ b/modules/clients/src/test/java/org/apache/ignite/internal/client/suite/IgniteClientTestSuite.java @@ -53,6 +53,7 @@ import org.apache.ignite.internal.processors.rest.ChangeStateCommandHandlerTest; import org.apache.ignite.internal.processors.rest.ClientMemcachedProtocolSelfTest; import org.apache.ignite.internal.processors.rest.JettyRestProcessorAuthenticationWithCredsSelfTest; import org.apache.ignite.internal.processors.rest.JettyRestProcessorAuthenticationWithTokenSelfTest; +import org.apache.ignite.internal.processors.rest.JettyRestProcessorGetAllAsArrayTest; import org.apache.ignite.internal.processors.rest.JettyRestProcessorSignedSelfTest; import org.apache.ignite.internal.processors.rest.JettyRestProcessorUnsignedSelfTest; import org.apache.ignite.internal.processors.rest.RestBinaryProtocolSelfTest; @@ -63,6 +64,7 @@ import org.apache.ignite.internal.processors.rest.TaskCommandHandlerSelfTest; import org.apache.ignite.internal.processors.rest.TcpRestUnmarshalVulnerabilityTest; import org.apache.ignite.internal.processors.rest.protocols.tcp.TcpRestParserSelfTest; import org.apache.ignite.internal.processors.rest.protocols.tcp.redis.RedisProtocolConnectSelfTest; +import org.apache.ignite.internal.processors.rest.protocols.tcp.redis.RedisProtocolGetAllAsArrayTest; import org.apache.ignite.internal.processors.rest.protocols.tcp.redis.RedisProtocolServerSelfTest; import org.apache.ignite.internal.processors.rest.protocols.tcp.redis.RedisProtocolStringSelfTest; import org.apache.ignite.testframework.IgniteTestSuite; @@ -94,12 +96,14 @@ public class IgniteClientTestSuite extends TestSuite { suite.addTestSuite(JettyRestProcessorUnsignedSelfTest.class); suite.addTestSuite(JettyRestProcessorAuthenticationWithCredsSelfTest.class); suite.addTestSuite(JettyRestProcessorAuthenticationWithTokenSelfTest.class); + suite.addTestSuite(JettyRestProcessorGetAllAsArrayTest.class); // Test TCP rest processor with original memcache client. suite.addTestSuite(ClientMemcachedProtocolSelfTest.class); // Test TCP rest processor with original REDIS client. suite.addTestSuite(RedisProtocolStringSelfTest.class); + suite.addTestSuite(RedisProtocolGetAllAsArrayTest.class); suite.addTestSuite(RedisProtocolConnectSelfTest.class); suite.addTestSuite(RedisProtocolServerSelfTest.class); http://git-wip-us.apache.org/repos/asf/ignite/blob/390c6a8c/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorGetAllAsArrayTest.java ---------------------------------------------------------------------- diff --git a/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorGetAllAsArrayTest.java b/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorGetAllAsArrayTest.java new file mode 100644 index 0000000..521d7c1 --- /dev/null +++ b/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorGetAllAsArrayTest.java @@ -0,0 +1,84 @@ +/* + * 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.rest; + +import com.fasterxml.jackson.databind.JsonNode; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import org.apache.ignite.internal.util.typedef.F; + +import static org.apache.ignite.IgniteSystemProperties.IGNITE_REST_GETALL_AS_ARRAY; +import static org.apache.ignite.internal.processors.rest.GridRestResponse.STATUS_SUCCESS; + +/** */ +public class JettyRestProcessorGetAllAsArrayTest extends JettyRestProcessorCommonSelfTest { + /** {@inheritDoc} */ + @Override protected void beforeTestsStarted() throws Exception { + System.setProperty(IGNITE_REST_GETALL_AS_ARRAY, "true"); + + super.beforeTestsStarted(); + } + + /** {@inheritDoc} */ + @Override protected void afterTestsStopped() throws Exception { + super.afterTestsStopped(); + + System.clearProperty(IGNITE_REST_GETALL_AS_ARRAY); + } + + /** + * @throws Exception If failed. + */ + public void testGetAll() throws Exception { + final Map<String, String> entries = F.asMap("getKey1", "getVal1", "getKey2", "getVal2"); + + jcache().putAll(entries); + + String ret = content(DEFAULT_CACHE_NAME, GridRestCommand.CACHE_GET_ALL, + "k1", "getKey1", + "k2", "getKey2" + ); + + info("Get all command result: " + ret); + + assertNotNull(ret); + assertFalse(ret.isEmpty()); + + JsonNode node = JSON_MAPPER.readTree(ret); + + assertEquals(STATUS_SUCCESS, node.get("successStatus").asInt()); + assertTrue(node.get("error").isNull()); + + JsonNode res = node.get("response"); + + assertTrue(res.isArray()); + + Set<Map<String, String>> returnValue = new HashSet<>(); + + returnValue.add(F.asMap("key", "getKey1", "value", "getVal1")); + returnValue.add(F.asMap("key", "getKey2", "value", "getVal2")); + + assertEquals(returnValue, JSON_MAPPER.treeToValue(res, Set.class)); + } + + /** {@inheritDoc} */ + @Override protected String signature() { + return null; + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/390c6a8c/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/protocols/tcp/redis/RedisProtocolGetAllAsArrayTest.java ---------------------------------------------------------------------- diff --git a/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/protocols/tcp/redis/RedisProtocolGetAllAsArrayTest.java b/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/protocols/tcp/redis/RedisProtocolGetAllAsArrayTest.java new file mode 100644 index 0000000..f892ca5 --- /dev/null +++ b/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/protocols/tcp/redis/RedisProtocolGetAllAsArrayTest.java @@ -0,0 +1,39 @@ +/* + * 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.rest.protocols.tcp.redis; + +import org.apache.ignite.IgniteSystemProperties; + +/** + * Test for being unaffected by {@link IgniteSystemProperties#IGNITE_REST_GETALL_AS_ARRAY}. + */ +public class RedisProtocolGetAllAsArrayTest extends RedisProtocolStringSelfTest { + /** {@inheritDoc} */ + @Override protected void beforeTestsStarted() throws Exception { + System.setProperty(IgniteSystemProperties.IGNITE_REST_GETALL_AS_ARRAY, "true"); + + super.beforeTestsStarted(); + } + + /** {@inheritDoc} */ + @Override protected void afterTestsStopped() throws Exception { + super.afterTestsStopped(); + + System.clearProperty(IgniteSystemProperties.IGNITE_REST_GETALL_AS_ARRAY); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/390c6a8c/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java b/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java index 00ab49a..9e21814 100644 --- a/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java +++ b/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java @@ -29,6 +29,7 @@ import org.apache.ignite.configuration.CacheConfiguration; import org.apache.ignite.configuration.DataStorageConfiguration; import org.apache.ignite.internal.client.GridClient; import org.apache.ignite.internal.marshaller.optimized.OptimizedMarshaller; +import org.apache.ignite.internal.processors.rest.GridRestCommand; import org.apache.ignite.internal.util.GridLogThrottle; import org.apache.ignite.stream.StreamTransformer; import org.jetbrains.annotations.Nullable; @@ -137,6 +138,15 @@ public final class IgniteSystemProperties { public static final String IGNITE_REST_START_ON_CLIENT = "IGNITE_REST_START_ON_CLIENT"; /** + * This property changes output format of {@link GridRestCommand#CACHE_GET_ALL} from {k: v, ...} + * to [{"key": k, "value": v}, ...] to allow non-string keys output. + * + * @deprecated Should be made default in Apache Ignite 3.0. + */ + @Deprecated + public static final String IGNITE_REST_GETALL_AS_ARRAY = "IGNITE_REST_GETALL_AS_ARRAY"; + + /** * This property defines the maximum number of attempts to remap near get to the same * primary node. Remapping may be needed when topology is changed concurrently with * get operation. http://git-wip-us.apache.org/repos/asf/ignite/blob/390c6a8c/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyRestHandler.java ---------------------------------------------------------------------- diff --git a/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyRestHandler.java b/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyRestHandler.java index 729016b..12dc0dd 100644 --- a/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyRestHandler.java +++ b/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyRestHandler.java @@ -29,6 +29,7 @@ import java.nio.charset.StandardCharsets; import java.sql.Date; import java.sql.Time; import java.sql.Timestamp; +import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.LinkedList; @@ -42,6 +43,7 @@ import javax.servlet.http.HttpServletResponse; import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.IgniteLogger; +import org.apache.ignite.IgniteSystemProperties; import org.apache.ignite.cache.CacheWriteSynchronizationMode; import org.apache.ignite.internal.processors.cache.CacheConfigurationOverride; import org.apache.ignite.internal.processors.rest.GridRestCommand; @@ -58,6 +60,7 @@ import org.apache.ignite.internal.processors.rest.request.RestQueryRequest; import org.apache.ignite.internal.processors.rest.request.RestUserActionRequest; import org.apache.ignite.internal.util.typedef.F; import org.apache.ignite.internal.util.typedef.internal.U; +import org.apache.ignite.lang.IgniteBiTuple; import org.apache.ignite.lang.IgniteClosure; import org.apache.ignite.lang.IgniteUuid; import org.apache.ignite.plugin.security.SecurityCredentials; @@ -68,6 +71,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import org.jetbrains.annotations.Nullable; +import static org.apache.ignite.IgniteSystemProperties.IGNITE_REST_GETALL_AS_ARRAY; import static org.apache.ignite.internal.client.GridClientCacheFlag.KEEP_BINARIES_MASK; import static org.apache.ignite.internal.processors.rest.GridRestCommand.CACHE_CONTAINS_KEYS; import static org.apache.ignite.internal.processors.rest.GridRestCommand.CACHE_GET_ALL; @@ -136,6 +140,9 @@ public class GridJettyRestHandler extends AbstractHandler { /** Mapper from Java object to JSON. */ private final ObjectMapper jsonMapper; + /** */ + private final boolean getAllAsArray = IgniteSystemProperties.getBoolean(IGNITE_REST_GETALL_AS_ARRAY); + /** * Creates new HTTP requests handler. * @@ -391,6 +398,15 @@ public class GridJettyRestHandler extends AbstractHandler { if (cmdRes == null) throw new IllegalStateException("Received null result from handler: " + hnd); + if (getAllAsArray && cmd == GridRestCommand.CACHE_GET_ALL) { + List<Object> resKeyValue = new ArrayList<>(); + + for (Map.Entry<Object, Object> me : ((Map<Object, Object>)cmdRes.getResponse()).entrySet()) + resKeyValue.add(new IgniteBiTuple<>(me.getKey(), me.getValue())); + + cmdRes.setResponse(resKeyValue); + } + byte[] sesTok = cmdRes.sessionTokenBytes(); if (sesTok != null)