You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by an...@apache.org on 2016/06/16 07:44:09 UTC

[1/2] ignite git commit: IGNITE-3277 Migrated rest-http from outdated json-lib to Jackson v2.

Repository: ignite
Updated Branches:
  refs/heads/ignite-3277 [created] 73689ae5d


http://git-wip-us.apache.org/repos/asf/ignite/blob/73689ae5/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheV4.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheV4.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheV4.java
new file mode 100644
index 0000000..81dbacb
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheV4.java
@@ -0,0 +1,124 @@
+/*
+ * 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.visor.cache;
+
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.internal.IgniteEx;
+import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
+import org.apache.ignite.internal.processors.cache.GridCacheAdapter;
+import org.apache.ignite.internal.processors.cache.GridCacheSwapManager;
+import org.apache.ignite.internal.util.typedef.internal.S;
+
+/**
+ * Data transfer object for {@link IgniteCache}.
+ */
+public class VisorCacheV4 extends VisorCacheV2 {
+    /** */
+    private static final long serialVersionUID = 0L;
+
+    /** Number of primary entries in offheap. */
+    private int offHeapPrimaryEntriesCnt;
+
+    /** Number of backup entries in offheap. */
+    private int offHeapBackupEntriesCnt;
+
+    /** Number of primary entries in swap. */
+    private int swapPrimaryEntriesCnt;
+
+    /** Number of backup entries in swap. */
+    private int swapBackupEntriesCnt;
+
+    /** {@inheritDoc} */
+    @Override public VisorCache from(IgniteEx ignite, String cacheName, int sample) throws IgniteCheckedException {
+        VisorCache c = super.from(ignite, cacheName, sample);
+
+        if (c != null && c instanceof VisorCacheV4) {
+            VisorCacheV4 cacheV4 = (VisorCacheV4)c;
+
+            GridCacheAdapter ca = ignite.context().cache().internalCache(cacheName);
+
+            // Process only started caches.
+            if (ca != null && ca.context().started()) {
+                GridCacheSwapManager swap = ca.context().swap();
+
+                cacheV4.offHeapPrimaryEntriesCnt = swap.offheapEntriesCount(true, false, AffinityTopologyVersion.NONE);
+                cacheV4.offHeapBackupEntriesCnt = swap.offheapEntriesCount(false, true, AffinityTopologyVersion.NONE);
+
+                cacheV4.swapPrimaryEntriesCnt = swap.swapEntriesCount(true, false, AffinityTopologyVersion.NONE);
+                cacheV4.swapBackupEntriesCnt = swap.swapEntriesCount(false, true, AffinityTopologyVersion.NONE);
+            }
+        }
+
+        return c;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected VisorCache initHistory(VisorCache c) {
+        super.initHistory(c);
+
+        if (c instanceof VisorCacheV4) {
+            VisorCacheV4 cacheV4 = (VisorCacheV4)c;
+
+            cacheV4.offHeapPrimaryEntriesCnt = offHeapPrimaryEntriesCnt;
+            cacheV4.offHeapBackupEntriesCnt = offHeapBackupEntriesCnt;
+            cacheV4.swapPrimaryEntriesCnt = swapPrimaryEntriesCnt;
+            cacheV4.swapBackupEntriesCnt = swapBackupEntriesCnt;
+        }
+
+        return c;
+    }
+
+    /** {@inheritDoc} */
+    @Override public VisorCache history() {
+        return initHistory(new VisorCacheV3());
+    }
+
+    /**
+     * @return Off-heap heap primary entries count.
+     */
+    public int offHeapPrimaryEntriesCount() {
+        return offHeapPrimaryEntriesCnt;
+    }
+
+    /**
+     * @return Off-heap heap backup entries count.
+     */
+    public int offHeapBackupEntriesCount() {
+        return offHeapBackupEntriesCnt;
+    }
+
+    /**
+     * @return Swap primary entries count.
+     */
+    public int swapPrimaryEntriesCount() {
+        return swapPrimaryEntriesCnt;
+    }
+
+    /**
+     * @return Swap backup entries count.
+     */
+    public int swapBackupEntriesCount() {
+        return swapBackupEntriesCnt;
+    }
+
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        return S.toString(VisorCacheV4.class, this);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/73689ae5/modules/core/src/main/java/org/apache/ignite/internal/visor/node/VisorNodeDataCollectorJob.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/node/VisorNodeDataCollectorJob.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/node/VisorNodeDataCollectorJob.java
index 79760ef..7646cb9 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/visor/node/VisorNodeDataCollectorJob.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/node/VisorNodeDataCollectorJob.java
@@ -31,6 +31,7 @@ import org.apache.ignite.internal.visor.VisorJob;
 import org.apache.ignite.internal.visor.cache.VisorCache;
 import org.apache.ignite.internal.visor.cache.VisorCacheV2;
 import org.apache.ignite.internal.visor.cache.VisorCacheV3;
+import org.apache.ignite.internal.visor.cache.VisorCacheV4;
 import org.apache.ignite.internal.visor.compute.VisorComputeMonitoringHolder;
 import org.apache.ignite.internal.visor.igfs.VisorIgfs;
 import org.apache.ignite.internal.visor.igfs.VisorIgfsEndpoint;
@@ -57,6 +58,9 @@ public class VisorNodeDataCollectorJob extends VisorJob<VisorNodeDataCollectorTa
     /** */
     private static final IgniteProductVersion VER_1_5_9 = IgniteProductVersion.fromString("1.5.9");
 
+    /** */
+    private static final IgniteProductVersion VER_1_5_25 = IgniteProductVersion.fromString("1.5.25");
+
     /**
      * Create job with given argument.
      *
@@ -125,7 +129,7 @@ public class VisorNodeDataCollectorJob extends VisorJob<VisorNodeDataCollectorTa
 
     /**
      * @param ver Version to check.
-     * @return {@code true} if compatible.
+     * @return {@code true} if found at least one compatible node with specified version.
      */
     private boolean compatibleWith(IgniteProductVersion ver) {
         for (ClusterNode node : ignite.cluster().nodes())
@@ -136,6 +140,22 @@ public class VisorNodeDataCollectorJob extends VisorJob<VisorNodeDataCollectorTa
     }
 
     /**
+     * @return Compatible {@link VisorCache} instance.
+     */
+    private VisorCache createVisorCache() {
+        if (compatibleWith(VER_1_4_1))
+            return new VisorCache();
+
+        if (compatibleWith(VER_1_5_9))
+            return new VisorCacheV2();
+
+        if (compatibleWith(VER_1_5_25))
+            return new VisorCacheV3();
+
+        return new VisorCacheV4();
+    }
+
+    /**
      * Collect caches.
      *
      * @param res Job result.
@@ -152,9 +172,7 @@ public class VisorNodeDataCollectorJob extends VisorJob<VisorNodeDataCollectorTa
                     long start0 = U.currentTimeMillis();
 
                     try {
-                        VisorCache cache = (compatibleWith(VER_1_4_1) ? new VisorCache() :
-                                compatibleWith(VER_1_5_9) ? new VisorCacheV2() : new VisorCacheV3())
-                                    .from(ignite, cacheName, arg.sample());
+                        VisorCache cache = createVisorCache().from(ignite, cacheName, arg.sample());
 
                         if (cache != null)
                             res.caches().add(cache);

http://git-wip-us.apache.org/repos/asf/ignite/blob/73689ae5/modules/rest-http/pom.xml
----------------------------------------------------------------------
diff --git a/modules/rest-http/pom.xml b/modules/rest-http/pom.xml
index c97d670..b535dda 100644
--- a/modules/rest-http/pom.xml
+++ b/modules/rest-http/pom.xml
@@ -97,28 +97,15 @@
         </dependency>
 
         <dependency>
-            <groupId>net.sf.json-lib</groupId>
-            <artifactId>json-lib</artifactId>
-            <version>${jsonlib.version}</version>
-            <classifier>jdk15</classifier>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-core</artifactId>
+            <version>${jackson2.version}</version>
         </dependency>
 
         <dependency>
-            <groupId>net.sf.ezmorph</groupId>
-            <artifactId>ezmorph</artifactId>
-            <version>${ezmorph.version}</version>
-        </dependency>
-
-        <dependency>
-            <groupId>commons-collections</groupId>
-            <artifactId>commons-collections</artifactId>
-            <version>${commons.collections.version}</version>
-        </dependency>
-
-        <dependency>
-            <groupId>commons-beanutils</groupId>
-            <artifactId>commons-beanutils</artifactId>
-            <version>${commons.beanutils.version}</version>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-databind</artifactId>
+            <version>${jackson2.version}</version>
         </dependency>
 
         <dependency>

http://git-wip-us.apache.org/repos/asf/ignite/blob/73689ae5/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyJsonConfig.java
----------------------------------------------------------------------
diff --git a/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyJsonConfig.java b/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyJsonConfig.java
deleted file mode 100644
index c2795a4..0000000
--- a/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyJsonConfig.java
+++ /dev/null
@@ -1,317 +0,0 @@
-/*
- * 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.http.jetty;
-
-import java.lang.reflect.Method;
-import java.text.DateFormat;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Set;
-import java.util.UUID;
-import java.util.concurrent.locks.ReadWriteLock;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
-import net.sf.json.JSONObject;
-import net.sf.json.JsonConfig;
-import net.sf.json.processors.JsonBeanProcessor;
-import net.sf.json.processors.JsonBeanProcessorMatcher;
-import net.sf.json.processors.JsonValueProcessor;
-import net.sf.json.processors.JsonValueProcessorMatcher;
-import org.apache.ignite.IgniteLogger;
-import org.apache.ignite.internal.processors.cache.query.GridCacheSqlIndexMetadata;
-import org.apache.ignite.internal.processors.cache.query.GridCacheSqlMetadata;
-import org.apache.ignite.internal.util.typedef.internal.U;
-import org.apache.ignite.internal.visor.cache.VisorCache;
-import org.apache.ignite.lang.IgniteBiTuple;
-import org.apache.ignite.lang.IgniteUuid;
-
-/**
- * Jetty protocol json configuration.
- */
-class GridJettyJsonConfig extends JsonConfig {
-    /** Logger. */
-    private final IgniteLogger log;
-
-    /**
-     * Class for finding a matching JsonBeanProcessor.
-     */
-    private static final JsonBeanProcessorMatcher LESS_NAMING_BEAN_MATCHER = new JsonBeanProcessorMatcher() {
-        /** {@inheritDoc} */
-        @Override public Object getMatch(Class target, Set keys) {
-            return GridJettyJsonConfig.getMatch(target, keys);
-        }
-    };
-
-    /**
-     * Class for finding a matching JsonValueProcessor.
-     */
-    private static final JsonValueProcessorMatcher LESS_NAMING_VALUE_MATCHER = new JsonValueProcessorMatcher() {
-        /** {@inheritDoc} */
-        @Override public Object getMatch(Class target, Set keys) {
-            return GridJettyJsonConfig.getMatch(target, keys);
-        }
-    };
-
-    /**
-     * Helper class for simple to-string conversion for {@link UUID}.
-     */
-    private static JsonValueProcessor UUID_PROCESSOR = new JsonValueProcessor() {
-        /** {@inheritDoc} */
-        @Override public Object processArrayValue(Object val, JsonConfig jsonCfg) {
-            if (val == null)
-                return new JSONObject(true);
-
-            if (val instanceof UUID)
-                return val.toString();
-
-            throw new UnsupportedOperationException("Serialize value to json is not supported: " + val);
-        }
-
-        /** {@inheritDoc} */
-        @Override public Object processObjectValue(String key, Object val, JsonConfig jsonCfg) {
-            return processArrayValue(val, jsonCfg);
-        }
-    };
-
-    /**
-     * Helper class for simple to-string conversion for {@link UUID}.
-     */
-    private static JsonValueProcessor IGNITE_BI_TUPLE_PROCESSOR = new JsonValueProcessor() {
-        /** {@inheritDoc} */
-        @Override public Object processArrayValue(Object val, JsonConfig jsonCfg) {
-            if (val == null)
-                return new JSONObject(true);
-
-            if (val instanceof IgniteBiTuple) {
-                IgniteBiTuple t2 = (IgniteBiTuple)val;
-
-                final JSONObject ret = new JSONObject();
-
-                ret.element("key", t2.getKey(), jsonCfg);
-                ret.element("value", t2.getValue(), jsonCfg);
-
-                return ret;
-            }
-
-            throw new UnsupportedOperationException("Serialize value to json is not supported: " + val);
-        }
-
-        /** {@inheritDoc} */
-        @Override public Object processObjectValue(String key, Object val, JsonConfig jsonCfg) {
-            return processArrayValue(val, jsonCfg);
-        }
-    };
-
-    /**
-     * Helper class for simple to-string conversion for {@link IgniteUuid}.
-     */
-    private static JsonValueProcessor IGNITE_UUID_PROCESSOR = new JsonValueProcessor() {
-        /** {@inheritDoc} */
-        @Override public Object processArrayValue(Object val, JsonConfig jsonCfg) {
-            if (val == null)
-                return new JSONObject(true);
-
-            if (val instanceof IgniteUuid)
-                return val.toString();
-
-            throw new UnsupportedOperationException("Serialize value to json is not supported: " + val);
-        }
-
-        /** {@inheritDoc} */
-        @Override public Object processObjectValue(String key, Object val, JsonConfig jsonCfg) {
-            return processArrayValue(val, jsonCfg);
-        }
-    };
-
-    /**
-     * Helper class for simple to-string conversion for {@link Date}.
-     */
-    private static JsonValueProcessor DATE_PROCESSOR = new JsonValueProcessor() {
-        /** Thread local US date format. */
-        private final ThreadLocal<DateFormat> dateFmt = new ThreadLocal<DateFormat>() {
-            @Override protected DateFormat initialValue() {
-                return DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT, Locale.US);
-            }
-        };
-
-        /** {@inheritDoc} */
-        @Override public synchronized Object processArrayValue(Object val, JsonConfig jsonCfg) {
-            if (val == null)
-                return new JSONObject(true);
-
-            if (val instanceof Date)
-                return dateFmt.get().format(val);
-
-            throw new UnsupportedOperationException("Serialize value to json is not supported: " + val);
-        }
-
-        /** {@inheritDoc} */
-        @Override public synchronized Object processObjectValue(String key, Object val, JsonConfig jsonCfg) {
-            return processArrayValue(val, jsonCfg);
-        }
-    };
-
-    /**
-     * Constructs default jetty json config.
-     */
-    GridJettyJsonConfig(IgniteLogger log) {
-        this.log = log;
-
-        setAllowNonStringKeys(true);
-
-        registerJsonValueProcessor(IgniteBiTuple.class, IGNITE_BI_TUPLE_PROCESSOR);
-        registerJsonValueProcessor(UUID.class, UUID_PROCESSOR);
-        registerJsonValueProcessor(IgniteUuid.class, IGNITE_UUID_PROCESSOR);
-        registerJsonValueProcessor(Date.class, DATE_PROCESSOR);
-        registerJsonValueProcessor(java.sql.Date.class, DATE_PROCESSOR);
-
-        final LessNamingProcessor lessNamingProcessor = new LessNamingProcessor();
-
-        registerJsonBeanProcessor(LessNamingProcessor.class, lessNamingProcessor);
-        registerJsonValueProcessor(LessNamingProcessor.class, lessNamingProcessor);
-
-        setJsonBeanProcessorMatcher(LESS_NAMING_BEAN_MATCHER);
-        setJsonValueProcessorMatcher(LESS_NAMING_VALUE_MATCHER);
-    }
-
-    /**
-     * Returns the matching class calculated with the target class and the provided set. Matches the target class with
-     * instanceOf, for Visor classes return custom processor class.
-     *
-     * @param target the target class to match
-     * @param keys a set of possible matches
-     */
-    private static Object getMatch(Class target, Set keys) {
-        if (target == null || keys == null)
-            return null;
-
-        if (target.getSimpleName().startsWith("Visor") ||
-            GridCacheSqlMetadata.class.isAssignableFrom(target) ||
-            GridCacheSqlIndexMetadata.class.isAssignableFrom(target))
-            return LessNamingProcessor.class;
-
-        if (keys.contains(target))
-            return target;
-
-        for (Object key : keys) {
-            Class<?> clazz = (Class<?>)key;
-
-            if (clazz.isAssignableFrom(target))
-                return key;
-        }
-
-        return null;
-    }
-
-    /**
-     * Helper class for simple to-json conversion for Visor classes.
-     */
-    private class LessNamingProcessor implements JsonBeanProcessor, JsonValueProcessor {
-        /** Methods to exclude. */
-        private final Collection<String> exclMtds = Arrays.asList("toString", "hashCode", "clone", "getClass");
-
-        /** */
-        private final Map<Class<?>, Collection<Method>> clsCache = new HashMap<>();
-
-        /** */
-        private final ReadWriteLock rwLock = new ReentrantReadWriteLock();
-
-        /** {@inheritDoc} */
-        @Override public JSONObject processBean(Object bean, JsonConfig jsonCfg) {
-            if (bean == null)
-                return new JSONObject(true);
-
-            final JSONObject ret = new JSONObject();
-
-            Collection<Method> methods;
-
-            Class<?> cls = bean.getClass();
-
-            // Get descriptor from cache.
-            rwLock.readLock().lock();
-
-            try {
-                methods = clsCache.get(cls);
-            }
-            finally {
-                rwLock.readLock().unlock();
-            }
-
-            // If missing in cache - build descriptor
-            if (methods == null) {
-                Method[] publicMtds = cls.getMethods();
-
-                methods = new ArrayList<>(publicMtds.length);
-
-                for (Method mtd : publicMtds) {
-                    Class retType = mtd.getReturnType();
-
-                    if (mtd.getParameterTypes().length != 0 ||
-                        retType == void.class ||
-                        retType == cls ||
-                        exclMtds.contains(mtd.getName()) ||
-                        (retType == VisorCache.class && mtd.getName().equals("history")))
-                        continue;
-
-                    mtd.setAccessible(true);
-
-                    methods.add(mtd);
-                }
-
-                /*
-                 * Allow multiple puts for the same class - they will simply override.
-                 */
-                rwLock.writeLock().lock();
-
-                try {
-                    clsCache.put(cls, methods);
-                }
-                finally {
-                    rwLock.writeLock().unlock();
-                }
-            }
-
-            // Extract fields values using descriptor and build JSONObject.
-            for (Method mtd : methods) {
-                try {
-                    ret.element(mtd.getName(), mtd.invoke(bean), jsonCfg);
-                }
-                catch (Exception e) {
-                    U.error(log, "Failed to read object property [type= " + cls.getName()
-                        + ", property=" + mtd.getName() + "]", e);
-                }
-            }
-
-            return ret;
-        }
-
-        /** {@inheritDoc} */
-        @Override public Object processArrayValue(Object val, JsonConfig jsonCfg) {
-            return processBean(val, jsonCfg);
-        }
-
-        /** {@inheritDoc} */
-        @Override public Object processObjectValue(String key, Object val, JsonConfig jsonCfg) {
-            return processArrayValue(val, jsonCfg);
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/ignite/blob/73689ae5/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 b6a386b..ac53fb0 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
@@ -17,34 +17,56 @@
 
 package org.apache.ignite.internal.processors.rest.protocols.http.jetty;
 
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.BeanDescription;
+import com.fasterxml.jackson.databind.BeanProperty;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.JsonSerializer;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationConfig;
+import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.module.SimpleModule;
+import com.fasterxml.jackson.databind.ser.BeanSerializerModifier;
+import com.fasterxml.jackson.databind.ser.DefaultSerializerProvider;
+import com.fasterxml.jackson.databind.ser.SerializerFactory;
+import com.fasterxml.jackson.databind.ser.impl.UnknownSerializer;
+import java.beans.IntrospectionException;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
 import java.io.BufferedInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.LineNumberReader;
+import java.lang.reflect.Method;
 import java.net.InetSocketAddress;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.UUID;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
 import javax.servlet.ServletException;
 import javax.servlet.ServletRequest;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
-import net.sf.json.JSON;
-import net.sf.json.JSONException;
-import net.sf.json.JSONSerializer;
-import net.sf.json.JsonConfig;
-import net.sf.json.processors.JsonValueProcessor;
+
 import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.IgniteLogger;
+import org.apache.ignite.internal.processors.cache.query.GridCacheSqlIndexMetadata;
+import org.apache.ignite.internal.processors.cache.query.GridCacheSqlMetadata;
 import org.apache.ignite.internal.processors.rest.GridRestCommand;
 import org.apache.ignite.internal.processors.rest.GridRestProtocolHandler;
 import org.apache.ignite.internal.processors.rest.GridRestResponse;
-import org.apache.ignite.internal.processors.rest.client.message.GridClientTaskResultBean;
 import org.apache.ignite.internal.processors.rest.request.DataStructuresRequest;
 import org.apache.ignite.internal.processors.rest.request.GridRestCacheRequest;
 import org.apache.ignite.internal.processors.rest.request.GridRestLogRequest;
@@ -52,10 +74,17 @@ import org.apache.ignite.internal.processors.rest.request.GridRestRequest;
 import org.apache.ignite.internal.processors.rest.request.GridRestTaskRequest;
 import org.apache.ignite.internal.processors.rest.request.GridRestTopologyRequest;
 import org.apache.ignite.internal.processors.rest.request.RestQueryRequest;
+import org.apache.ignite.internal.util.IgniteExceptionRegistry;
 import org.apache.ignite.internal.util.typedef.F;
 import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.internal.visor.cache.VisorCache;
+import org.apache.ignite.internal.visor.util.VisorExceptionWrapper;
+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;
+import org.apache.ignite.plugin.security.SecurityPermissionSet;
+import org.apache.ignite.plugin.security.SecuritySubject;
 import org.eclipse.jetty.server.Request;
 import org.eclipse.jetty.server.handler.AbstractHandler;
 import org.jetbrains.annotations.Nullable;
@@ -72,17 +101,6 @@ import static org.apache.ignite.internal.processors.rest.GridRestResponse.STATUS
  * {@code /ignite?cmd=cmdName&param1=abc&param2=123}
  */
 public class GridJettyRestHandler extends AbstractHandler {
-    /** JSON value processor that does not transform input object. */
-    private static final JsonValueProcessor SKIP_STR_VAL_PROC = new JsonValueProcessor() {
-        @Override public Object processArrayValue(Object o, JsonConfig jsonConfig) {
-            return o;
-        }
-
-        @Override public Object processObjectValue(String s, Object o, JsonConfig jsonConfig) {
-            return o;
-        }
-    };
-
     /** Logger. */
     private final IgniteLogger log;
     /** Authentication checker. */
@@ -137,14 +155,13 @@ public class GridJettyRestHandler extends AbstractHandler {
      * @param key Key.
      * @param params Parameters map.
      * @param dfltVal Default value.
-     * @return Long value from parameters map or {@code dfltVal} if null
-     *     or not exists.
+     * @return Long value from parameters map or {@code dfltVal} if null or not exists.
      * @throws IgniteCheckedException If parsing failed.
      */
     @Nullable private static Long longValue(String key, Map<String, Object> params, Long dfltVal) throws IgniteCheckedException {
         assert key != null;
 
-        String val = (String) params.get(key);
+        String val = (String)params.get(key);
 
         try {
             return val == null ? dfltVal : Long.valueOf(val);
@@ -160,17 +177,16 @@ public class GridJettyRestHandler extends AbstractHandler {
      * @param key Key.
      * @param params Parameters map.
      * @param dfltVal Default value.
-     * @return Integer value from parameters map or {@code dfltVal} if null
-     *     or not exists.
+     * @return Integer value from parameters map or {@code dfltVal} if null or not exists.
      * @throws IgniteCheckedException If parsing failed.
      */
-    @Nullable private static Integer intValue(String key, Map<String, Object> params, Integer dfltVal) throws IgniteCheckedException {
+    private static int intValue(String key, Map<String, Object> params, int dfltVal) throws IgniteCheckedException {
         assert key != null;
 
-        String val = (String) params.get(key);
+        String val = (String)params.get(key);
 
         try {
-            return val == null ? dfltVal : Integer.valueOf(val);
+            return val == null ? dfltVal : Integer.parseInt(val);
         }
         catch (NumberFormatException ignore) {
             throw new IgniteCheckedException("Failed to parse parameter of Integer type [" + key + "=" + val + "]");
@@ -182,14 +198,13 @@ public class GridJettyRestHandler extends AbstractHandler {
      *
      * @param key Key.
      * @param params Parameters map.
-     * @return UUID value from parameters map or {@code null} if null
-     *     or not exists.
+     * @return UUID value from parameters map or {@code null} if null or not exists.
      * @throws IgniteCheckedException If parsing failed.
      */
     @Nullable private static UUID uuidValue(String key, Map<String, Object> params) throws IgniteCheckedException {
         assert key != null;
 
-        String val = (String) params.get(key);
+        String val = (String)params.get(key);
 
         try {
             return val == null ? null : UUID.fromString(val);
@@ -208,7 +223,7 @@ public class GridJettyRestHandler extends AbstractHandler {
         InputStream in = getClass().getResourceAsStream("rest.html");
 
         if (in != null) {
-            LineNumberReader rdr = new LineNumberReader(new InputStreamReader(in));
+            LineNumberReader rdr = new LineNumberReader(new InputStreamReader(in, "UTF-8"));
 
             try {
                 StringBuilder buf = new StringBuilder(2048);
@@ -310,6 +325,244 @@ public class GridJettyRestHandler extends AbstractHandler {
         }
     }
 
+    /** Custom {@code null} value serializer. */
+    private static final JsonSerializer<Object> NULL_SERIALIZER = new JsonSerializer<Object>() {
+        /** {@inheritDoc} */
+        @Override public void serialize(Object val, JsonGenerator gen, SerializerProvider ser) throws IOException {
+            gen.writeNull();
+        }
+    };
+
+    /** Custom {@code null} string serializer. */
+    private static final JsonSerializer<Object> NULL_STRING_SERIALIZER = new JsonSerializer<Object>() {
+        /** {@inheritDoc} */
+        @Override public void serialize(Object val, JsonGenerator gen, SerializerProvider ser) throws IOException {
+            gen.writeString("");
+        }
+    };
+
+    /** Custom serializer for {@link Throwable} */
+    private static final JsonSerializer<Throwable> THROWABLE_SERIALIZER = new JsonSerializer<Throwable>() {
+        /** {@inheritDoc} */
+        @Override public void serialize(Throwable e, JsonGenerator gen, SerializerProvider ser) throws IOException {
+            gen.writeStartObject();
+
+            if (e instanceof VisorExceptionWrapper) {
+                VisorExceptionWrapper wrapper = (VisorExceptionWrapper)e;
+
+                gen.writeStringField("className", wrapper.getClassName());
+            }
+            else
+                gen.writeStringField("className", e.getClass().getName());
+
+            if (e.getMessage() != null)
+                gen.writeStringField("message", e.getMessage());
+
+            if (e.getCause() != null)
+                gen.writeObjectField("cause", e.getCause());
+
+            if (e instanceof SQLException) {
+                SQLException sqlE = (SQLException)e;
+
+                gen.writeNumberField("errorCode", sqlE.getErrorCode());
+                gen.writeStringField("SQLState", sqlE.getSQLState());
+            }
+
+            gen.writeEndObject();
+        }
+    };
+
+    /** Custom serializer for {@link IgniteUuid} */
+    private static final JsonSerializer<IgniteUuid> IGNITE_UUID_SERIALIZER = new JsonSerializer<IgniteUuid>() {
+        /** {@inheritDoc} */
+        @Override public void serialize(IgniteUuid uid, JsonGenerator gen, SerializerProvider ser) throws IOException {
+            gen.writeString(uid.toString());
+        }
+    };
+
+    /** Custom serializer for {@link IgniteBiTuple} */
+    private static final JsonSerializer<IgniteBiTuple> IGNITE_TUPLE_SERIALIZER = new JsonSerializer<IgniteBiTuple>() {
+        /** {@inheritDoc} */
+        @Override public void serialize(IgniteBiTuple t, JsonGenerator gen, SerializerProvider ser) throws IOException {
+            gen.writeStartObject();
+
+            gen.writeObjectField("key", t.getKey());
+            gen.writeObjectField("value", t.getValue());
+
+            gen.writeEndObject();
+        }
+    };
+
+    /**
+     * Custom serializer for Visor classes with non JavaBeans getters.
+     */
+    private static final JsonSerializer<Object> LESS_NAMING_SERIALIZER = new JsonSerializer<Object>() {
+        /** Methods to exclude. */
+        private final Collection<String> exclMtds = Arrays.asList("toString", "hashCode", "clone", "getClass");
+
+        /** */
+        private final Map<Class<?>, Collection<Method>> clsCache = new HashMap<>();
+
+        /** */
+        private final ReadWriteLock rwLock = new ReentrantReadWriteLock();
+
+        /** {@inheritDoc} */
+        @Override public void serialize(Object bean, JsonGenerator gen, SerializerProvider ser) throws IOException {
+            if (bean != null) {
+                gen.writeStartObject();
+
+                Class<?> cls = bean.getClass();
+
+                Collection<Method> methods;
+
+                // Get descriptor from cache.
+                rwLock.readLock().lock();
+
+                try {
+                    methods = clsCache.get(cls);
+                }
+                finally {
+                    rwLock.readLock().unlock();
+                }
+
+                // If missing in cache - build descriptor
+                if (methods == null) {
+                    Method[] publicMtds = cls.getMethods();
+
+                    methods = new ArrayList<>(publicMtds.length);
+
+                    for (Method mtd : publicMtds) {
+                        Class retType = mtd.getReturnType();
+
+                        String mtdName = mtd.getName();
+
+                        if (mtd.getParameterTypes().length != 0 ||
+                            retType == void.class || retType == cls ||
+                            exclMtds.contains(mtdName) ||
+                            (VisorCache.class.isAssignableFrom(retType) && "history".equals(mtdName)))
+                            continue;
+
+                        mtd.setAccessible(true);
+
+                        methods.add(mtd);
+                    }
+
+                /*
+                 * Allow multiple puts for the same class - they will simply override.
+                 */
+                    rwLock.writeLock().lock();
+
+                    try {
+                        clsCache.put(cls, methods);
+                    }
+                    finally {
+                        rwLock.writeLock().unlock();
+                    }
+                }
+
+                // Extract fields values using descriptor and build JSONObject.
+                for (Method mtd : methods) {
+                    try {
+                        Object prop = mtd.invoke(bean);
+
+                        if (prop != null)
+                            gen.writeObjectField(mtd.getName(), prop);
+                    }
+                    catch (IOException ioe) {
+                        throw ioe;
+                    }
+                    catch (Exception e) {
+                        throw new IOException(e);
+                    }
+                }
+
+                gen.writeEndObject();
+            }
+        }
+    };
+
+    /** */
+    private static final BeanSerializerModifier CUSTOM_JSON_SERIALIZER_MODIFIER = new BeanSerializerModifier() {
+        /** {@inheritDoc} */
+        @Override public JsonSerializer<?> modifySerializer(SerializationConfig cfg, BeanDescription beanDesc,
+            JsonSerializer<?> serializer) {
+            if (serializer.getClass() == UnknownSerializer.class) {
+                Class<?> beanCls = beanDesc.getBeanClass();
+
+                if ((beanCls.getSimpleName().startsWith("Visor") && beanCls != VisorExceptionWrapper.class) ||
+                    beanCls == IgniteExceptionRegistry.ExceptionInfo.class ||
+                    GridCacheSqlMetadata.class.isAssignableFrom(beanCls) ||
+                    GridCacheSqlIndexMetadata.class.isAssignableFrom(beanCls) ||
+                    SecuritySubject.class.isAssignableFrom(beanCls) ||
+                    SecurityPermissionSet.class.isAssignableFrom(beanCls))
+                    return LESS_NAMING_SERIALIZER;
+
+                try {
+                    PropertyDescriptor[] props = Introspector.getBeanInfo(beanCls).getPropertyDescriptors();
+
+                    if (props == null || (props.length == 1 && props[0].getName().equals("class")))
+                        return LESS_NAMING_SERIALIZER;
+                }
+                catch (IntrospectionException ignore) {
+                    // No-op.
+                }
+            }
+
+            return super.modifySerializer(cfg, beanDesc, serializer);
+        }
+    };
+
+    /**
+     * Custom serializers provider that provide special serializers for {@code null} values.
+     */
+    private static class CustomSerializerProvider extends DefaultSerializerProvider {
+        /**
+         * Default constructor.
+         */
+        CustomSerializerProvider() {
+            super();
+        }
+
+        /**
+         * Full constructor.
+         *
+         * @param src Blueprint object used as the baseline for this instance.
+         * @param cfg Provider configuration.
+         * @param f Serializers factory.
+         */
+        CustomSerializerProvider(SerializerProvider src, SerializationConfig cfg, SerializerFactory f) {
+            super(src, cfg, f);
+        }
+
+        /** {@inheritDoc} */
+        public DefaultSerializerProvider createInstance(SerializationConfig cfg, SerializerFactory jsf) {
+            return new CustomSerializerProvider(this, cfg, jsf);
+        }
+
+        /** {@inheritDoc} */
+        @Override public JsonSerializer<Object> findNullValueSerializer(BeanProperty prop) throws JsonMappingException {
+            if (prop.getType().getRawClass() == String.class)
+                return NULL_STRING_SERIALIZER;
+
+            return NULL_SERIALIZER;
+        }
+    }
+
+    /** */
+    private static final ObjectMapper JSON_MAPPER = new ObjectMapper(null, new CustomSerializerProvider(), null);
+
+    static {
+        final SimpleModule module = new SimpleModule();
+
+        module.setSerializerModifier(CUSTOM_JSON_SERIALIZER_MODIFIER);
+
+        module.addSerializer(Throwable.class, THROWABLE_SERIALIZER);
+        module.addSerializer(IgniteBiTuple.class, IGNITE_TUPLE_SERIALIZER);
+        module.addSerializer(IgniteUuid.class, IGNITE_UUID_SERIALIZER);
+
+        JSON_MAPPER.registerModule(module);
+    }
+
     /**
      * Process HTTP request.
      *
@@ -368,39 +621,35 @@ public class GridJettyRestHandler extends AbstractHandler {
                 throw (Error)e;
         }
 
-        JsonConfig cfg = new GridJettyJsonConfig(log);
-
-        // Workaround for not needed transformation of string into JSON object.
-        if (cmdRes.getResponse() instanceof String)
-            cfg.registerJsonValueProcessor(cmdRes.getClass(), "response", SKIP_STR_VAL_PROC);
-
-        // Workaround for not needed transformation of result field string into JSON object at GridClientTaskResultBean.
-        if (cmdRes.getResponse() instanceof GridClientTaskResultBean
-            && ((GridClientTaskResultBean)cmdRes.getResponse()).getResult() instanceof String)
-            cfg.registerJsonValueProcessor(cmdRes.getResponse().getClass(), "result", SKIP_STR_VAL_PROC);
-
-        JSON json;
+        String json;
 
         try {
-            json = JSONSerializer.toJSON(cmdRes, cfg);
+            json = JSON_MAPPER.writeValueAsString(cmdRes);
         }
-        catch (JSONException e) {
-            U.error(log, "Failed to convert response to JSON: " + cmdRes, e);
+        catch (JsonProcessingException e1) {
+            U.error(log, "Failed to convert response to JSON: " + cmdRes, e1);
 
-            json = JSONSerializer.toJSON(new GridRestResponse(STATUS_FAILED, e.getMessage()), cfg);
+            GridRestResponse resFailed = new GridRestResponse(STATUS_FAILED, e1.getMessage());
+
+            try {
+                json = JSON_MAPPER.writeValueAsString(resFailed);
+            }
+            catch (JsonProcessingException e2) {
+                json = "{\"successStatus\": \"1\", \"error:\" \"" + e2.getMessage() + "\"}}";
+            }
         }
 
         try {
             if (log.isDebugEnabled())
-                log.debug("Parsed command response into JSON object: " + json.toString(2));
+                log.debug("Parsed command response into JSON object: " + json);
 
-            res.getWriter().write(json.toString());
+            res.getWriter().write(json);
 
             if (log.isDebugEnabled())
                 log.debug("Processed HTTP request [action=" + act + ", jsonRes=" + cmdRes + ", req=" + req + ']');
         }
         catch (IOException e) {
-            U.error(log, "Failed to send HTTP response: " + json.toString(2), e);
+            U.error(log, "Failed to send HTTP response: " + json, e);
         }
     }
 
@@ -510,10 +759,10 @@ public class GridJettyRestHandler extends AbstractHandler {
             case NODE: {
                 GridRestTopologyRequest restReq0 = new GridRestTopologyRequest();
 
-                restReq0.includeMetrics(Boolean.parseBoolean((String) params.get("mtr")));
-                restReq0.includeAttributes(Boolean.parseBoolean((String) params.get("attr")));
+                restReq0.includeMetrics(Boolean.parseBoolean((String)params.get("mtr")));
+                restReq0.includeAttributes(Boolean.parseBoolean((String)params.get("attr")));
 
-                restReq0.nodeIp((String) params.get("ip"));
+                restReq0.nodeIp((String)params.get("ip"));
 
                 restReq0.nodeId(uuidValue("id", params));
 
@@ -527,12 +776,12 @@ public class GridJettyRestHandler extends AbstractHandler {
             case NOOP: {
                 GridRestTaskRequest restReq0 = new GridRestTaskRequest();
 
-                restReq0.taskId((String) params.get("id"));
-                restReq0.taskName((String) params.get("name"));
+                restReq0.taskId((String)params.get("id"));
+                restReq0.taskName((String)params.get("name"));
 
                 restReq0.params(values("p", params));
 
-                restReq0.async(Boolean.parseBoolean((String) params.get("async")));
+                restReq0.async(Boolean.parseBoolean((String)params.get("async")));
 
                 restReq0.timeout(longValue("timeout", params, 0L));
 
@@ -544,7 +793,7 @@ public class GridJettyRestHandler extends AbstractHandler {
             case LOG: {
                 GridRestLogRequest restReq0 = new GridRestLogRequest();
 
-                restReq0.path((String) params.get("path"));
+                restReq0.path((String)params.get("path"));
 
                 restReq0.from(intValue("from", params, -1));
                 restReq0.to(intValue("to", params, -1));
@@ -569,9 +818,9 @@ public class GridJettyRestHandler extends AbstractHandler {
 
                 restReq0.arguments(values("arg", params).toArray());
 
-                restReq0.typeName((String) params.get("type"));
+                restReq0.typeName((String)params.get("type"));
 
-                String pageSize = (String) params.get("pageSize");
+                String pageSize = (String)params.get("pageSize");
 
                 if (pageSize != null)
                     restReq0.pageSize(Integer.parseInt(pageSize));
@@ -612,7 +861,7 @@ public class GridJettyRestHandler extends AbstractHandler {
             case FETCH_SQL_QUERY: {
                 RestQueryRequest restReq0 = new RestQueryRequest();
 
-                String qryId = (String) params.get("qryId");
+                String qryId = (String)params.get("qryId");
 
                 if (qryId != null)
                     restReq0.queryId(Long.parseLong(qryId));
@@ -632,7 +881,7 @@ public class GridJettyRestHandler extends AbstractHandler {
             case CLOSE_SQL_QUERY: {
                 RestQueryRequest restReq0 = new RestQueryRequest();
 
-                String qryId = (String) params.get("qryId");
+                String qryId = (String)params.get("qryId");
 
                 if (qryId != null)
                     restReq0.queryId(Long.parseLong(qryId));
@@ -659,7 +908,7 @@ public class GridJettyRestHandler extends AbstractHandler {
             restReq.credentials(cred);
         }
 
-        String clientId = (String) params.get("clientId");
+        String clientId = (String)params.get("clientId");
 
         try {
             if (clientId != null)
@@ -669,7 +918,7 @@ public class GridJettyRestHandler extends AbstractHandler {
             // Ignore invalid client id. Rest handler will process this logic.
         }
 
-        String destId = (String) params.get("destId");
+        String destId = (String)params.get("destId");
 
         try {
             if (destId != null)
@@ -679,7 +928,7 @@ public class GridJettyRestHandler extends AbstractHandler {
             // Don't fail - try to execute locally.
         }
 
-        String sesTokStr = (String) params.get("sessionToken");
+        String sesTokStr = (String)params.get("sessionToken");
 
         try {
             if (sesTokStr != null)
@@ -699,7 +948,7 @@ public class GridJettyRestHandler extends AbstractHandler {
      * @param params Parameters map.
      * @return Values.
      */
-    @Nullable protected List<Object> values(String keyPrefix, Map<String, Object> params) {
+    protected List<Object> values(String keyPrefix, Map<String, Object> params) {
         assert keyPrefix != null;
 
         List<Object> vals = new LinkedList<>();
@@ -720,15 +969,14 @@ public class GridJettyRestHandler extends AbstractHandler {
      * @param req Request.
      * @return Command.
      */
-    @Nullable GridRestCommand command(ServletRequest req) {
+    @Nullable private GridRestCommand command(ServletRequest req) {
         String cmd = req.getParameter("cmd");
 
         return cmd == null ? null : GridRestCommand.fromKey(cmd.toLowerCase());
     }
 
     /**
-     * Parses HTTP parameters in an appropriate format and return back map of
-     * values to predefined list of names.
+     * Parses HTTP parameters in an appropriate format and return back map of values to predefined list of names.
      *
      * @param req Request.
      * @return Map of parsed parameters.

http://git-wip-us.apache.org/repos/asf/ignite/blob/73689ae5/parent/pom.xml
----------------------------------------------------------------------
diff --git a/parent/pom.xml b/parent/pom.xml
index c493248..662ab55 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -74,6 +74,7 @@
         <httpclient.version>4.5.1</httpclient.version>
         <httpcore.version>4.4.3</httpcore.version>
         <jackson.version>1.9.13</jackson.version>
+        <jackson2.version>2.7.4</jackson2.version>
         <javax.cache.bundle.version>1.0.0_1</javax.cache.bundle.version>
         <javax.cache.version>1.0.0</javax.cache.version>
         <jetty.version>9.2.11.v20150529</jetty.version>


[2/2] ignite git commit: IGNITE-3277 Migrated rest-http from outdated json-lib to Jackson v2.

Posted by an...@apache.org.
IGNITE-3277 Migrated rest-http from outdated json-lib to Jackson v2.


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/73689ae5
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/73689ae5
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/73689ae5

Branch: refs/heads/ignite-3277
Commit: 73689ae5dbc58b932d93baf6071c6cd27c430452
Parents: 4ed02fd
Author: Andrey Novikov <an...@apache.org>
Authored: Thu Jun 16 14:42:30 2016 +0700
Committer: Andrey Novikov <an...@apache.org>
Committed: Thu Jun 16 14:42:30 2016 +0700

----------------------------------------------------------------------
 modules/clients/pom.xml                         |   8 -
 .../ignite/internal/client/ClientHttpTask.java  |  33 +-
 .../ignite/internal/client/ClientTcpTask.java   |  10 +-
 .../integration/ClientAbstractSelfTest.java     |  93 +-
 .../JettyRestProcessorAbstractSelfTest.java     | 890 +++++++------------
 modules/core/pom.xml                            |  15 +-
 .../ignite/internal/visor/cache/VisorCache.java |   1 -
 .../internal/visor/cache/VisorCacheV4.java      | 124 +++
 .../visor/node/VisorNodeDataCollectorJob.java   |  26 +-
 modules/rest-http/pom.xml                       |  25 +-
 .../http/jetty/GridJettyJsonConfig.java         | 317 -------
 .../http/jetty/GridJettyRestHandler.java        | 380 ++++++--
 parent/pom.xml                                  |   1 +
 13 files changed, 870 insertions(+), 1053 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/73689ae5/modules/clients/pom.xml
----------------------------------------------------------------------
diff --git a/modules/clients/pom.xml b/modules/clients/pom.xml
index 5b328e0..fa25d18 100644
--- a/modules/clients/pom.xml
+++ b/modules/clients/pom.xml
@@ -83,14 +83,6 @@
         </dependency>
 
         <dependency>
-            <groupId>net.sf.json-lib</groupId>
-            <artifactId>json-lib</artifactId>
-            <version>2.4</version>
-            <classifier>jdk15</classifier>
-            <scope>test</scope>
-        </dependency>
-
-        <dependency>
             <groupId>org.apache.ignite</groupId>
             <artifactId>ignite-core</artifactId>
             <version>${project.version}</version>

http://git-wip-us.apache.org/repos/asf/ignite/blob/73689ae5/modules/clients/src/test/java/org/apache/ignite/internal/client/ClientHttpTask.java
----------------------------------------------------------------------
diff --git a/modules/clients/src/test/java/org/apache/ignite/internal/client/ClientHttpTask.java b/modules/clients/src/test/java/org/apache/ignite/internal/client/ClientHttpTask.java
index 9604c29..977a1eb 100644
--- a/modules/clients/src/test/java/org/apache/ignite/internal/client/ClientHttpTask.java
+++ b/modules/clients/src/test/java/org/apache/ignite/internal/client/ClientHttpTask.java
@@ -17,12 +17,13 @@
 
 package org.apache.ignite.internal.client;
 
+import java.io.IOException;
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
-import net.sf.json.JSON;
-import net.sf.json.JSONArray;
-import net.sf.json.JSONSerializer;
-import net.sf.json.JsonConfig;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.apache.ignite.IgniteException;
 import org.apache.ignite.compute.ComputeJob;
 import org.apache.ignite.compute.ComputeJobResult;
 import org.apache.ignite.compute.ComputeJobResultPolicy;
@@ -40,14 +41,28 @@ public class ClientHttpTask extends ComputeTaskSplitAdapter<String, Integer> {
     /** Task delegate. */
     private final ClientTcpTask delegate = new ClientTcpTask();
 
+    /** JSON to java mapper. */
+    private static final ObjectMapper JSON_MAPPER = new ObjectMapper();
+
     /** {@inheritDoc} */
     @Override protected Collection<? extends ComputeJob> split(int gridSize, String arg) {
-        JSON json = JSONSerializer.toJSON(arg);
+        try {
+            JsonNode json = JSON_MAPPER.readTree(arg);
+
+            List<String> list = null;
+
+            if (json.isArray()) {
+                list = new ArrayList<>();
 
-        List list = json.isArray() ? JSONArray.toList((JSONArray)json, String.class, new JsonConfig()) : null;
+                for (JsonNode child : json)
+                    list.add(child.asText());
+            }
 
-        //noinspection unchecked
-        return delegate.split(gridSize, list);
+            return delegate.split(gridSize, list);
+        }
+        catch (IOException e) {
+            throw new IgniteException(e);
+        }
     }
 
     /** {@inheritDoc} */
@@ -62,4 +77,4 @@ public class ClientHttpTask extends ComputeTaskSplitAdapter<String, Integer> {
 
         return WAIT;
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/73689ae5/modules/clients/src/test/java/org/apache/ignite/internal/client/ClientTcpTask.java
----------------------------------------------------------------------
diff --git a/modules/clients/src/test/java/org/apache/ignite/internal/client/ClientTcpTask.java b/modules/clients/src/test/java/org/apache/ignite/internal/client/ClientTcpTask.java
index 8458c0e..54a58e6 100644
--- a/modules/clients/src/test/java/org/apache/ignite/internal/client/ClientTcpTask.java
+++ b/modules/clients/src/test/java/org/apache/ignite/internal/client/ClientTcpTask.java
@@ -34,13 +34,13 @@ import static org.apache.ignite.compute.ComputeJobResultPolicy.WAIT;
  * <p>
  * The argument of the task is a collection of objects to calculate string length sum of.
  */
-public class ClientTcpTask extends ComputeTaskSplitAdapter<List<Object>, Integer> {
+public class ClientTcpTask extends ComputeTaskSplitAdapter<List<String>, Integer> {
     /** {@inheritDoc} */
-    @Override protected Collection<? extends ComputeJob> split(int gridSize, List<Object> list) {
+    @Override protected Collection<? extends ComputeJob> split(int gridSize, List<String> list) {
         Collection<ComputeJobAdapter> jobs = new ArrayList<>();
 
         if (list != null)
-            for (final Object val : list)
+            for (final String val : list)
                 jobs.add(new ComputeJobAdapter() {
                     @Override public Object execute() {
                         try {
@@ -50,7 +50,7 @@ public class ClientTcpTask extends ComputeTaskSplitAdapter<List<Object>, Integer
                             Thread.currentThread().interrupt();
                         }
 
-                        return val == null ? 0 : val.toString().length();
+                        return val == null ? 0 : val.length();
                     }
                 });
 
@@ -74,4 +74,4 @@ public class ClientTcpTask extends ComputeTaskSplitAdapter<List<Object>, Integer
 
         return WAIT;
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/73689ae5/modules/clients/src/test/java/org/apache/ignite/internal/client/integration/ClientAbstractSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/clients/src/test/java/org/apache/ignite/internal/client/integration/ClientAbstractSelfTest.java b/modules/clients/src/test/java/org/apache/ignite/internal/client/integration/ClientAbstractSelfTest.java
index 125603e..d00a3a0 100644
--- a/modules/clients/src/test/java/org/apache/ignite/internal/client/integration/ClientAbstractSelfTest.java
+++ b/modules/clients/src/test/java/org/apache/ignite/internal/client/integration/ClientAbstractSelfTest.java
@@ -17,9 +17,11 @@
 
 package org.apache.ignite.internal.client.integration;
 
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.List;
@@ -31,12 +33,13 @@ import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ThreadFactory;
 import java.util.concurrent.atomic.AtomicInteger;
+import javax.cache.Cache;
 import javax.cache.configuration.Factory;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
 import junit.framework.Assert;
-import net.sf.json.JSON;
-import net.sf.json.JSONArray;
-import net.sf.json.JSONSerializer;
-import net.sf.json.JsonConfig;
+import org.apache.ignite.IgniteException;
 import org.apache.ignite.cache.store.CacheStore;
 import org.apache.ignite.cache.store.CacheStoreAdapter;
 import org.apache.ignite.compute.ComputeJob;
@@ -246,8 +249,8 @@ public abstract class ClientAbstractSelfTest extends GridCommonAbstractTest {
             cacheConfiguration("partitioned"), cacheConfiguration(CACHE_NAME));
 
         clientCfg.setMessageInterceptor(new ConnectorMessageInterceptor() {
-            @Override
-            public Object onReceive(@Nullable Object obj) {
+            /** {@inheritDoc} */
+            @Override public Object onReceive(@Nullable Object obj) {
                 if (obj != null)
                     INTERCEPTED_OBJECTS.put(obj, obj);
 
@@ -255,8 +258,8 @@ public abstract class ClientAbstractSelfTest extends GridCommonAbstractTest {
                     obj + INTERCEPTED_SUF : obj;
             }
 
-            @Override
-            public Object onSend(Object obj) {
+            /** {@inheritDoc} */
+            @Override public Object onSend(Object obj) {
                 if (obj != null)
                     INTERCEPTED_OBJECTS.put(obj, obj);
 
@@ -332,7 +335,7 @@ public abstract class ClientAbstractSelfTest extends GridCommonAbstractTest {
         cfg.setDataConfigurations(Arrays.asList(nullCache, cache));
 
         cfg.setProtocol(protocol());
-        cfg.setServers(Arrays.asList(serverAddress()));
+        cfg.setServers(Collections.singleton(serverAddress()));
 
         // Setting custom executor, to avoid failures on client shutdown.
         // And applying custom naming scheme to ease debugging.
@@ -390,9 +393,9 @@ public abstract class ClientAbstractSelfTest extends GridCommonAbstractTest {
         futs.put("put", data.putAsync("key", "val"));
         futs.put("putAll", data.putAllAsync(F.asMap("key", "val")));
         futs.put("get", data.getAsync("key"));
-        futs.put("getAll", data.getAllAsync(Arrays.asList("key")));
+        futs.put("getAll", data.getAllAsync(Collections.singletonList("key")));
         futs.put("remove", data.removeAsync("key"));
-        futs.put("removeAll", data.removeAllAsync(Arrays.asList("key")));
+        futs.put("removeAll", data.removeAllAsync(Collections.singletonList("key")));
         futs.put("replace", data.replaceAsync("key", "val"));
         futs.put("cas", data.casAsync("key", "val", "val2"));
         futs.put("metrics", data.metricsAsync());
@@ -500,8 +503,8 @@ public abstract class ClientAbstractSelfTest extends GridCommonAbstractTest {
 
         GridClientCompute compute = client.compute();
 
-        Assert.assertEquals(new Integer(17), compute.execute(taskName, taskArg));
-        Assert.assertEquals(new Integer(17), compute.executeAsync(taskName, taskArg).get());
+        Assert.assertEquals(17, compute.execute(taskName, taskArg));
+        Assert.assertEquals(17, compute.executeAsync(taskName, taskArg).get());
     }
 
     /**
@@ -570,13 +573,13 @@ public abstract class ClientAbstractSelfTest extends GridCommonAbstractTest {
     /**
      * Test task.
      */
-    private static class TestTask extends ComputeTaskSplitAdapter<List<Object>, Integer> {
+    private static class TestTask extends ComputeTaskSplitAdapter<List<String>, Integer> {
         /** {@inheritDoc} */
-        @Override protected Collection<? extends ComputeJob> split(int gridSize, List<Object> list) {
+        @Override protected Collection<? extends ComputeJob> split(int gridSize, List<String> list) {
             Collection<ComputeJobAdapter> jobs = new ArrayList<>();
 
             if (list != null)
-                for (final Object val : list)
+                for (final String val : list)
                     jobs.add(new ComputeJobAdapter() {
                         @Override public Object execute() {
                             try {
@@ -586,7 +589,7 @@ public abstract class ClientAbstractSelfTest extends GridCommonAbstractTest {
                                 Thread.currentThread().interrupt();
                             }
 
-                            return val == null ? 0 : val.toString().length();
+                            return val == null ? 0 : val.length();
                         }
                     });
 
@@ -607,20 +610,20 @@ public abstract class ClientAbstractSelfTest extends GridCommonAbstractTest {
     /**
      * Test task that sleeps 5 seconds.
      */
-    private static class SleepTestTask extends ComputeTaskSplitAdapter<List<Object>, Integer> {
+    private static class SleepTestTask extends ComputeTaskSplitAdapter<List<String>, Integer> {
         /** {@inheritDoc} */
-        @Override protected Collection<? extends ComputeJob> split(int gridSize, List<Object> list)
+        @Override protected Collection<? extends ComputeJob> split(int gridSize, List<String> list)
             {
             Collection<ComputeJobAdapter> jobs = new ArrayList<>();
 
             if (list != null)
-                for (final Object val : list)
+                for (final String val : list)
                     jobs.add(new ComputeJobAdapter() {
                         @Override public Object execute() {
                             try {
                                 Thread.sleep(5000);
 
-                                return val == null ? 0 : val.toString().length();
+                                return val == null ? 0 : val.length();
                             }
                             catch (InterruptedException ignored) {
                                 return -1;
@@ -642,10 +645,14 @@ public abstract class ClientAbstractSelfTest extends GridCommonAbstractTest {
         }
     }
 
+    /** JSON to java mapper. */
+    private static final ObjectMapper JSON_MAPPER = new ObjectMapper();
+
     /**
      * Http test task with restriction to string arguments only.
      */
     protected static class HttpTestTask extends ComputeTaskSplitAdapter<String, Integer> {
+        /** */
         private final TestTask delegate = new TestTask();
 
         /** {@inheritDoc} */
@@ -654,11 +661,23 @@ public abstract class ClientAbstractSelfTest extends GridCommonAbstractTest {
             if (arg.endsWith("intercepted"))
                 arg = arg.substring(0, arg.length() - 11);
 
-            JSON json = JSONSerializer.toJSON(arg);
+            try {
+                JsonNode json = JSON_MAPPER.readTree(arg);
+
+                List<String> list = null;
 
-            List list = json.isArray() ? JSONArray.toList((JSONArray)json, String.class, new JsonConfig()) : null;
+                if (json.isArray()) {
+                    list = new ArrayList<>();
 
-            return delegate.split(gridSize, list);
+                    for (JsonNode child : json)
+                        list.add(child.asText());
+                }
+
+                return delegate.split(gridSize, list);
+            }
+            catch (IOException e) {
+                throw new IgniteException(e);
+            }
         }
 
         /** {@inheritDoc} */
@@ -671,16 +690,29 @@ public abstract class ClientAbstractSelfTest extends GridCommonAbstractTest {
      * Http wrapper for sleep task.
      */
     protected static class SleepHttpTestTask extends ComputeTaskSplitAdapter<String, Integer> {
+        /** */
         private final SleepTestTask delegate = new SleepTestTask();
 
         /** {@inheritDoc} */
         @SuppressWarnings("unchecked")
         @Override protected Collection<? extends ComputeJob> split(int gridSize, String arg) {
-            JSON json = JSONSerializer.toJSON(arg);
+            try {
+                JsonNode json = JSON_MAPPER.readTree(arg);
+
+                List<String> list = null;
 
-            List list = json.isArray() ? JSONArray.toList((JSONArray)json, String.class, new JsonConfig()) : null;
+                if (json.isArray()) {
+                    list = new ArrayList<>();
+
+                    for (JsonNode child : json)
+                        list.add(child.asText());
+                }
 
-            return delegate.split(gridSize, list);
+                return delegate.split(gridSize, list);
+            }
+            catch (IOException e) {
+                throw new IgniteException(e);
+            }
         }
 
         /** {@inheritDoc} */
@@ -698,9 +730,8 @@ public abstract class ClientAbstractSelfTest extends GridCommonAbstractTest {
 
         /** {@inheritDoc} */
         @Override public void loadCache(IgniteBiInClosure<Object, Object> clo, Object... args) {
-            for (Map.Entry e : map.entrySet()) {
+            for (Map.Entry e : map.entrySet())
                 clo.apply(e.getKey(), e.getValue());
-            }
         }
 
         /** {@inheritDoc} */
@@ -709,7 +740,7 @@ public abstract class ClientAbstractSelfTest extends GridCommonAbstractTest {
         }
 
         /** {@inheritDoc} */
-        @Override public void write(javax.cache.Cache.Entry<? extends Object, ? extends Object> e) {
+        @Override public void write(Cache.Entry<?, ?> e) {
             map.put(e.getKey(), e.getValue());
         }
 
@@ -718,4 +749,4 @@ public abstract class ClientAbstractSelfTest extends GridCommonAbstractTest {
             map.remove(key);
         }
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/73689ae5/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorAbstractSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorAbstractSelfTest.java b/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorAbstractSelfTest.java
index 9fd3044..66d74b8 100644
--- a/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorAbstractSelfTest.java
+++ b/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorAbstractSelfTest.java
@@ -17,24 +17,24 @@
 
 package org.apache.ignite.internal.processors.rest;
 
+import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.LineNumberReader;
 import java.io.Serializable;
+import java.io.UnsupportedEncodingException;
 import java.net.URL;
 import java.net.URLConnection;
 import java.net.URLEncoder;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.Iterator;
-import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.UUID;
 import java.util.concurrent.ConcurrentHashMap;
-import java.util.regex.Pattern;
-import net.sf.json.JSONNull;
-import net.sf.json.JSONObject;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
 import org.apache.ignite.IgniteCache;
 import org.apache.ignite.cache.CacheAtomicityMode;
 import org.apache.ignite.cache.CacheMode;
@@ -103,6 +103,7 @@ import org.apache.ignite.lang.IgniteUuid;
 import org.apache.ignite.testframework.GridTestUtils;
 
 import static org.apache.ignite.IgniteSystemProperties.IGNITE_JETTY_PORT;
+import static org.apache.ignite.internal.IgniteVersionUtils.VER_STR;
 
 /**
  * Tests for Jetty REST protocol.
@@ -112,6 +113,12 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
     /** Grid count. */
     private static final int GRID_CNT = 3;
 
+    /** Default encoding. */
+    private static final String CHARSET = "UTF-8";
+
+    /** JSON to java mapper. */
+    private static final ObjectMapper JSON_MAPPER = new ObjectMapper();
+
     /** {@inheritDoc} */
     @Override protected void beforeTestsStarted() throws Exception {
         System.setProperty(IGNITE_JETTY_PORT, Integer.toString(restPort()));
@@ -157,12 +164,14 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
      * @throws Exception If failed.
      */
     protected String content(Map<String, String> params) throws Exception {
-        String addr = "http://" + LOC_HOST + ":" + restPort() + "/ignite?";
+        SB sb = new SB();
+
+        sb.a("http://").a(LOC_HOST).a(":").a(restPort()).a("/ignite?");
 
         for (Map.Entry<String, String> e : params.entrySet())
-            addr += e.getKey() + '=' + e.getValue() + '&';
+            sb.a(e.getKey()).a('=').a(e.getValue()).a('&');
 
-        URL url = new URL(addr);
+        URL url = new URL(sb.toString());
 
         URLConnection conn = url.openConnection();
 
@@ -173,149 +182,139 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
 
         InputStream in = conn.getInputStream();
 
-        LineNumberReader rdr = new LineNumberReader(new InputStreamReader(in));
-
         StringBuilder buf = new StringBuilder(256);
 
-        for (String line = rdr.readLine(); line != null; line = rdr.readLine())
-            buf.append(line);
+        try (LineNumberReader rdr = new LineNumberReader(new InputStreamReader(in, "UTF-8"))) {
+            for (String line = rdr.readLine(); line != null; line = rdr.readLine())
+                buf.append(line);
+        }
 
         return buf.toString();
     }
 
     /**
-     * @param json JSON response.
-     * @param ptrn Pattern to match.
+     * @param content Content to check.
      */
-    @SuppressWarnings("TypeMayBeWeakened")
-    protected void jsonEquals(String json, String ptrn) {
-        assertTrue("JSON mismatch [json=" + json + ", ptrn=" + ptrn + ']', Pattern.matches(ptrn, json));
-    }
+    private void assertResponseContainsError(String content) throws IOException {
+        assertNotNull(content);
+        assertFalse(content.isEmpty());
 
-    /**
-     * @param res Response.
-     * @param success Success flag.
-     * @return Regex pattern for JSON.
-     */
-    private String cachePattern(String res, boolean success) {
-        return "\\{\\\"affinityNodeId\\\":\\\"\\w{8}-\\w{4}-\\w{4}-\\w{4}-\\w{12}\\\"\\," +
-            "\\\"error\\\":\\\"\\\"\\," +
-            "\\\"response\\\":\\\"" + res + "\\\"\\," +
-            "\\\"sessionToken\\\":\\\"" + (securityEnabled() && success ? ".+" : "") + "\\\"," +
-            "\\\"successStatus\\\":" + (success ? 0 : 1) + "\\}";
-    }
+        JsonNode node = JSON_MAPPER.readTree(content);
 
-    /**
-     * @param err Error.
-     * @return Regex pattern for JSON.
-     */
-    private String errorPattern(String err) {
-        return "\\{" +
-            "\\\"error\\\":\\\"" + err + "\\\"\\," +
-            "\\\"response\\\":null\\," +
-            "\\\"sessionToken\\\":\\\"\\\"," +
-            "\\\"successStatus\\\":" + 1 + "\\}";
+        assertEquals(1, node.get("successStatus").asInt());
+        assertFalse(node.get("error").asText().isEmpty());
+        assertTrue(node.get("response").isNull());
+        assertTrue(node.get("sessionToken").asText().isEmpty());
     }
 
     /**
-     * @param res Response.
-     * @param success Success flag.
-     * @return Regex pattern for JSON.
+     * @param content Content to check.
+     * @param err Error message.
      */
-    private String integerPattern(int res, boolean success) {
-        return "\\{\\\"error\\\":\\\"\\\"\\," +
-            "\\\"response\\\":" + res + "\\," +
-            "\\\"sessionToken\\\":\\\"" + (securityEnabled() && success ? ".+" : "") + "\\\"," +
-            "\\\"successStatus\\\":" + (success ? 0 : 1) + "\\}";
-    }
+    private void assertResponseContainsError(String content, String err) throws IOException {
+        assertNotNull(content);
+        assertFalse(content.isEmpty());
 
-    /**
-     * @param res Response.
-     * @param success Success flag.
-     * @return Regex pattern for JSON.
-     */
-    private String cacheBulkPattern(String res, boolean success) {
-        return "\\{\\\"affinityNodeId\\\":\\\"\\\"\\," +
-            "\\\"error\\\":\\\"\\\"\\," +
-            "\\\"response\\\":" + res + "\\," +
-            "\\\"sessionToken\\\":\\\"" + (securityEnabled() && success ? ".+" : "") + "\\\"," +
-            "\\\"successStatus\\\":" + (success ? 0 : 1) + "\\}";
+        assertNotNull(err);
+
+        JsonNode node = JSON_MAPPER.readTree(content);
+
+        assertEquals(1, node.get("successStatus").asInt());
+
+        assertTrue(node.get("response").isNull());
+        assertEquals(err, node.get("error").asText());
     }
 
     /**
-     * @param res Response.
-     * @param success Success flag.
-     * @return Regex pattern for JSON.
+     * @param content Content to check.
      */
-    private String cacheBulkPattern(int res, boolean success) {
-        return "\\{\\\"affinityNodeId\\\":\\\"\\\"\\," +
-            "\\\"error\\\":\\\"\\\"\\," +
-            "\\\"response\\\":" + res + "\\," +
-            "\\\"sessionToken\\\":\\\"" + (securityEnabled() && success ? ".+" : "") + "\\\"," +
-            "\\\"successStatus\\\":" + (success ? 0 : 1) + "\\}";
+    private JsonNode jsonCacheOperationResponse(String content, boolean bulk) throws IOException {
+        assertNotNull(content);
+        assertFalse(content.isEmpty());
+
+        JsonNode node = JSON_MAPPER.readTree(content);
+
+        assertEquals(bulk, node.get("affinityNodeId").asText().isEmpty());
+        assertEquals(0, node.get("successStatus").asInt());
+        assertTrue(node.get("error").asText().isEmpty());
+
+        assertNotSame(securityEnabled(), node.get("sessionToken").asText().isEmpty());
+
+        return node.get("response");
     }
 
     /**
+     * @param content Content to check.
      * @param res Response.
-     * @param success Success flag.
-     * @return Regex pattern for JSON.
      */
-    private String cachePattern(boolean res, boolean success) {
-        return "\\{\\\"affinityNodeId\\\":\\\"\\w{8}-\\w{4}-\\w{4}-\\w{4}-\\w{12}\\\"\\," +
-            "\\\"error\\\":\\\"\\\"\\," +
-            "\\\"response\\\":" + res + "\\," +
-            "\\\"sessionToken\\\":\\\"" + (securityEnabled() && success ? ".+" : "") + "\\\"," +
-            "\\\"successStatus\\\":" + (success ? 0 : 1) + "\\}";
+    private void assertCacheOperation(String content, Object res) throws IOException {
+        JsonNode ret = jsonCacheOperationResponse(content, false);
+
+        assertEquals(String.valueOf(res), ret.asText());
     }
 
     /**
+     * @param content Content to check.
      * @param res Response.
-     * @param success Success flag.
-     * @return Regex pattern for JSON.
      */
-    private String cacheBulkPattern(boolean res, boolean success) {
-        return "\\{\\\"affinityNodeId\\\":\\\"\\\"\\," +
-            "\\\"error\\\":\\\"\\\"\\," +
-            "\\\"response\\\":" + res + "\\," +
-            "\\\"sessionToken\\\":\\\"" + (securityEnabled() && success ? ".+" : "") + "\\\"," +
-            "\\\"successStatus\\\":" + (success ? 0 : 1) + "\\}";
+    private void assertCacheBulkOperation(String content, Object res) throws IOException {
+        JsonNode ret = jsonCacheOperationResponse(content, true);
+
+        assertEquals(String.valueOf(res), ret.asText());
     }
 
     /**
-     * @param res Response.
-     * @param success Success flag.
-     * @return Regex pattern for JSON.
+     * @param content Content to check.
      */
-    private String cacheMetricsPattern(String res, boolean success) {
-        return "\\{\\\"affinityNodeId\\\":\\\"(\\w{8}-\\w{4}-\\w{4}-\\w{4}-\\w{12})?\\\"\\," +
-            "\\\"error\\\":\\\"\\\"\\," +
-            "\\\"response\\\":" + res + "\\," +
-            "\\\"sessionToken\\\":\\\"" + (securityEnabled() && success ? ".+" : "") + "\\\"," +
-            "\\\"successStatus\\\":" + (success ? 0 : 1) + "\\}";
+    private void assertCacheMetrics(String content) throws IOException {
+        JsonNode ret = jsonCacheOperationResponse(content, true);
+
+        assertTrue(ret.isObject());
     }
 
     /**
-     * @param res Response.
-     * @param success Success flag.
-     * @return Regex pattern for JSON.
+     * @param content Content to check.
+     * @return REST result.
      */
-    protected String pattern(String res, boolean success) {
-        return "\\{\\\"error\\\":\\\"" + (!success ? ".+" : "") + "\\\"\\," +
-            "\\\"response\\\":" + res + "\\," +
-            "\\\"sessionToken\\\":\\\"" + (securityEnabled() && success ? ".+" : "") + "\\\"," +
-            "\\\"successStatus\\\":" + (success ? 0 : 1) + "\\}";
+    protected JsonNode jsonResponse(String content) throws IOException {
+        assertNotNull(content);
+        assertFalse(content.isEmpty());
+
+        JsonNode node = JSON_MAPPER.readTree(content);
+
+        assertEquals(0, node.get("successStatus").asInt());
+        assertTrue(node.get("error").asText().isEmpty());
+
+        assertNotSame(securityEnabled(), node.get("sessionToken").asText().isEmpty());
+
+        return node.get("response");
     }
 
     /**
-     * @param res Response.
-     * @param success Success flag.
-     * @return Regex pattern for JSON.
+     * @param content Content to check.
+     * @return Task result.
      */
-    private String stringPattern(String res, boolean success) {
-        return "\\{\\\"error\\\":\\\"" + (!success ? ".+" : "") + "\\\"\\," +
-            "\\\"response\\\":\\\"" + res + "\\\"\\," +
-            "\\\"sessionToken\\\":\\\"" + (securityEnabled() && success ? ".+" : "") + "\\\"," +
-            "\\\"successStatus\\\":" + (success ? 0 : 1) + "\\}";
+    protected JsonNode jsonTaskResult(String content) throws IOException {
+        assertNotNull(content);
+        assertFalse(content.isEmpty());
+
+        JsonNode node = JSON_MAPPER.readTree(content);
+
+        assertEquals(0, node.get("successStatus").asInt());
+        assertTrue(node.get("error").asText().isEmpty());
+        assertFalse(node.get("response").isNull());
+
+        assertEquals(securityEnabled(), !node.get("sessionToken").asText().isEmpty());
+
+        JsonNode res = node.get("response");
+
+        assertTrue(res.isObject());
+
+        assertFalse(res.get("id").asText().isEmpty());
+        assertTrue(res.get("finished").asBoolean());
+        assertTrue(res.get("error").asText().isEmpty());
+
+        return res.get("result");
     }
 
     /**
@@ -326,12 +325,9 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
 
         String ret = content(F.asMap("cmd", GridRestCommand.CACHE_GET.key(), "key", "getKey"));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
         info("Get command result: " + ret);
 
-        jsonEquals(ret, cachePattern("getVal", true));
+        assertCacheOperation(ret, "getVal");
     }
 
     /**
@@ -344,12 +340,9 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
 
         String ret = content(F.asMap("cmd", GridRestCommand.CACHE_SIZE.key()));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
         info("Size command result: " + ret);
 
-        jsonEquals(ret, cacheBulkPattern(1, true));
+        assertCacheBulkOperation(ret, 1);
     }
 
     /**
@@ -358,12 +351,9 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
     public void testIgniteName() throws Exception {
         String ret = content(F.asMap("cmd", GridRestCommand.NAME.key()));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
         info("Name command result: " + ret);
 
-        jsonEquals(ret, stringPattern(getTestGridName(0), true));
+        assertEquals(getTestGridName(0), jsonResponse(ret).asText());
     }
 
     /**
@@ -372,17 +362,13 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
     public void testGetOrCreateCache() throws Exception {
         String ret = content(F.asMap("cmd", GridRestCommand.GET_OR_CREATE_CACHE.key(), "cacheName", "testCache"));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
         info("Name command result: " + ret);
 
         grid(0).cache("testCache").put("1", "1");
 
         ret = content(F.asMap("cmd", GridRestCommand.DESTROY_CACHE.key(), "cacheName", "testCache"));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
+        assertTrue(jsonResponse(ret).isNull());
 
         assertNull(grid(0).cache("testCache"));
     }
@@ -391,20 +377,19 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
      * @throws Exception If failed.
      */
     public void testGetAll() throws Exception {
-        jcache().put("getKey1", "getVal1");
-        jcache().put("getKey2", "getVal2");
+        final Map<String, String> entries = F.asMap("getKey1", "getVal1", "getKey2", "getVal2");
 
-        String ret = content(F.asMap("cmd", GridRestCommand.CACHE_GET_ALL.key(), "k1", "getKey1", "k2", "getKey2"));
+        jcache().putAll(entries);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
+        String ret = content(F.asMap("cmd", GridRestCommand.CACHE_GET_ALL.key(), "k1", "getKey1", "k2", "getKey2"));
 
         info("Get all command result: " + ret);
 
-        jsonEquals(ret,
-            // getKey[12] is used since the order is not determined.
-            cacheBulkPattern("\\{\\\"getKey[12]\\\":\\\"getVal[12]\\\"\\,\\\"getKey[12]\\\":\\\"getVal[12]\\\"\\}",
-                true));
+        JsonNode res = jsonCacheOperationResponse(ret, true);
+
+        assertTrue(res.isObject());
+
+        assertTrue(entries.equals(JSON_MAPPER.treeToValue(res, Map.class)));
     }
 
     /**
@@ -413,9 +398,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
     public void testIncorrectPut() throws Exception {
         String ret = content(F.asMap("cmd", GridRestCommand.CACHE_PUT.key(), "key", "key0"));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-        jsonEquals(ret, errorPattern("Failed to find mandatory parameter in request: val"));
+        assertResponseContainsError(ret, "Failed to find mandatory parameter in request: val");
     }
 
     /**
@@ -426,10 +409,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
 
         String ret = content(F.asMap("cmd", GridRestCommand.CACHE_CONTAINS_KEY.key(), "key", "key0"));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, cachePattern(true, true));
+        assertCacheOperation(ret, true);
     }
 
     /**
@@ -442,10 +422,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
         String ret = content(F.asMap("cmd", GridRestCommand.CACHE_CONTAINS_KEYS.key(),
             "k1", "key0", "k2", "key1"));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, cacheBulkPattern(true, true));
+        assertCacheBulkOperation(ret, true);
     }
 
     /**
@@ -456,10 +433,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
 
         String ret = content(F.asMap("cmd", GridRestCommand.CACHE_GET_AND_PUT.key(), "key", "key0", "val", "val1"));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, cachePattern("val0", true));
+        assertCacheOperation(ret, "val0");
 
         assertEquals("val1", grid(0).cache(null).get("key0"));
     }
@@ -473,10 +447,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
         String ret = content(F.asMap("cmd", GridRestCommand.CACHE_GET_AND_PUT_IF_ABSENT.key(),
             "key", "key0", "val", "val1"));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, cachePattern("val0", true));
+        assertCacheOperation(ret, "val0");
 
         assertEquals("val0", grid(0).cache(null).get("key0"));
     }
@@ -488,10 +459,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
         String ret = content(F.asMap("cmd", GridRestCommand.CACHE_PUT_IF_ABSENT.key(),
             "key", "key0", "val", "val1"));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, cachePattern(true, true));
+        assertCacheOperation(ret, true);
 
         assertEquals("val1", grid(0).cache(null).get("key0"));
     }
@@ -505,20 +473,14 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
         String ret = content(F.asMap("cmd", GridRestCommand.CACHE_REMOVE_VALUE.key(),
             "key", "key0", "val", "val1"));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, cachePattern(false, true));
+        assertCacheOperation(ret, false);
 
         assertEquals("val0", grid(0).cache(null).get("key0"));
 
         ret = content(F.asMap("cmd", GridRestCommand.CACHE_REMOVE_VALUE.key(),
             "key", "key0", "val", "val0"));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, cachePattern(true, true));
+        assertCacheOperation(ret, true);
 
         assertNull(grid(0).cache(null).get("key0"));
     }
@@ -532,10 +494,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
         String ret = content(F.asMap("cmd", GridRestCommand.CACHE_GET_AND_REMOVE.key(),
             "key", "key0"));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, cachePattern("val0", true));
+        assertCacheOperation(ret, "val0");
 
         assertNull(grid(0).cache(null).get("key0"));
     }
@@ -549,20 +508,14 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
         String ret = content(F.asMap("cmd", GridRestCommand.CACHE_REPLACE_VALUE.key(),
             "key", "key0", "val", "val1", "val2", "val2"));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, cachePattern(false, true));
+        assertCacheOperation(ret, false);
 
         assertEquals("val0", grid(0).cache(null).get("key0"));
 
         ret = content(F.asMap("cmd", GridRestCommand.CACHE_REPLACE_VALUE.key(),
             "key", "key0", "val", "val1", "val2", "val0"));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, cachePattern(true, true));
+        assertCacheOperation(ret, true);
 
         assertEquals("val1", grid(0).cache(null).get("key0"));
     }
@@ -576,10 +529,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
         String ret = content(F.asMap("cmd", GridRestCommand.CACHE_GET_AND_REPLACE.key(),
             "key", "key0", "val", "val1"));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, cachePattern("val0", true));
+        assertCacheOperation(ret, "val0");
 
         assertEquals("val1", grid(0).cache(null).get("key0"));
     }
@@ -591,14 +541,11 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
         String ret = content(F.asMap("cmd", GridRestCommand.CACHE_PUT.key(),
             "key", "putKey", "val", "putVal"));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
         info("Put command result: " + ret);
 
         assertEquals("putVal", jcache().localPeek("putKey", CachePeekMode.ONHEAP));
 
-        jsonEquals(ret, cachePattern(true, true));
+        assertCacheOperation(ret, true);
     }
 
     /**
@@ -608,10 +555,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
         String ret = content(F.asMap("cmd", GridRestCommand.CACHE_PUT.key(),
             "key", "putKey", "val", "putVal", "exp", "2000"));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, cachePattern(true, true));
+        assertCacheOperation(ret, true);
 
         assertEquals("putVal", jcache().get("putKey"));
 
@@ -629,10 +573,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
         String ret = content(F.asMap("cmd", GridRestCommand.CACHE_ADD.key(),
             "key", "addKey2", "val", "addVal2"));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, cachePattern(true, true));
+        assertCacheOperation(ret, true);
 
         assertEquals("addVal1", jcache().localPeek("addKey1", CachePeekMode.ONHEAP));
         assertEquals("addVal2", jcache().localPeek("addKey2", CachePeekMode.ONHEAP));
@@ -645,10 +586,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
         String ret = content(F.asMap("cmd", GridRestCommand.CACHE_ADD.key(),
             "key", "addKey", "val", "addVal", "exp", "2000"));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, cachePattern(true, true));
+        assertCacheOperation(ret, true);
 
         assertEquals("addVal", jcache().get("addKey"));
 
@@ -665,15 +603,12 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
             "k1", "putKey1", "k2", "putKey2",
             "v1", "putVal1", "v2", "putVal2"));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
         info("Put all command result: " + ret);
 
         assertEquals("putVal1", jcache().localPeek("putKey1", CachePeekMode.ONHEAP));
         assertEquals("putVal2", jcache().localPeek("putKey2", CachePeekMode.ONHEAP));
 
-        jsonEquals(ret, cacheBulkPattern(true, true));
+        assertCacheBulkOperation(ret, true);
     }
 
     /**
@@ -687,14 +622,11 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
         String ret = content(F.asMap("cmd", GridRestCommand.CACHE_REMOVE.key(),
             "key", "rmvKey"));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
         info("Remove command result: " + ret);
 
         assertNull(jcache().localPeek("rmvKey", CachePeekMode.ONHEAP));
 
-        jsonEquals(ret, cachePattern(true, true));
+        assertCacheOperation(ret, true);
     }
 
     /**
@@ -714,9 +646,6 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
         String ret = content(F.asMap("cmd", GridRestCommand.CACHE_REMOVE_ALL.key(),
             "k1", "rmvKey1", "k2", "rmvKey2"));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
         info("Remove all command result: " + ret);
 
         assertNull(jcache().localPeek("rmvKey1", CachePeekMode.ONHEAP));
@@ -724,13 +653,10 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
         assertEquals("rmvVal3", jcache().localPeek("rmvKey3", CachePeekMode.ONHEAP));
         assertEquals("rmvVal4", jcache().localPeek("rmvKey4", CachePeekMode.ONHEAP));
 
-        jsonEquals(ret, cacheBulkPattern(true, true));
+        assertCacheBulkOperation(ret, true);
 
         ret = content(F.asMap("cmd", GridRestCommand.CACHE_REMOVE_ALL.key()));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
         info("Remove all command result: " + ret);
 
         assertNull(jcache().localPeek("rmvKey1", CachePeekMode.ONHEAP));
@@ -739,7 +665,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
         assertNull(jcache().localPeek("rmvKey4", CachePeekMode.ONHEAP));
         assertTrue(jcache().localSize() == 0);
 
-        jsonEquals(ret, cacheBulkPattern(true, true));
+        assertCacheBulkOperation(ret, true);
     }
 
     /**
@@ -753,14 +679,11 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
         String ret = content(F.asMap("cmd", GridRestCommand.CACHE_CAS.key(),
             "key", "casKey", "val2", "casOldVal", "val1", "casNewVal"));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
         info("CAS command result: " + ret);
 
         assertEquals("casNewVal", jcache().localPeek("casKey", CachePeekMode.ONHEAP));
 
-        jsonEquals(ret, cachePattern(true, true));
+        assertCacheOperation(ret, true);
 
         jcache().remove("casKey");
     }
@@ -776,14 +699,11 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
         String ret = content(F.asMap("cmd", GridRestCommand.CACHE_REPLACE.key(),
             "key", "repKey", "val", "repVal"));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
         info("Replace command result: " + ret);
 
         assertEquals("repVal", jcache().localPeek("repKey", CachePeekMode.ONHEAP));
 
-        jsonEquals(ret, cachePattern(true, true));
+        assertCacheOperation(ret, true);
     }
 
     /**
@@ -797,10 +717,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
         String ret = content(F.asMap("cmd", GridRestCommand.CACHE_REPLACE.key(),
             "key", "replaceKey", "val", "replaceValNew", "exp", "2000"));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, cachePattern(true, true));
+        assertCacheOperation(ret, true);
 
         assertEquals("replaceValNew", jcache().get("replaceKey"));
 
@@ -819,10 +736,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
         String ret = content(F.asMap("cmd", GridRestCommand.CACHE_APPEND.key(),
             "key", "appendKey", "val", "_suffix"));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, cachePattern(true, true));
+        assertCacheOperation(ret, true);
 
         assertEquals("appendVal_suffix", jcache().get("appendKey"));
     }
@@ -836,10 +750,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
         String ret = content(F.asMap("cmd", GridRestCommand.CACHE_PREPEND.key(),
             "key", "prependKey", "val", "prefix_"));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, cachePattern(true, true));
+        assertCacheOperation(ret, true);
 
         assertEquals("prefix_prependVal", jcache().get("prependKey"));
     }
@@ -851,20 +762,16 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
         String ret = content(F.asMap("cmd", GridRestCommand.ATOMIC_INCREMENT.key(),
             "key", "incrKey", "init", "2", "delta", "3"));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, integerPattern(5, true));
+        JsonNode res = jsonResponse(ret);
 
+        assertEquals(5, res.asInt());
         assertEquals(5, grid(0).atomicLong("incrKey", 0, true).get());
 
         ret = content(F.asMap("cmd", GridRestCommand.ATOMIC_INCREMENT.key(), "key", "incrKey", "delta", "10"));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, integerPattern(15, true));
+        res = jsonResponse(ret);
 
+        assertEquals(15, res.asInt());
         assertEquals(15, grid(0).atomicLong("incrKey", 0, true).get());
     }
 
@@ -875,21 +782,17 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
         String ret = content(F.asMap("cmd", GridRestCommand.ATOMIC_DECREMENT.key(),
             "key", "decrKey", "init", "15", "delta", "10"));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, integerPattern(5, true));
+        JsonNode res = jsonResponse(ret);
 
+        assertEquals(5, res.asInt());
         assertEquals(5, grid(0).atomicLong("decrKey", 0, true).get());
 
         ret = content(F.asMap("cmd", GridRestCommand.ATOMIC_DECREMENT.key(),
             "key", "decrKey", "delta", "3"));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, integerPattern(2, true));
+        res = jsonResponse(ret);
 
+        assertEquals(2, res.asInt());
         assertEquals(2, grid(0).atomicLong("decrKey", 0, true).get());
     }
 
@@ -904,14 +807,11 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
         String ret = content(F.asMap("cmd", GridRestCommand.CACHE_CAS.key(),
             "key", "casKey", "val2", "casOldVal"));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
         info("CAR command result: " + ret);
 
         assertNull(jcache().localPeek("casKey", CachePeekMode.ONHEAP));
 
-        jsonEquals(ret, cachePattern(true, true));
+        assertCacheOperation(ret, true);
     }
 
     /**
@@ -923,14 +823,11 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
         String ret = content(F.asMap("cmd", GridRestCommand.CACHE_CAS.key(),
             "key", "casKey", "val1", "casNewVal"));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
         info("PutIfAbsent command result: " + ret);
 
         assertEquals("casNewVal", jcache().localPeek("casKey", CachePeekMode.ONHEAP));
 
-        jsonEquals(ret, cachePattern(true, true));
+        assertCacheOperation(ret, true);
     }
 
     /**
@@ -943,14 +840,11 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
 
         String ret = content(F.asMap("cmd", GridRestCommand.CACHE_CAS.key(), "key", "casKey"));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
         info("CAS Remove command result: " + ret);
 
         assertNull(jcache().localPeek("casKey", CachePeekMode.ONHEAP));
 
-        jsonEquals(ret, cachePattern(true, true));
+        assertCacheOperation(ret, true);
     }
 
     /**
@@ -959,12 +853,9 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
     public void testMetrics() throws Exception {
         String ret = content(F.asMap("cmd", GridRestCommand.CACHE_METRICS.key()));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
         info("Cache metrics command result: " + ret);
 
-        jsonEquals(ret, cacheMetricsPattern("\\{.+\\}", true));
+        assertCacheMetrics(ret);
     }
 
     /**
@@ -981,20 +872,16 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
 
         String ret = content(params);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
         info("Cache metadata result: " + ret);
 
-        jsonEquals(ret, pattern("\\[.+\\]", true));
+        JsonNode arr = jsonResponse(ret);
 
-        Collection<Map> results = (Collection)JSONObject.fromObject(ret).get("response");
+        assertTrue(arr.isArray());
+        assertEquals(metas.size(), arr.size());
 
-        assertEquals(metas.size(), results.size());
-        assertEquals(cacheNameArg, F.first(results).get("cacheName"));
-
-        for (Map res : results) {
-            final Object cacheName = res.get("cacheName");
+        for (JsonNode item : arr) {
+            JsonNode cacheNameNode = item.get("cacheName");
+            final String cacheName = cacheNameNode != null ? cacheNameNode.asText() : null;
 
             GridCacheSqlMetadata meta = F.find(metas, null, new P1<GridCacheSqlMetadata>() {
                 @Override public boolean apply(GridCacheSqlMetadata meta) {
@@ -1004,49 +891,60 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
 
             assertNotNull("REST return metadata for unexpected cache: " + cacheName, meta);
 
-            Collection types = (Collection)res.get("types");
+            JsonNode types = item.get("types");
 
             assertNotNull(types);
-            assertEqualsCollections(meta.types(), types);
+            assertFalse(types.isNull());
+
+            assertEqualsCollections(meta.types(), JSON_MAPPER.treeToValue(types, Collection.class));
 
-            Map keyClasses = (Map)res.get("keyClasses");
+            JsonNode keyClasses = item.get("keyClasses");
 
             assertNotNull(keyClasses);
-            assertTrue(meta.keyClasses().equals(keyClasses));
+            assertFalse(keyClasses.isNull());
+
+            assertTrue(meta.keyClasses().equals(JSON_MAPPER.treeToValue(keyClasses, Map.class)));
 
-            Map valClasses = (Map)res.get("valClasses");
+            JsonNode valClasses = item.get("valClasses");
 
             assertNotNull(valClasses);
-            assertTrue(meta.valClasses().equals(valClasses));
+            assertFalse(valClasses.isNull());
 
-            Map fields = (Map)res.get("fields");
+            assertTrue(meta.valClasses().equals(JSON_MAPPER.treeToValue(valClasses, Map.class)));
+
+            JsonNode fields = item.get("fields");
 
             assertNotNull(fields);
-            assertTrue(meta.fields().equals(fields));
+            assertFalse(fields.isNull());
+            assertTrue(meta.fields().equals(JSON_MAPPER.treeToValue(fields, Map.class)));
 
-            Map indexesByType = (Map)res.get("indexes");
+            JsonNode indexesByType = item.get("indexes");
 
             assertNotNull(indexesByType);
+            assertFalse(indexesByType.isNull());
             assertEquals(meta.indexes().size(), indexesByType.size());
 
             for (Map.Entry<String, Collection<GridCacheSqlIndexMetadata>> metaIndexes : meta.indexes().entrySet()) {
-                Collection<Map> indexes = (Collection<Map>)indexesByType.get(metaIndexes.getKey());
+                JsonNode indexes = indexesByType.get(metaIndexes.getKey());
 
                 assertNotNull(indexes);
+                assertFalse(indexes.isNull());
                 assertEquals(metaIndexes.getValue().size(), indexes.size());
 
                 for (final GridCacheSqlIndexMetadata metaIdx : metaIndexes.getValue()) {
-                    Map idx = F.find(indexes, null, new P1<Map>() {
-                        @Override public boolean apply(Map map) {
-                            return metaIdx.name().equals(map.get("name"));
+                    JsonNode idx = F.find(indexes, null, new P1<JsonNode>() {
+                        @Override public boolean apply(JsonNode idx) {
+                            return metaIdx.name().equals(idx.get("name").asText());
                         }
                     });
 
                     assertNotNull(idx);
 
-                    assertEqualsCollections(metaIdx.fields(), (Collection)idx.get("fields"));
-                    assertEqualsCollections(metaIdx.descendings(), (Collection)idx.get("descendings"));
-                    assertEquals(metaIdx.unique(), idx.get("unique"));
+                    assertEqualsCollections(metaIdx.fields(),
+                        JSON_MAPPER.treeToValue(idx.get("fields"), Collection.class));
+                    assertEqualsCollections(metaIdx.descendings(),
+                        JSON_MAPPER.treeToValue(idx.get("descendings"), Collection.class));
+                    assertEquals(metaIdx.unique(), idx.get("unique").asBoolean());
                 }
             }
         }
@@ -1087,32 +985,28 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
     public void testTopology() throws Exception {
         String ret = content(F.asMap("cmd", GridRestCommand.TOPOLOGY.key(), "attr", "false", "mtr", "false"));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
         info("Topology command result: " + ret);
 
-        jsonEquals(ret, pattern("\\[\\{.+\\}\\]", true));
-
-        JSONObject json = JSONObject.fromObject(ret);
+        JsonNode res = jsonResponse(ret);
 
-        Collection<Map> nodes = (Collection)json.get("response");
+        assertEquals(GRID_CNT, res.size());
 
-        assertEquals(GRID_CNT, nodes.size());
+        for (JsonNode node : res) {
+            assertTrue(node.get("attributes").isNull());
+            assertTrue(node.get("metrics").isNull());
 
-        for (Map node : nodes) {
-            assertEquals(JSONNull.getInstance(), node.get("attributes"));
-            assertEquals(JSONNull.getInstance(), node.get("metrics"));
+            JsonNode caches = node.get("caches");
 
-            Collection<Map> caches = (Collection)node.get("caches");
+            assertFalse(caches.isNull());
 
             Collection<IgniteCacheProxy<?, ?>> publicCaches = grid(0).context().cache().publicCaches();
 
-            assertNotNull(caches);
             assertEquals(publicCaches.size(), caches.size());
 
-            for (Map cache : caches) {
-                final String cacheName = cache.get("name").equals("") ? null : (String)cache.get("name");
+            for (JsonNode cache : caches) {
+                String cacheName0 = cache.get("name").asText();
+
+                final String cacheName = cacheName0.equals("") ? null : cacheName0;
 
                 IgniteCacheProxy<?, ?> publicCache = F.find(publicCaches, null, new P1<IgniteCacheProxy<?, ?>>() {
                     @Override public boolean apply(IgniteCacheProxy<?, ?> c) {
@@ -1122,9 +1016,9 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
 
                 assertNotNull(publicCache);
 
-                CacheMode cacheMode = CacheMode.valueOf((String)cache.get("mode"));
+                CacheMode cacheMode = CacheMode.valueOf(cache.get("mode").asText());
 
-                assertEquals(publicCache.getConfiguration(CacheConfiguration.class).getCacheMode(),cacheMode);
+                assertEquals(publicCache.getConfiguration(CacheConfiguration.class).getCacheMode(), cacheMode);
             }
         }
     }
@@ -1136,31 +1030,30 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
         String ret = content(F.asMap("cmd", GridRestCommand.NODE.key(), "attr", "true", "mtr", "true", "id",
             grid(0).localNode().id().toString()));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
         info("Topology command result: " + ret);
 
-        jsonEquals(ret, pattern("\\{.+\\}", true));
+        JsonNode res = jsonResponse(ret);
 
-        ret = content(F.asMap("cmd", GridRestCommand.NODE.key(), "attr", "false", "mtr", "false", "ip", LOC_HOST));
+        assertTrue(res.get("attributes").isObject());
+        assertTrue(res.get("metrics").isObject());
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
+        ret = content(F.asMap("cmd", GridRestCommand.NODE.key(), "attr", "false", "mtr", "false", "ip", LOC_HOST));
 
         info("Topology command result: " + ret);
 
-        jsonEquals(ret, pattern("\\{.+\\}", true));
+        res = jsonResponse(ret);
+
+        assertTrue(res.get("attributes").isNull());
+        assertTrue(res.get("metrics").isNull());
 
         ret = content(F.asMap("cmd", GridRestCommand.NODE.key(), "attr", "false", "mtr", "false", "ip", LOC_HOST, "id",
             UUID.randomUUID().toString()));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
         info("Topology command result: " + ret);
 
-        jsonEquals(ret, pattern("null", true));
+        res = jsonResponse(ret);
+
+        assertTrue(res.isNull());
     }
 
     /**
@@ -1173,52 +1066,41 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
     public void testExe() throws Exception {
         String ret = content(F.asMap("cmd", GridRestCommand.EXE.key()));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
         info("Exe command result: " + ret);
 
-        jsonEquals(ret, pattern("null", false));
+        assertResponseContainsError(ret);
 
         // Attempt to execute unknown task (UNKNOWN_TASK) will result in exception on server.
         ret = content(F.asMap("cmd", GridRestCommand.EXE.key(), "name", "UNKNOWN_TASK"));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
         info("Exe command result: " + ret);
 
-        jsonEquals(ret, pattern("null", false));
+        assertResponseContainsError(ret);
 
         grid(0).compute().localDeployTask(TestTask1.class, TestTask1.class.getClassLoader());
         grid(0).compute().localDeployTask(TestTask2.class, TestTask2.class.getClassLoader());
 
         ret = content(F.asMap("cmd", GridRestCommand.EXE.key(), "name", TestTask1.class.getName()));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
         info("Exe command result: " + ret);
 
-        jsonEquals(ret, pattern("\\{.+\\}", true));
+        JsonNode res = jsonTaskResult(ret);
 
-        ret = content(F.asMap("cmd", GridRestCommand.EXE.key(), "name", TestTask2.class.getName()));
+        assertTrue(res.isNull());
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
+        ret = content(F.asMap("cmd", GridRestCommand.EXE.key(), "name", TestTask2.class.getName()));
 
         info("Exe command result: " + ret);
 
-        jsonEquals(ret, pattern("\\{.+" + TestTask2.RES + ".+\\}", true));
+        res = jsonTaskResult(ret);
 
-        ret = content(F.asMap("cmd", GridRestCommand.RESULT.key()));
+        assertEquals(TestTask2.RES, res.asText());
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
+        ret = content(F.asMap("cmd", GridRestCommand.RESULT.key()));
 
         info("Exe command result: " + ret);
 
-        jsonEquals(ret, pattern("null", false));
+        assertResponseContainsError(ret);
     }
 
     /**
@@ -1229,9 +1111,6 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
     public void testVisorGateway() throws Exception {
         ClusterNode locNode = grid(1).localNode();
 
-        final String successRes = pattern(
-            "\\{\\\"error\\\":\\\"\\\",\\\"finished\\\":true,\\\"id\\\":\\\"[^\\\"]+\\\",\\\"result\\\":.+}", true);
-
         final IgniteUuid cid = grid(1).context().cache().internalCache("person").context().dynamicDeploymentId();
 
         String ret = content(new VisorGatewayArgument(VisorCacheConfigurationCollectorTask.class)
@@ -1240,10 +1119,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
 
         info("VisorCacheConfigurationCollectorTask result: " + ret);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, successRes);
+        jsonTaskResult(ret);
 
         ret = content(new VisorGatewayArgument(VisorCacheNodesTask.class)
             .forNode(locNode)
@@ -1251,10 +1127,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
 
         info("VisorCacheNodesTask result: " + ret);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, successRes);
+        jsonTaskResult(ret);
 
         ret = content(new VisorGatewayArgument(VisorCacheLoadTask.class)
             .forNode(locNode)
@@ -1262,10 +1135,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
 
         info("VisorCacheLoadTask result: " + ret);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, successRes);
+        jsonTaskResult(ret);
 
         ret = content(new VisorGatewayArgument(VisorCacheSwapBackupsTask.class)
             .forNode(locNode)
@@ -1273,10 +1143,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
 
         info("VisorCacheSwapBackupsTask result: " + ret);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, successRes);
+        jsonTaskResult(ret);
 
         ret = content(new VisorGatewayArgument(VisorCacheRebalanceTask.class)
             .forNode(locNode)
@@ -1284,10 +1151,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
 
         info("VisorCacheRebalanceTask result: " + ret);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, successRes);
+        jsonTaskResult(ret);
 
         ret = content(new VisorGatewayArgument(VisorCacheMetadataTask.class)
             .forNode(locNode)
@@ -1295,10 +1159,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
 
         info("VisorCacheMetadataTask result: " + ret);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, successRes);
+        jsonTaskResult(ret);
 
         ret = content(new VisorGatewayArgument(VisorCacheResetMetricsTask.class)
             .forNode(locNode)
@@ -1306,10 +1167,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
 
         info("VisorCacheResetMetricsTask result: " + ret);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, successRes);
+        jsonTaskResult(ret);
 
         ret = content(new VisorGatewayArgument(VisorIgfsSamplingStateTask.class)
             .forNode(locNode)
@@ -1317,10 +1175,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
 
         info("VisorIgfsSamplingStateTask result: " + ret);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, successRes);
+        jsonTaskResult(ret);
 
         ret = content(new VisorGatewayArgument(VisorIgfsProfilerClearTask.class)
             .forNode(locNode)
@@ -1328,10 +1183,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
 
         info("VisorIgfsProfilerClearTask result: " + ret);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, successRes);
+        jsonTaskResult(ret);
 
         ret = content(new VisorGatewayArgument(VisorIgfsProfilerTask.class)
             .forNode(locNode)
@@ -1339,10 +1191,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
 
         info("VisorIgfsProfilerTask result: " + ret);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, successRes);
+        jsonTaskResult(ret);
 
         ret = content(new VisorGatewayArgument(VisorIgfsFormatTask.class)
             .forNode(locNode)
@@ -1350,10 +1199,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
 
         info("VisorIgfsFormatTask result: " + ret);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, successRes);
+        jsonTaskResult(ret);
 
         ret = content(new VisorGatewayArgument(VisorIgfsResetMetricsTask.class)
             .forNode(locNode)
@@ -1361,20 +1207,14 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
 
         info("VisorIgfsResetMetricsTask result: " + ret);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, successRes);
+        jsonTaskResult(ret);
 
         ret = content(new VisorGatewayArgument(VisorThreadDumpTask.class)
             .forNode(locNode));
 
         info("VisorThreadDumpTask result: " + ret);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, successRes);
+        jsonTaskResult(ret);
 
         ret = content(new VisorGatewayArgument(VisorLatestTextFilesTask.class)
             .forNode(locNode)
@@ -1382,20 +1222,14 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
 
         info("VisorLatestTextFilesTask result: " + ret);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, successRes);
+        jsonTaskResult(ret);
 
         ret = content(new VisorGatewayArgument(VisorLatestVersionTask.class)
             .forNode(locNode));
 
         info("VisorLatestVersionTask result: " + ret);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, successRes);
+        jsonTaskResult(ret);
 
         ret = content(new VisorGatewayArgument(VisorFileBlockTask.class)
             .forNode(locNode)
@@ -1403,10 +1237,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
 
         info("VisorFileBlockTask result: " + ret);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, successRes);
+        jsonTaskResult(ret);
 
         ret = content(new VisorGatewayArgument(VisorNodePingTask.class)
             .forNode(locNode)
@@ -1414,45 +1245,31 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
 
         info("VisorNodePingTask result: " + ret);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, successRes);
+        jsonTaskResult(ret);
 
         ret = content(new VisorGatewayArgument(VisorNodeConfigurationCollectorTask.class)
             .forNode(locNode));
 
         info("VisorNodeConfigurationCollectorTask result: " + ret);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, successRes);
+        jsonTaskResult(ret);
 
         ret = content(new VisorGatewayArgument(VisorComputeResetMetricsTask.class)
             .forNode(locNode));
 
         info("VisorComputeResetMetricsTask result: " + ret);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, successRes);
+        jsonTaskResult(ret);
 
         ret = content(new VisorGatewayArgument(VisorQueryTask.class)
             .forNode(locNode)
-            .argument(VisorQueryArg.class, "person", URLEncoder.encode("select * from Person"), false, 1));
+            .argument(VisorQueryArg.class, "person", URLEncoder.encode("select * from Person", CHARSET), false, 1));
 
         info("VisorQueryTask result: " + ret);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, successRes);
+        JsonNode res = jsonTaskResult(ret);
 
-        JSONObject json = JSONObject.fromObject(ret);
-
-        final String qryId = (String)((Map)((Map)((Map)json.get("response")).get("result")).get("value")).get("queryId");
+        final String qryId = res.get("value").get("queryId").asText();
 
         ret = content(new VisorGatewayArgument(VisorQueryNextPageTask.class)
             .forNode(locNode)
@@ -1460,30 +1277,21 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
 
         info("VisorQueryNextPageTask result: " + ret);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, successRes);
+        jsonTaskResult(ret);
 
         ret = content(new VisorGatewayArgument(VisorQueryCleanupTask.class)
             .map(UUID.class, Set.class, F.asMap(locNode.id(), qryId)));
 
         info("VisorQueryCleanupTask result: " + ret);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, successRes);
+        jsonTaskResult(ret);
 
         ret = content(new VisorGatewayArgument(VisorResolveHostNameTask.class)
             .forNode(locNode));
 
         info("VisorResolveHostNameTask result: " + ret);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, successRes);
+        jsonTaskResult(ret);
 
         // Multinode tasks
 
@@ -1492,10 +1300,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
 
         info("VisorComputeCancelSessionsTask result: " + ret);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, successRes);
+        jsonTaskResult(ret);
 
         ret = content(new VisorGatewayArgument(VisorCacheMetricsCollectorTask.class)
             .pair(Boolean.class, Set.class, false, "person"));
@@ -1508,39 +1313,27 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
 
         info("VisorCacheMetricsCollectorTask (with nodes) result: " + ret);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, successRes);
+        jsonTaskResult(ret);
 
         ret = content(new VisorGatewayArgument(VisorLogSearchTask.class)
             .argument(VisorLogSearchTask.VisorLogSearchArg.class, ".", ".", "abrakodabra.txt", 1));
 
         info("VisorLogSearchTask result: " + ret);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, successRes);
+        jsonTaskResult(ret);
 
         ret = content(new VisorGatewayArgument(VisorNodeGcTask.class));
 
         info("VisorNodeGcTask result: " + ret);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, successRes);
+        jsonTaskResult(ret);
 
         ret = content(new VisorGatewayArgument(VisorAckTask.class)
             .argument("MSG"));
 
         info("VisorAckTask result: " + ret);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, successRes);
+        jsonTaskResult(ret);
 
         ret = content(new VisorGatewayArgument(VisorNodeEventsCollectorTask.class)
             .argument(VisorNodeEventsCollectorTask.VisorNodeEventsCollectorTaskArg.class,
@@ -1548,10 +1341,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
 
         info("VisorNodeEventsCollectorTask result: " + ret);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, successRes);
+        jsonTaskResult(ret);
 
         ret = content(new VisorGatewayArgument(VisorNodeDataCollectorTask.class)
             .argument(VisorNodeDataCollectorTaskArg.class, false,
@@ -1559,30 +1349,21 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
 
         info("VisorNodeDataCollectorTask result: " + ret);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, successRes);
+        jsonTaskResult(ret);
 
         ret = content(new VisorGatewayArgument(VisorComputeToggleMonitoringTask.class)
             .pair(String.class, Boolean.class, UUID.randomUUID(), false));
 
         info("VisorComputeToggleMonitoringTask result: " + ret);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, successRes);
+        jsonTaskResult(ret);
 
         ret = content(new VisorGatewayArgument(VisorNodeSuppressedErrorsTask.class)
             .map(UUID.class, Long.class, new HashMap()));
 
         info("VisorNodeSuppressedErrorsTask result: " + ret);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, successRes);
+        jsonTaskResult(ret);
 
         ret = content(new VisorGatewayArgument(VisorCacheClearTask.class)
             .forNode(locNode)
@@ -1590,10 +1371,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
 
         info("VisorCacheClearTask result: " + ret);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, successRes);
+        jsonTaskResult(ret);
 
         /** Spring XML to start cache via Visor task. */
         final String START_CACHE =
@@ -1608,14 +1386,12 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
                     "</beans>";
 
         ret = content(new VisorGatewayArgument(VisorCacheStartTask.class)
-            .argument(VisorCacheStartTask.VisorCacheStartArg.class, false, "person2", URLEncoder.encode(START_CACHE)));
+            .argument(VisorCacheStartTask.VisorCacheStartArg.class, false, "person2",
+                URLEncoder.encode(START_CACHE, CHARSET)));
 
         info("VisorCacheStartTask result: " + ret);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, successRes);
+        jsonTaskResult(ret);
 
         ret = content(new VisorGatewayArgument(VisorCacheStopTask.class)
             .forNode(locNode)
@@ -1623,10 +1399,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
 
         info("VisorCacheStopTask result: " + ret);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        jsonEquals(ret, successRes);
+        jsonTaskResult(ret);
     }
 
     /**
@@ -1635,10 +1408,9 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
     public void testVersion() throws Exception {
         String ret = content(F.asMap("cmd", GridRestCommand.VERSION.key()));
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
+        JsonNode res = jsonResponse(ret);
 
-        jsonEquals(ret, stringPattern(".+", true));
+        assertEquals(VER_STR, res.asText());
     }
 
     /**
@@ -1652,18 +1424,13 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
         params.put("type", "Person");
         params.put("pageSize", "10");
         params.put("cacheName", "person");
-        params.put("qry", URLEncoder.encode(qry));
+        params.put("qry", URLEncoder.encode(qry, CHARSET));
         params.put("arg1", "1000");
         params.put("arg2", "2000");
 
         String ret = content(params);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        JSONObject json = JSONObject.fromObject(ret);
-
-        List items = (List)((Map)json.get("response")).get("items");
+        JsonNode items = jsonResponse(ret).get("items");
 
         assertEquals(2, items.size());
 
@@ -1681,12 +1448,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
 
         String ret = content(params);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        JSONObject json = JSONObject.fromObject(ret);
-
-        List items = (List)((Map)json.get("response")).get("items");
+        JsonNode items = jsonResponse(ret).get("items");
 
         assertEquals(4, items.size());
 
@@ -1705,12 +1467,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
 
         String ret = content(params);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        JSONObject json = JSONObject.fromObject(ret);
-
-        List items = (List)((Map)json.get("response")).get("items");
+        JsonNode items = jsonResponse(ret).get("items");
 
         assertEquals(2, items.size());
 
@@ -1721,22 +1478,17 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
      * @throws Exception If failed.
      */
     public void testIncorrectFilterQueryScan() throws Exception {
+        String clsName = ScanFilter.class.getName() + 1;
+
         Map<String, String> params = new HashMap<>();
         params.put("cmd", GridRestCommand.EXECUTE_SCAN_QUERY.key());
         params.put("pageSize", "10");
         params.put("cacheName", "person");
-        params.put("className", ScanFilter.class.getName() + 1);
+        params.put("className", clsName);
 
         String ret = content(params);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        JSONObject json = JSONObject.fromObject(ret);
-
-        String err = (String)json.get("error");
-
-        assertTrue(err.contains("Failed to find target class"));
+        assertResponseContainsError(ret, "Failed to find target class: " + clsName);
     }
 
     /**
@@ -1751,42 +1503,33 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
         params.put("cmd", GridRestCommand.EXECUTE_SQL_QUERY.key());
         params.put("type", "String");
         params.put("pageSize", "1");
-        params.put("qry", URLEncoder.encode("select * from String"));
+        params.put("qry", URLEncoder.encode("select * from String", CHARSET));
 
         String ret = content(params);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
+        JsonNode qryId = jsonResponse(ret).get("queryId");
 
-        JSONObject json = JSONObject.fromObject(ret);
-
-        Integer qryId = (Integer)((Map)json.get("response")).get("queryId");
-
-        assertNotNull(qryId);
+        assertFalse(jsonResponse(ret).get("queryId").isNull());
 
         ret = content(F.asMap("cmd", GridRestCommand.FETCH_SQL_QUERY.key(),
-            "pageSize", "1", "qryId", String.valueOf(qryId)));
-
-        json = JSONObject.fromObject(ret);
+            "pageSize", "1", "qryId", qryId.asText()));
 
-        Integer qryId0 = (Integer)((Map)json.get("response")).get("queryId");
+        JsonNode res = jsonResponse(ret);
 
-        Boolean last = (Boolean)((Map)json.get("response")).get("last");
+        JsonNode qryId0 = jsonResponse(ret).get("queryId");
 
         assertEquals(qryId0, qryId);
-        assertFalse(last);
+        assertFalse(res.get("last").asBoolean());
 
         ret = content(F.asMap("cmd", GridRestCommand.FETCH_SQL_QUERY.key(),
-            "pageSize", "1", "qryId", String.valueOf(qryId)));
+            "pageSize", "1", "qryId", qryId.asText()));
 
-        json = JSONObject.fromObject(ret);
+        res = jsonResponse(ret);
 
-        qryId0 = (Integer)((Map)json.get("response")).get("queryId");
-
-        last = (Boolean)((Map)json.get("response")).get("last");
+        qryId0 = jsonResponse(ret).get("queryId");
 
         assertEquals(qryId0, qryId);
-        assertTrue(last);
+        assertTrue(res.get("last").asBoolean());
 
         assertFalse(queryCursorFound());
     }
@@ -1801,16 +1544,11 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
         params.put("cmd", GridRestCommand.EXECUTE_SQL_FIELDS_QUERY.key());
         params.put("pageSize", "10");
         params.put("cacheName", "person");
-        params.put("qry", URLEncoder.encode(qry));
+        params.put("qry", URLEncoder.encode(qry, CHARSET));
 
         String ret = content(params);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        JSONObject json = JSONObject.fromObject(ret);
-
-        List items = (List)((Map)json.get("response")).get("items");
+        JsonNode items = jsonResponse(ret).get("items");
 
         assertEquals(4, items.size());
 
@@ -1827,29 +1565,25 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
         params.put("cmd", GridRestCommand.EXECUTE_SQL_FIELDS_QUERY.key());
         params.put("pageSize", "10");
         params.put("cacheName", "person");
-        params.put("qry", URLEncoder.encode(qry));
+        params.put("qry", URLEncoder.encode(qry, CHARSET));
 
         String ret = content(params);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        JSONObject json = JSONObject.fromObject(ret);
+        JsonNode res = jsonResponse(ret);
 
-        List items = (List)((Map)json.get("response")).get("items");
+        JsonNode items = res.get("items");
 
-        List meta = (List)((Map)json.get("response")).get("fieldsMetadata");
+        JsonNode meta = res.get("fieldsMetadata");
 
         assertEquals(4, items.size());
-
         assertEquals(2, meta.size());
 
-        JSONObject o = (JSONObject)meta.get(0);
+        JsonNode o = meta.get(0);
 
-        assertEquals("FIRSTNAME", o.get("fieldName"));
-        assertEquals("java.lang.String", o.get("fieldTypeName"));
-        assertEquals("person", o.get("schemaName"));
-        assertEquals("PERSON", o.get("typeName"));
+        assertEquals("FIRSTNAME", o.get("fieldName").asText());
+        assertEquals("java.lang.String", o.get("fieldTypeName").asText());
+        assertEquals("person", o.get("schemaName").asText());
+        assertEquals("PERSON", o.get("typeName").asText());
 
         assertFalse(queryCursorFound());
     }
@@ -1865,32 +1599,23 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
         params.put("type", "Person");
         params.put("pageSize", "1");
         params.put("cacheName", "person");
-        params.put("qry", URLEncoder.encode(qry));
+        params.put("qry", URLEncoder.encode(qry, CHARSET));
         params.put("arg1", "1000");
         params.put("arg2", "2000");
 
         String ret = content(params);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        JSONObject json = JSONObject.fromObject(ret);
-
-        List items = (List)((Map)json.get("response")).get("items");
+        JsonNode res = jsonResponse(ret);
 
-        assertEquals(1, items.size());
+        assertEquals(1, res.get("items").size());
 
         assertTrue(queryCursorFound());
 
-        Integer qryId = (Integer)((Map)json.get("response")).get("queryId");
-
-        assertNotNull(qryId);
+        assertFalse(res.get("queryId").isNull());
 
-        ret = content(F.asMap("cmd", GridRestCommand.CLOSE_SQL_QUERY.key(),
-            "cacheName", "person", "qryId", String.valueOf(qryId)));
+        String qryId = res.get("queryId").asText();
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
+        content(F.asMap("cmd", GridRestCommand.CLOSE_SQL_QUERY.key(), "cacheName", "person", "qryId", qryId));
 
         assertFalse(queryCursorFound());
     }
@@ -1906,7 +1631,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
         params.put("type", "Person");
         params.put("pageSize", "1");
         params.put("cacheName", "person");
-        params.put("qry", URLEncoder.encode(qry));
+        params.put("qry", URLEncoder.encode(qry, CHARSET));
         params.put("arg1", "1000");
         params.put("arg2", "2000");
 
@@ -1915,12 +1640,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
         for (int i = 0; i < 10; ++i)
             ret = content(params);
 
-        assertNotNull(ret);
-        assertTrue(!ret.isEmpty());
-
-        JSONObject json = JSONObject.fromObject(ret);
-
-        List items = (List)((Map)json.get("response")).get("items");
+        JsonNode items = jsonResponse(ret).get("items");
 
         assertEquals(1, items.size());
 
@@ -2238,7 +1958,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
          * @param valCls Value class.
          * @param map Map.
          */
-        public VisorGatewayArgument map(Class keyCls, Class valCls, Map<?, ?> map) {
+        public VisorGatewayArgument map(Class keyCls, Class valCls, Map<?, ?> map) throws UnsupportedEncodingException {
             put("p" + idx++, Map.class.getName());
             put("p" + idx++, keyCls.getName());
             put("p" + idx++, valCls.getName());
@@ -2259,7 +1979,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
                 first = false;
             }
 
-            put("p" + idx++, URLEncoder.encode(sb.toString()));
+            put("p" + idx++, URLEncoder.encode(sb.toString(), CHARSET));
 
             return this;
         }
@@ -2285,7 +2005,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
             }
 
             return sb.toString();
-        };
+        }
     }
 
     /** {@inheritDoc} */

http://git-wip-us.apache.org/repos/asf/ignite/blob/73689ae5/modules/core/pom.xml
----------------------------------------------------------------------
diff --git a/modules/core/pom.xml b/modules/core/pom.xml
index 34368c8..5e32caf 100644
--- a/modules/core/pom.xml
+++ b/modules/core/pom.xml
@@ -76,6 +76,13 @@
         </dependency>
 
         <dependency>
+            <groupId>commons-collections</groupId>
+            <artifactId>commons-collections</artifactId>
+            <version>3.2.2</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
             <groupId>commons-dbcp</groupId>
             <artifactId>commons-dbcp</artifactId>
             <version>1.4</version>
@@ -153,14 +160,6 @@
         </dependency>
 
         <dependency>
-            <groupId>net.sf.json-lib</groupId>
-            <artifactId>json-lib</artifactId>
-            <version>${jsonlib.version}</version>
-            <classifier>jdk15</classifier>
-            <scope>test</scope>
-        </dependency>
-
-        <dependency>
             <groupId>org.gridgain</groupId>
             <artifactId>ignite-shmem</artifactId>
             <version>1.0.0</version>

http://git-wip-us.apache.org/repos/asf/ignite/blob/73689ae5/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCache.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCache.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCache.java
index f06813f..b56a2fa 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCache.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCache.java
@@ -21,7 +21,6 @@ import java.io.Serializable;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Iterator;
-import java.util.Set;
 import org.apache.ignite.IgniteCache;
 import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.cache.CacheMode;