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/01/15 12:04:02 UTC

[1/6] ignite git commit: IGNITE-843 WIP

Repository: ignite
Updated Branches:
  refs/heads/ignite-843-rc2 f6629cab8 -> d603a53a8


http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/remote/RemoteHandler.java
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/remote/RemoteHandler.java b/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/remote/RemoteHandler.java
new file mode 100644
index 0000000..4eda313
--- /dev/null
+++ b/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/remote/RemoteHandler.java
@@ -0,0 +1,252 @@
+/*
+ * 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.console.agent.remote;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonNull;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonPrimitive;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import org.apache.http.auth.AuthenticationException;
+import org.apache.log4j.Logger;
+
+/**
+ * Allow to execute methods remotely from NodeJS server by web-socket command.
+ */
+public class RemoteHandler implements AutoCloseable {
+    /** */
+    public static final Gson GSON = new Gson();
+
+    /** */
+    public static final Object[] EMPTY_OBJECTS = new Object[0];
+
+    /** */
+    private static final Logger log = Logger.getLogger(RemoteHandler.class.getName());
+
+    /** */
+    private static final String INTERNAL_EXCEPTION_TYPE = "org.apache.ignite.agent.AgentException";
+
+    /** */
+    private final WebSocketSender snd;
+
+    /** */
+    private final Map<String, MethodDescriptor> mtds = new HashMap<>();
+
+    /** */
+    private final ExecutorService executorSrvc = Executors.newFixedThreadPool(Runtime.getRuntime()
+        .availableProcessors());
+
+    /**
+     * @param snd Session.
+     * @param hnds Handlers.
+     */
+    private RemoteHandler(WebSocketSender snd, Object ... hnds) {
+        this.snd = snd;
+
+        for (Object hnd : hnds) {
+            for (Method method : hnd.getClass().getMethods()) {
+                Remote remoteAnn = method.getAnnotation(Remote.class);
+
+                if (remoteAnn != null) {
+                    MethodDescriptor old = mtds.put(method.getName(), new MethodDescriptor(method, hnd,
+                        remoteAnn.async()));
+
+                    if (old != null)
+                        throw new IllegalArgumentException("Duplicated method: " + method.getName());
+                }
+            }
+        }
+    }
+
+    /**
+     * @param hnds Handler.
+     * @param snd Sender.
+     */
+    public static RemoteHandler wrap(WebSocketSender snd, Object ... hnds) {
+        return new RemoteHandler(snd, hnds);
+    }
+
+    /**
+     * @param req Request.
+     */
+    public void onMessage(JsonObject req) {
+        JsonPrimitive reqIdJson = req.getAsJsonPrimitive("reqId");
+
+        final Long reqId = reqIdJson == null ? null : reqIdJson.getAsLong();
+
+        String mtdName = req.getAsJsonPrimitive("mtdName").getAsString();
+
+        final MethodDescriptor desc = mtds.get(mtdName);
+
+        if (desc == null) {
+            sendException(reqId, INTERNAL_EXCEPTION_TYPE, "Unknown method: " + mtdName);
+
+            return;
+        }
+
+        Type[] paramTypes = desc.mtd.getGenericParameterTypes();
+
+        JsonArray argsJson = req.getAsJsonArray("args");
+
+        final Object[] args;
+
+        if (paramTypes.length > 0) {
+            args = new Object[paramTypes.length];
+
+            if (argsJson == null || argsJson.size() != paramTypes.length) {
+                sendException(reqId, INTERNAL_EXCEPTION_TYPE, "Inconsistent parameters");
+
+                return;
+            }
+
+            for (int i = 0; i < paramTypes.length; i++)
+                args[i] = GSON.fromJson(argsJson.get(i), paramTypes[i]);
+        }
+        else {
+            args = EMPTY_OBJECTS;
+
+            if (argsJson != null && argsJson.size() > 0) {
+                sendException(reqId, INTERNAL_EXCEPTION_TYPE, "Inconsistent parameters");
+
+                return;
+            }
+        }
+
+        Runnable run = new Runnable() {
+            @Override public void run() {
+                final Object res;
+
+                try {
+                    res = desc.mtd.invoke(desc.hnd, args);
+                }
+                catch (Throwable e) {
+                    if (e instanceof AuthenticationException) {
+                        close();
+
+                        return;
+                    }
+
+                    if (e instanceof InvocationTargetException)
+                        e = ((InvocationTargetException)e).getTargetException();
+
+                    if (reqId != null)
+                        sendException(reqId, e.getClass().getName(), e.getMessage());
+                    else
+                        log.error("Exception on execute remote method.", e);
+
+                    return;
+                }
+
+                sendResponse(reqId, res, desc.returnType);
+            }
+        };
+
+        if (desc.async)
+            executorSrvc.submit(run);
+        else
+            run.run();
+    }
+
+    /**
+     * @param reqId Request id.
+     * @param exType Exception class name.
+     * @param exMsg Exception message.
+     */
+    protected void sendException(Long reqId, String exType, String exMsg) {
+        if (reqId == null)
+            return;
+
+        JsonObject res = new JsonObject();
+
+        res.addProperty("type", "CallRes");
+        res.addProperty("reqId", reqId);
+
+        JsonObject exJson = new JsonObject();
+        exJson.addProperty("type", exType);
+        exJson.addProperty("message", exMsg);
+
+        res.add("ex", exJson);
+
+        snd.send(res);
+    }
+
+    /**
+     * @param reqId Request id.
+     * @param res Result.
+     * @param type Type.
+     */
+    private void sendResponse(Long reqId, Object res, Type type) {
+        if (reqId == null)
+            return;
+
+        JsonObject resp = new JsonObject();
+
+        resp.addProperty("type", "CallRes");
+
+        resp.addProperty("reqId", reqId);
+
+        JsonElement resJson = type == void.class ? JsonNull.INSTANCE : GSON.toJsonTree(res, type);
+
+        resp.add("res", resJson);
+
+        snd.send(resp);
+    }
+
+    /** {@inheritDoc} */
+    @Override public void close() {
+        executorSrvc.shutdown();
+    }
+
+    /**
+     *
+     */
+    private static class MethodDescriptor {
+        /** */
+        private final Method mtd;
+
+        /** */
+        private final Object hnd;
+
+        /** */
+        private final Type returnType;
+
+        /** */
+        private final boolean async;
+
+        /**
+         * @param mtd Method.
+         * @param hnd Handler.
+         * @param async Async.
+         */
+        MethodDescriptor(Method mtd, Object hnd, boolean async) {
+            this.mtd = mtd;
+            this.hnd = hnd;
+            this.async = async;
+
+            returnType = mtd.getGenericReturnType();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/remote/WebSocketSender.java
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/remote/WebSocketSender.java b/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/remote/WebSocketSender.java
new file mode 100644
index 0000000..cceb86b
--- /dev/null
+++ b/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/remote/WebSocketSender.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.console.agent.remote;
+
+import com.google.gson.JsonObject;
+
+/**
+ * Sender for messages to web-socket.
+ */
+public interface WebSocketSender {
+    /**
+     * Send message.
+     * @param msg Message.
+     * @return {@code true} if message sent successfully.
+     */
+    public boolean send(String msg);
+
+    /**
+     * Send message.
+     * @param msg Message.
+     * @return {@code true} if message sent successfully.
+     */
+    public boolean send(JsonObject msg);
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-agent/src/main/java/org/apache/ignite/console/demo/AgentMetadataDemo.java
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/console/demo/AgentMetadataDemo.java b/modules/control-center-agent/src/main/java/org/apache/ignite/console/demo/AgentMetadataDemo.java
new file mode 100644
index 0000000..5d33f29
--- /dev/null
+++ b/modules/control-center-agent/src/main/java/org/apache/ignite/console/demo/AgentMetadataDemo.java
@@ -0,0 +1,88 @@
+/*
+ * 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.console.demo;
+
+import java.io.File;
+import java.io.FileReader;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.apache.log4j.Logger;
+import org.h2.tools.RunScript;
+import org.h2.tools.Server;
+
+import static org.apache.ignite.console.agent.AgentUtils.resolvePath;
+
+/**
+ * Demo for metadata load from database.
+ *
+ * H2 database will be started and several tables will be created.
+ */
+public class AgentMetadataDemo {
+    /** */
+    private static final Logger log = Logger.getLogger(AgentMetadataDemo.class.getName());
+
+    /** */
+    private static final AtomicBoolean initLatch = new AtomicBoolean();
+
+    /**
+     * @param jdbcUrl Connection url.
+     * @return true if url is used for test-drive.
+     */
+    public static boolean isTestDriveUrl(String jdbcUrl) {
+        return "jdbc:h2:mem:demo-db".equals(jdbcUrl);
+    }
+
+    /**
+     * Start H2 database and populate it with several tables.
+     */
+    public static void testDrive() {
+        if (initLatch.compareAndSet(false, true)) {
+            log.info("DEMO: Prepare in-memory H2 database...");
+
+            try {
+                Connection conn = DriverManager.getConnection("jdbc:h2:mem:demo-db;DB_CLOSE_DELAY=-1", "sa", "");
+
+                File sqlScript = resolvePath("demo/db-init.sql");
+
+                if (sqlScript == null) {
+                    log.error("DEMO: Failed to find demo database init script file: demo/db-init.sql");
+                    log.error("DEMO: Failed to start demo for metadata");
+
+                    return;
+                }
+
+                RunScript.execute(conn, new FileReader(sqlScript));
+
+                log.info("DEMO: Sample tables created.");
+
+                conn.close();
+
+                Server.createTcpServer("-tcpDaemon").start();
+
+                log.info("DEMO: TcpServer stared.");
+
+                log.info("DEMO: JDBC URL for test drive metadata load: jdbc:h2:mem:demo-db");
+            }
+            catch (Exception e) {
+                log.error("DEMO: Failed to start test drive for metadata!", e);
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-agent/src/main/java/org/apache/ignite/console/demo/AgentSqlDemo.java
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/console/demo/AgentSqlDemo.java b/modules/control-center-agent/src/main/java/org/apache/ignite/console/demo/AgentSqlDemo.java
new file mode 100644
index 0000000..1e63232
--- /dev/null
+++ b/modules/control-center-agent/src/main/java/org/apache/ignite/console/demo/AgentSqlDemo.java
@@ -0,0 +1,551 @@
+/*
+ * 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.console.demo;
+
+import java.net.InetSocketAddress;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.Random;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.Ignition;
+import org.apache.ignite.console.agent.AgentConfiguration;
+import org.apache.ignite.console.demo.model.Car;
+import org.apache.ignite.console.demo.model.Country;
+import org.apache.ignite.console.demo.model.Department;
+import org.apache.ignite.console.demo.model.Employee;
+import org.apache.ignite.console.demo.model.Parking;
+import org.apache.ignite.cache.QueryEntity;
+import org.apache.ignite.cache.QueryIndex;
+import org.apache.ignite.cache.QueryIndexType;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.internal.IgniteEx;
+import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.logger.NullLogger;
+import org.apache.ignite.spi.IgniteSpiException;
+import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
+import org.apache.ignite.spi.discovery.tcp.ipfinder.TcpDiscoveryIpFinderAdapter;
+import org.apache.log4j.Logger;
+
+import static org.apache.ignite.IgniteSystemProperties.IGNITE_JETTY_PORT;
+import static org.apache.ignite.internal.IgniteNodeAttributes.ATTR_REST_JETTY_ADDRS;
+import static org.apache.ignite.internal.IgniteNodeAttributes.ATTR_REST_JETTY_PORT;
+
+/**
+ * Demo for SQL.
+ *
+ * Cache will be created and populated with data to query.
+ */
+public class AgentSqlDemo {
+    /** */
+    private static final Logger log = Logger.getLogger(AgentMetadataDemo.class.getName());
+
+    /** */
+    private static final AtomicBoolean initLatch = new AtomicBoolean();
+
+    /** */
+    private static final String COUNTRY_CACHE_NAME = "CountryCache";
+    /** */
+    private static final String DEPARTMENT_CACHE_NAME = "DepartmentCache";
+    /** */
+    private static final String EMPLOYEE_CACHE_NAME = "EmployeeCache";
+    /** */
+    private static final String PARKING_CACHE_NAME = "ParkingCache";
+    /** */
+    private static final String CAR_CACHE_NAME = "CarCache";
+
+    /** */
+    private static final Random rnd = new Random();
+
+    /** Countries count. */
+    private static final int CNTR_CNT = 10;
+
+    /** Departments count */
+    private static final int DEP_CNT = 100;
+
+    /** Employees count. */
+    private static final int EMPL_CNT = 1000;
+
+    /** Countries count. */
+    private static final int CAR_CNT = 100;
+
+    /** Departments count */
+    private static final int PARK_CNT = 10;
+
+    /** Counter for threads in pool. */
+    private static final AtomicInteger THREAD_CNT = new AtomicInteger(0);
+
+    /**
+     * Configure cacheCountry.
+     */
+    private static <K, V> CacheConfiguration<K, V> cacheCountry() {
+        CacheConfiguration<K, V> ccfg = new CacheConfiguration<>(COUNTRY_CACHE_NAME);
+
+        // Configure cacheCountry types.
+        Collection<QueryEntity> queryEntities = new ArrayList<>();
+
+        // COUNTRY.
+        QueryEntity type = new QueryEntity();
+
+        queryEntities.add(type);
+
+        type.setKeyType(Integer.class.getName());
+        type.setValueType(Country.class.getName());
+
+        // Query fields for COUNTRY.
+        LinkedHashMap<String, String> qryFlds = new LinkedHashMap<>();
+
+        qryFlds.put("id", "java.lang.Integer");
+        qryFlds.put("name", "java.lang.String");
+        qryFlds.put("population", "java.lang.Integer");
+
+        type.setFields(qryFlds);
+
+        // Indexes for COUNTRY.
+        type.setIndexes(Collections.singletonList(new QueryIndex("id", QueryIndexType.SORTED, false, "PRIMARY_KEY_6")));
+
+        ccfg.setQueryEntities(queryEntities);
+
+        return ccfg;
+    }
+
+    /**
+     * Configure cacheEmployee.
+     */
+    private static <K, V> CacheConfiguration<K, V> cacheDepartment() {
+        CacheConfiguration<K, V> ccfg = new CacheConfiguration<>(DEPARTMENT_CACHE_NAME);
+
+        // Configure cacheDepartment types.
+        Collection<QueryEntity> queryEntities = new ArrayList<>();
+
+        // DEPARTMENT.
+        QueryEntity type = new QueryEntity();
+
+        queryEntities.add(type);
+
+        type.setKeyType(Integer.class.getName());
+        type.setValueType(Department.class.getName());
+
+        // Query fields for DEPARTMENT.
+        LinkedHashMap<String, String> qryFlds = new LinkedHashMap<>();
+
+        qryFlds.put("id", "java.lang.Integer");
+        qryFlds.put("countryId", "java.lang.Integer");
+        qryFlds.put("name", "java.lang.String");
+
+        type.setFields(qryFlds);
+
+        // Indexes for DEPARTMENT.
+        type.setIndexes(Collections.singletonList(new QueryIndex("id", QueryIndexType.SORTED, false, "PRIMARY_KEY_4")));
+
+        ccfg.setQueryEntities(queryEntities);
+
+        return ccfg;
+    }
+
+    /**
+     * Configure cacheEmployee.
+     */
+    private static <K, V> CacheConfiguration<K, V> cacheEmployee() {
+        CacheConfiguration<K, V> ccfg = new CacheConfiguration<>(EMPLOYEE_CACHE_NAME);
+
+        // Configure cacheEmployee types.
+        Collection<QueryEntity> queryEntities = new ArrayList<>();
+
+        // EMPLOYEE.
+        QueryEntity type = new QueryEntity();
+
+        queryEntities.add(type);
+
+        type.setKeyType(Integer.class.getName());
+        type.setValueType(Employee.class.getName());
+
+        // Query fields for EMPLOYEE.
+        LinkedHashMap<String, String> qryFlds = new LinkedHashMap<>();
+
+        qryFlds.put("id", "java.lang.Integer");
+        qryFlds.put("departmentId", "java.lang.Integer");
+        qryFlds.put("managerId", "java.lang.Integer");
+        qryFlds.put("firstName", "java.lang.String");
+        qryFlds.put("lastName", "java.lang.String");
+        qryFlds.put("email", "java.lang.String");
+        qryFlds.put("phoneNumber", "java.lang.String");
+        qryFlds.put("hireDate", "java.sql.Date");
+        qryFlds.put("job", "java.lang.String");
+        qryFlds.put("salary", "java.lang.Double");
+
+        type.setFields(qryFlds);
+
+        // Indexes for EMPLOYEE.
+        Collection<QueryIndex> indexes = new ArrayList<>();
+
+        indexes.add(new QueryIndex("id", QueryIndexType.SORTED, false, "PRIMARY_KEY_7"));
+
+        QueryIndex index = new QueryIndex();
+
+        index.setName("EMP_NAMES");
+        index.setIndexType(QueryIndexType.SORTED);
+        LinkedHashMap<String, Boolean> indFlds = new LinkedHashMap<>();
+
+        indFlds.put("firstName", false);
+        indFlds.put("lastName", false);
+
+        index.setFields(indFlds);
+
+        indexes.add(index);
+        indexes.add(new QueryIndex("salary", QueryIndexType.SORTED, false, "EMP_SALARY"));
+
+        type.setIndexes(indexes);
+
+        ccfg.setQueryEntities(queryEntities);
+
+        return ccfg;
+    }
+
+    /**
+     * Configure cacheEmployee.
+     */
+    private static <K, V> CacheConfiguration<K, V> cacheParking() {
+        CacheConfiguration<K, V> ccfg = new CacheConfiguration<>(PARKING_CACHE_NAME);
+
+        // Configure cacheParking types.
+        Collection<QueryEntity> queryEntities = new ArrayList<>();
+
+        // PARKING.
+        QueryEntity type = new QueryEntity();
+
+        queryEntities.add(type);
+
+        type.setKeyType(Integer.class.getName());
+        type.setValueType(Parking.class.getName());
+
+        // Query fields for PARKING.
+        LinkedHashMap<String, String> qryFlds = new LinkedHashMap<>();
+
+        qryFlds.put("id", "java.lang.Integer");
+        qryFlds.put("name", "java.lang.String");
+        qryFlds.put("capacity", "java.lang.Integer");;
+
+        type.setFields(qryFlds);
+
+        // Indexes for PARKING.
+        type.setIndexes(Collections.singletonList(new QueryIndex("id", QueryIndexType.SORTED, false, "PRIMARY_KEY_F")));
+
+        ccfg.setQueryEntities(queryEntities);
+
+        return ccfg;
+    }
+
+    /**
+     * Configure cacheEmployee.
+     */
+    private static <K, V> CacheConfiguration<K, V> cacheCar() {
+        CacheConfiguration<K, V> ccfg = new CacheConfiguration<>(CAR_CACHE_NAME);
+
+        // Configure cacheCar types.
+        Collection<QueryEntity> queryEntities = new ArrayList<>();
+
+        // CAR.
+        QueryEntity type = new QueryEntity();
+
+        queryEntities.add(type);
+
+        type.setKeyType(Integer.class.getName());
+        type.setValueType(Car.class.getName());
+
+        // Query fields for CAR.
+        LinkedHashMap<String, String> qryFlds = new LinkedHashMap<>();
+
+        qryFlds.put("id", "java.lang.Integer");
+        qryFlds.put("parkingId", "java.lang.Integer");
+        qryFlds.put("name", "java.lang.String");
+
+        type.setFields(qryFlds);
+
+        // Indexes for CAR.
+        type.setIndexes(Collections.singletonList(new QueryIndex("id", QueryIndexType.SORTED, false, "PRIMARY_KEY_1")));
+
+        ccfg.setQueryEntities(queryEntities);
+
+        return ccfg;
+    }
+
+    /**
+     * @param val Value to round.
+     * @param places Numbers after point.
+     * @return Rounded value;
+     */
+    private static double round(double val, int places) {
+        if (places < 0)
+            throw new IllegalArgumentException();
+
+        long factor = (long) Math.pow(10, places);
+
+        val *= factor;
+
+        long tmp = Math.round(val);
+
+        return (double) tmp / factor;
+    }
+
+    /**
+     * @param ignite Ignite.
+     * @param range Time range in milliseconds.
+     */
+    private static void populateCacheEmployee(Ignite ignite, long range) {
+        log.trace("DEMO: Start employees population with data...");
+
+        IgniteCache<Integer, Country> cacheCountry = ignite.cache(COUNTRY_CACHE_NAME);
+
+        for (int i = 0, n = i + 1; i < CNTR_CNT; i++)
+            cacheCountry.put(i, new Country(i, "Country #" + n, n * 10000000));
+
+        IgniteCache<Integer, Department> cacheDepartment = ignite.cache(DEPARTMENT_CACHE_NAME);
+
+        IgniteCache<Integer, Employee> cacheEmployee = ignite.cache(EMPLOYEE_CACHE_NAME);
+
+        for (int i = 0, n = i + 1; i < DEP_CNT; i++) {
+            cacheDepartment.put(i, new Department(n, rnd.nextInt(CNTR_CNT), "Department #" + n));
+
+            double r = rnd.nextDouble();
+
+            cacheEmployee.put(i, new Employee(i, rnd.nextInt(DEP_CNT), null, "First name manager #" + n,
+                "Last name manager #" + n, "Email manager #" + n, "Phone number manager #" + n,
+                new java.sql.Date((long)(r * range)), "Job manager #" + n, 1000 + round(r * 4000, 2)));
+        }
+
+        for (int i = 0, n = i + 1; i < EMPL_CNT; i++) {
+            Integer depId = rnd.nextInt(DEP_CNT);
+
+            double r = rnd.nextDouble();
+
+            cacheEmployee.put(i, new Employee(i, depId, depId, "First name employee #" + n,
+                    "Last name employee #" + n, "Email employee #" + n, "Phone number employee #" + n,
+                    new java.sql.Date((long)(r * range)), "Job employee #" + n, 500 + round(r * 2000, 2)));
+        }
+
+        log.trace("DEMO: Finished employees population.");
+    }
+
+    /**
+     * @param ignite Ignite.
+     */
+    private static void populateCacheCar(Ignite ignite) {
+        log.trace("DEMO: Start cars population...");
+
+        IgniteCache<Integer, Parking> cacheParking = ignite.cache(PARKING_CACHE_NAME);
+
+        for (int i = 0, n = i + 1; i < PARK_CNT; i++)
+            cacheParking.put(i, new Parking(i, "Parking #" + n, n * 10));
+
+        IgniteCache<Integer, Car> cacheCar = ignite.cache(CAR_CACHE_NAME);
+
+        for (int i = 0, n = i + 1; i < CAR_CNT; i++)
+            cacheCar.put(i, new Car(i, rnd.nextInt(PARK_CNT), "Car #" + n));
+
+        log.trace("DEMO: Finished cars population.");
+    }
+
+    /**
+     * Creates a thread pool that can schedule commands to run after a given delay, or to execute periodically.
+     *
+     * @param corePoolSize Number of threads to keep in the pool, even if they are idle.
+     * @param threadName Part of thread name that would be used by thread factory.
+     * @return Newly created scheduled thread pool.
+     */
+    private static ScheduledExecutorService newScheduledThreadPool(int corePoolSize, final String threadName) {
+        ScheduledExecutorService srvc = Executors.newScheduledThreadPool(corePoolSize, new ThreadFactory() {
+            @Override public Thread newThread(Runnable r) {
+                Thread thread = new Thread(r, String.format("%s-%d", threadName, THREAD_CNT.getAndIncrement()));
+
+                thread.setDaemon(true);
+
+                return thread;
+            }
+        });
+
+        ScheduledThreadPoolExecutor executor = (ScheduledThreadPoolExecutor) srvc;
+
+        // Setting up shutdown policy.
+        executor.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
+        executor.setContinueExistingPeriodicTasksAfterShutdownPolicy(false);
+
+        return srvc;
+    }
+
+    /**
+     * Starts read and write from cache in background.
+     *
+     * @param ignite Ignite.
+     * @param cnt - maximum count read/write key
+     */
+    private static void startLoad(final Ignite ignite, final int cnt) {
+        final long diff = new java.util.Date().getTime();
+
+        populateCacheEmployee(ignite, diff);
+
+        populateCacheCar(ignite);
+
+        ScheduledExecutorService cachePool = newScheduledThreadPool(2, "demo-sql-load-cache-tasks");
+
+        cachePool.scheduleWithFixedDelay(new Runnable() {
+            @Override public void run() {
+                try {
+                    IgniteCache<Integer, Employee> cacheEmployee = ignite.cache(EMPLOYEE_CACHE_NAME);
+
+                    if (cacheEmployee != null)
+                        for (int i = 0, n = i + 1; i < cnt; i++) {
+                            Integer id = rnd.nextInt(EMPL_CNT);
+
+                            Integer depId = rnd.nextInt(DEP_CNT);
+
+                            double r = rnd.nextDouble();
+
+                            cacheEmployee.put(id, new Employee(id, depId, depId, "First name employee #" + n,
+                                    "Last name employee #" + n, "Email employee #" + n, "Phone number employee #" + n,
+                                    new java.sql.Date((long)(r * diff)), "Job employee #" + n, 500 + round(r * 2000, 2)));
+
+                            if (rnd.nextBoolean())
+                                cacheEmployee.remove(rnd.nextInt(EMPL_CNT));
+                        }
+                }
+                catch (IllegalStateException ignored) {
+                    // No-op.
+                }
+                catch (Throwable e) {
+                    if (!e.getMessage().contains("cache is stopped"))
+                        ignite.log().error("Cache write task execution error", e);
+                }
+            }
+        }, 10, 3, TimeUnit.SECONDS);
+
+        cachePool.scheduleWithFixedDelay(new Runnable() {
+            @Override public void run() {
+                try {
+                    IgniteCache<Integer, Car> cache = ignite.cache(CAR_CACHE_NAME);
+
+                    if (cache != null)
+                        for (int i = 0; i < cnt; i++) {
+                            Integer carId = rnd.nextInt(CAR_CNT);
+
+                            cache.put(carId, new Car(carId, rnd.nextInt(PARK_CNT), "Car #" + (i + 1)));
+
+                            if (rnd.nextBoolean())
+                                cache.remove(rnd.nextInt(CAR_CNT));
+                        }
+                }
+                catch (IllegalStateException ignored) {
+                    // No-op.
+                }
+                catch (Throwable e) {
+                    if (!e.getMessage().contains("cache is stopped"))
+                        ignite.log().error("Cache write task execution error", e);
+                }
+            }
+        }, 10, 3, TimeUnit.SECONDS);
+    }
+
+    /**
+     * Start ignite node with cacheEmployee and populate it with data.
+     */
+    public static boolean testDrive(AgentConfiguration acfg) {
+        if (initLatch.compareAndSet(false, true)) {
+            log.info("DEMO: Starting embedded node for sql test-drive...");
+
+            try {
+                IgniteConfiguration cfg = new IgniteConfiguration();
+
+                cfg.setLocalHost("127.0.0.1");
+
+                cfg.setMetricsLogFrequency(0);
+
+                cfg.setGridLogger(new NullLogger());
+
+                // Configure discovery SPI.
+                TcpDiscoverySpi discoSpi = new TcpDiscoverySpi();
+
+                discoSpi.setLocalPort(60900);
+
+                discoSpi.setIpFinder(new TcpDiscoveryIpFinderAdapter() {
+                    {
+                        setShared(true);
+                    }
+
+                    /** {@inheritDoc} */
+                    @Override public Collection<InetSocketAddress> getRegisteredAddresses() throws IgniteSpiException {
+                        return Collections.emptyList();
+                    }
+
+                    /** {@inheritDoc} */
+                    @Override public void registerAddresses(Collection<InetSocketAddress> addrs) throws IgniteSpiException {
+                        // No-op.
+                    }
+
+                    /** {@inheritDoc} */
+                    @Override public void unregisterAddresses(Collection<InetSocketAddress> addrs) throws IgniteSpiException {
+                        // No-op.
+                    }
+                });
+
+                cfg.setDiscoverySpi(discoSpi);
+
+                cfg.setCacheConfiguration(cacheCountry(), cacheDepartment(), cacheEmployee(), cacheParking(), cacheCar());
+
+                System.setProperty(IGNITE_JETTY_PORT, "60800");
+
+                log.trace("DEMO: Start embedded node with indexed enabled caches...");
+
+                IgniteEx ignite = (IgniteEx)Ignition.start(cfg);
+
+                String host = ((Collection<String>)
+                    ignite.localNode().attribute(ATTR_REST_JETTY_ADDRS)).iterator().next();
+
+                Integer port = ignite.localNode().attribute(ATTR_REST_JETTY_PORT);
+
+                if (F.isEmpty(host) || port == null) {
+                    log.error("DEMO: Failed to start embedded node with rest!");
+
+                    return false;
+                }
+
+                acfg.demoNodeUri(String.format("http://%s:%d", host, port));
+
+                log.info("DEMO: Embedded node for sql test-drive successfully started");
+
+                startLoad(ignite, 20);
+            }
+            catch (Exception e) {
+                log.error("DEMO: Failed to start embedded node for sql test-drive!", e);
+
+                return false;
+            }
+        }
+
+        return true;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-agent/src/main/java/org/apache/ignite/console/demo/model/Car.java
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/console/demo/model/Car.java b/modules/control-center-agent/src/main/java/org/apache/ignite/console/demo/model/Car.java
new file mode 100755
index 0000000..16b1120
--- /dev/null
+++ b/modules/control-center-agent/src/main/java/org/apache/ignite/console/demo/model/Car.java
@@ -0,0 +1,137 @@
+package org.apache.ignite.console.demo.model;
+
+import java.io.Serializable;
+
+/**
+ * Car definition.
+ *
+ * This configuration was generated by Ignite Web Console (01/14/2016 13:46)
+ */
+public class Car implements Serializable {
+    /** */
+    private static final long serialVersionUID = 0L;
+
+    /** Value for id. */
+    private int id;
+
+    /** Value for parkingId. */
+    private int parkingId;
+
+    /** Value for name. */
+    private String name;
+
+    /**
+     * Empty constructor.
+     */
+    public Car() {
+        // No-op.
+    }
+
+    /**
+     * Full constructor.
+     */
+    public Car(
+        int id,
+        int parkingId,
+        String name
+    ) {
+        this.id = id;
+        this.parkingId = parkingId;
+        this.name = name;
+    }
+
+    /**
+     * Gets id.
+     *
+     * @return Value for id.
+     */
+    public int getId() {
+        return id;
+    }
+
+    /**
+     * Sets id.
+     *
+     * @param id New value for id.
+     */
+    public void setId(int id) {
+        this.id = id;
+    }
+
+    /**
+     * Gets parkingId.
+     *
+     * @return Value for parkingId.
+     */
+    public int getParkingId() {
+        return parkingId;
+    }
+
+    /**
+     * Sets parkingId.
+     *
+     * @param parkingId New value for parkingId.
+     */
+    public void setParkingId(int parkingId) {
+        this.parkingId = parkingId;
+    }
+
+    /**
+     * Gets name.
+     *
+     * @return Value for name.
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Sets name.
+     *
+     * @param name New value for name.
+     */
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean equals(Object o) {
+        if (this == o)
+            return true;
+        
+        if (!(o instanceof Car))
+            return false;
+
+        Car that = (Car)o;
+
+        if (id != that.id)
+            return false;
+
+        if (parkingId != that.parkingId)
+            return false;
+
+        if (name != null ? !name.equals(that.name) : that.name != null)
+            return false;
+
+        return true;
+    }
+
+    /** {@inheritDoc} */
+    @Override public int hashCode() {
+        int res = id;
+
+        res = 31 * res + parkingId;
+
+        res = 31 * res + (name != null ? name.hashCode() : 0);
+
+        return res;
+    }
+
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        return "Car [id=" + id +
+            ", parkingId=" + parkingId +
+            ", name=" + name +
+            ']';
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-agent/src/main/java/org/apache/ignite/console/demo/model/Country.java
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/console/demo/model/Country.java b/modules/control-center-agent/src/main/java/org/apache/ignite/console/demo/model/Country.java
new file mode 100755
index 0000000..1817224
--- /dev/null
+++ b/modules/control-center-agent/src/main/java/org/apache/ignite/console/demo/model/Country.java
@@ -0,0 +1,137 @@
+package org.apache.ignite.console.demo.model;
+
+import java.io.Serializable;
+
+/**
+ * Country definition.
+ *
+ * This configuration was generated by Ignite Web Console (01/14/2016 13:46)
+ */
+public class Country implements Serializable {
+    /** */
+    private static final long serialVersionUID = 0L;
+
+    /** Value for id. */
+    private int id;
+
+    /** Value for name. */
+    private String name;
+
+    /** Value for population. */
+    private int population;
+
+    /**
+     * Empty constructor.
+     */
+    public Country() {
+        // No-op.
+    }
+
+    /**
+     * Full constructor.
+     */
+    public Country(
+        int id,
+        String name,
+        int population
+    ) {
+        this.id = id;
+        this.name = name;
+        this.population = population;
+    }
+
+    /**
+     * Gets id.
+     *
+     * @return Value for id.
+     */
+    public int getId() {
+        return id;
+    }
+
+    /**
+     * Sets id.
+     *
+     * @param id New value for id.
+     */
+    public void setId(int id) {
+        this.id = id;
+    }
+
+    /**
+     * Gets name.
+     *
+     * @return Value for name.
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Sets name.
+     *
+     * @param name New value for name.
+     */
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    /**
+     * Gets population.
+     *
+     * @return Value for population.
+     */
+    public int getPopulation() {
+        return population;
+    }
+
+    /**
+     * Sets population.
+     *
+     * @param population New value for population.
+     */
+    public void setPopulation(int population) {
+        this.population = population;
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean equals(Object o) {
+        if (this == o)
+            return true;
+        
+        if (!(o instanceof Country))
+            return false;
+
+        Country that = (Country)o;
+
+        if (id != that.id)
+            return false;
+
+        if (name != null ? !name.equals(that.name) : that.name != null)
+            return false;
+
+        if (population != that.population)
+            return false;
+
+        return true;
+    }
+
+    /** {@inheritDoc} */
+    @Override public int hashCode() {
+        int res = id;
+
+        res = 31 * res + (name != null ? name.hashCode() : 0);
+
+        res = 31 * res + population;
+
+        return res;
+    }
+
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        return "Country [id=" + id +
+            ", name=" + name +
+            ", population=" + population +
+            ']';
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-agent/src/main/java/org/apache/ignite/console/demo/model/Department.java
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/console/demo/model/Department.java b/modules/control-center-agent/src/main/java/org/apache/ignite/console/demo/model/Department.java
new file mode 100755
index 0000000..3f90147
--- /dev/null
+++ b/modules/control-center-agent/src/main/java/org/apache/ignite/console/demo/model/Department.java
@@ -0,0 +1,137 @@
+package org.apache.ignite.console.demo.model;
+
+import java.io.Serializable;
+
+/**
+ * Department definition.
+ *
+ * This configuration was generated by Ignite Web Console (01/14/2016 13:46)
+ */
+public class Department implements Serializable {
+    /** */
+    private static final long serialVersionUID = 0L;
+
+    /** Value for id. */
+    private int id;
+
+    /** Value for countryId. */
+    private int countryId;
+
+    /** Value for name. */
+    private String name;
+
+    /**
+     * Empty constructor.
+     */
+    public Department() {
+        // No-op.
+    }
+
+    /**
+     * Full constructor.
+     */
+    public Department(
+        int id,
+        int countryId,
+        String name
+    ) {
+        this.id = id;
+        this.countryId = countryId;
+        this.name = name;
+    }
+
+    /**
+     * Gets id.
+     *
+     * @return Value for id.
+     */
+    public int getId() {
+        return id;
+    }
+
+    /**
+     * Sets id.
+     *
+     * @param id New value for id.
+     */
+    public void setId(int id) {
+        this.id = id;
+    }
+
+    /**
+     * Gets countryId.
+     *
+     * @return Value for countryId.
+     */
+    public int getCountryId() {
+        return countryId;
+    }
+
+    /**
+     * Sets countryId.
+     *
+     * @param countryId New value for countryId.
+     */
+    public void setCountryId(int countryId) {
+        this.countryId = countryId;
+    }
+
+    /**
+     * Gets name.
+     *
+     * @return Value for name.
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Sets name.
+     *
+     * @param name New value for name.
+     */
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean equals(Object o) {
+        if (this == o)
+            return true;
+        
+        if (!(o instanceof Department))
+            return false;
+
+        Department that = (Department)o;
+
+        if (id != that.id)
+            return false;
+
+        if (countryId != that.countryId)
+            return false;
+
+        if (name != null ? !name.equals(that.name) : that.name != null)
+            return false;
+
+        return true;
+    }
+
+    /** {@inheritDoc} */
+    @Override public int hashCode() {
+        int res = id;
+
+        res = 31 * res + countryId;
+
+        res = 31 * res + (name != null ? name.hashCode() : 0);
+
+        return res;
+    }
+
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        return "Department [id=" + id +
+            ", countryId=" + countryId +
+            ", name=" + name +
+            ']';
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-agent/src/main/java/org/apache/ignite/console/demo/model/Employee.java
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/console/demo/model/Employee.java b/modules/control-center-agent/src/main/java/org/apache/ignite/console/demo/model/Employee.java
new file mode 100755
index 0000000..f1f0b3f
--- /dev/null
+++ b/modules/control-center-agent/src/main/java/org/apache/ignite/console/demo/model/Employee.java
@@ -0,0 +1,341 @@
+package org.apache.ignite.console.demo.model;
+
+import java.io.Serializable;
+import java.sql.Date;
+
+/**
+ * Employee definition.
+ *
+ * This configuration was generated by Ignite Web Console (01/14/2016 13:46)
+ */
+public class Employee implements Serializable {
+    /** */
+    private static final long serialVersionUID = 0L;
+
+    /** Value for id. */
+    private int id;
+
+    /** Value for departmentId. */
+    private int departmentId;
+
+    /** Value for managerId. */
+    private Integer managerId;
+
+    /** Value for firstName. */
+    private String firstName;
+
+    /** Value for lastName. */
+    private String lastName;
+
+    /** Value for email. */
+    private String email;
+
+    /** Value for phoneNumber. */
+    private String phoneNumber;
+
+    /** Value for hireDate. */
+    private Date hireDate;
+
+    /** Value for job. */
+    private String job;
+
+    /** Value for salary. */
+    private Double salary;
+
+    /**
+     * Empty constructor.
+     */
+    public Employee() {
+        // No-op.
+    }
+
+    /**
+     * Full constructor.
+     */
+    public Employee(
+        int id,
+        int departmentId,
+        Integer managerId,
+        String firstName,
+        String lastName,
+        String email,
+        String phoneNumber,
+        Date hireDate,
+        String job,
+        Double salary
+    ) {
+        this.id = id;
+        this.departmentId = departmentId;
+        this.managerId = managerId;
+        this.firstName = firstName;
+        this.lastName = lastName;
+        this.email = email;
+        this.phoneNumber = phoneNumber;
+        this.hireDate = hireDate;
+        this.job = job;
+        this.salary = salary;
+    }
+
+    /**
+     * Gets id.
+     *
+     * @return Value for id.
+     */
+    public int getId() {
+        return id;
+    }
+
+    /**
+     * Sets id.
+     *
+     * @param id New value for id.
+     */
+    public void setId(int id) {
+        this.id = id;
+    }
+
+    /**
+     * Gets departmentId.
+     *
+     * @return Value for departmentId.
+     */
+    public int getDepartmentId() {
+        return departmentId;
+    }
+
+    /**
+     * Sets departmentId.
+     *
+     * @param departmentId New value for departmentId.
+     */
+    public void setDepartmentId(int departmentId) {
+        this.departmentId = departmentId;
+    }
+
+    /**
+     * Gets managerId.
+     *
+     * @return Value for managerId.
+     */
+    public Integer getManagerId() {
+        return managerId;
+    }
+
+    /**
+     * Sets managerId.
+     *
+     * @param managerId New value for managerId.
+     */
+    public void setManagerId(Integer managerId) {
+        this.managerId = managerId;
+    }
+
+    /**
+     * Gets firstName.
+     *
+     * @return Value for firstName.
+     */
+    public String getFirstName() {
+        return firstName;
+    }
+
+    /**
+     * Sets firstName.
+     *
+     * @param firstName New value for firstName.
+     */
+    public void setFirstName(String firstName) {
+        this.firstName = firstName;
+    }
+
+    /**
+     * Gets lastName.
+     *
+     * @return Value for lastName.
+     */
+    public String getLastName() {
+        return lastName;
+    }
+
+    /**
+     * Sets lastName.
+     *
+     * @param lastName New value for lastName.
+     */
+    public void setLastName(String lastName) {
+        this.lastName = lastName;
+    }
+
+    /**
+     * Gets email.
+     *
+     * @return Value for email.
+     */
+    public String getEmail() {
+        return email;
+    }
+
+    /**
+     * Sets email.
+     *
+     * @param email New value for email.
+     */
+    public void setEmail(String email) {
+        this.email = email;
+    }
+
+    /**
+     * Gets phoneNumber.
+     *
+     * @return Value for phoneNumber.
+     */
+    public String getPhoneNumber() {
+        return phoneNumber;
+    }
+
+    /**
+     * Sets phoneNumber.
+     *
+     * @param phoneNumber New value for phoneNumber.
+     */
+    public void setPhoneNumber(String phoneNumber) {
+        this.phoneNumber = phoneNumber;
+    }
+
+    /**
+     * Gets hireDate.
+     *
+     * @return Value for hireDate.
+     */
+    public Date getHireDate() {
+        return hireDate;
+    }
+
+    /**
+     * Sets hireDate.
+     *
+     * @param hireDate New value for hireDate.
+     */
+    public void setHireDate(Date hireDate) {
+        this.hireDate = hireDate;
+    }
+
+    /**
+     * Gets job.
+     *
+     * @return Value for job.
+     */
+    public String getJob() {
+        return job;
+    }
+
+    /**
+     * Sets job.
+     *
+     * @param job New value for job.
+     */
+    public void setJob(String job) {
+        this.job = job;
+    }
+
+    /**
+     * Gets salary.
+     *
+     * @return Value for salary.
+     */
+    public Double getSalary() {
+        return salary;
+    }
+
+    /**
+     * Sets salary.
+     *
+     * @param salary New value for salary.
+     */
+    public void setSalary(Double salary) {
+        this.salary = salary;
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean equals(Object o) {
+        if (this == o)
+            return true;
+        
+        if (!(o instanceof Employee))
+            return false;
+
+        Employee that = (Employee)o;
+
+        if (id != that.id)
+            return false;
+
+        if (departmentId != that.departmentId)
+            return false;
+
+        if (managerId != null ? !managerId.equals(that.managerId) : that.managerId != null)
+            return false;
+
+        if (firstName != null ? !firstName.equals(that.firstName) : that.firstName != null)
+            return false;
+
+        if (lastName != null ? !lastName.equals(that.lastName) : that.lastName != null)
+            return false;
+
+        if (email != null ? !email.equals(that.email) : that.email != null)
+            return false;
+
+        if (phoneNumber != null ? !phoneNumber.equals(that.phoneNumber) : that.phoneNumber != null)
+            return false;
+
+        if (hireDate != null ? !hireDate.equals(that.hireDate) : that.hireDate != null)
+            return false;
+
+        if (job != null ? !job.equals(that.job) : that.job != null)
+            return false;
+
+        if (salary != null ? !salary.equals(that.salary) : that.salary != null)
+            return false;
+
+        return true;
+    }
+
+    /** {@inheritDoc} */
+    @Override public int hashCode() {
+        int res = id;
+
+        res = 31 * res + departmentId;
+
+        res = 31 * res + (managerId != null ? managerId.hashCode() : 0);
+
+        res = 31 * res + (firstName != null ? firstName.hashCode() : 0);
+
+        res = 31 * res + (lastName != null ? lastName.hashCode() : 0);
+
+        res = 31 * res + (email != null ? email.hashCode() : 0);
+
+        res = 31 * res + (phoneNumber != null ? phoneNumber.hashCode() : 0);
+
+        res = 31 * res + (hireDate != null ? hireDate.hashCode() : 0);
+
+        res = 31 * res + (job != null ? job.hashCode() : 0);
+
+        res = 31 * res + (salary != null ? salary.hashCode() : 0);
+
+        return res;
+    }
+
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        return "Employee [id=" + id +
+            ", departmentId=" + departmentId +
+            ", managerId=" + managerId +
+            ", firstName=" + firstName +
+            ", lastName=" + lastName +
+            ", email=" + email +
+            ", phoneNumber=" + phoneNumber +
+            ", hireDate=" + hireDate +
+            ", job=" + job +
+            ", salary=" + salary +
+            ']';
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-agent/src/main/java/org/apache/ignite/console/demo/model/Parking.java
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/console/demo/model/Parking.java b/modules/control-center-agent/src/main/java/org/apache/ignite/console/demo/model/Parking.java
new file mode 100755
index 0000000..e6539fa
--- /dev/null
+++ b/modules/control-center-agent/src/main/java/org/apache/ignite/console/demo/model/Parking.java
@@ -0,0 +1,137 @@
+package org.apache.ignite.console.demo.model;
+
+import java.io.Serializable;
+
+/**
+ * Parking definition.
+ *
+ * This configuration was generated by Ignite Web Console (01/14/2016 13:46)
+ */
+public class Parking implements Serializable {
+    /** */
+    private static final long serialVersionUID = 0L;
+
+    /** Value for id. */
+    private int id;
+
+    /** Value for name. */
+    private String name;
+
+    /** Value for capacity. */
+    private int capacity;
+
+    /**
+     * Empty constructor.
+     */
+    public Parking() {
+        // No-op.
+    }
+
+    /**
+     * Full constructor.
+     */
+    public Parking(
+        int id,
+        String name,
+        int capacity
+    ) {
+        this.id = id;
+        this.name = name;
+        this.capacity = capacity;
+    }
+
+    /**
+     * Gets id.
+     *
+     * @return Value for id.
+     */
+    public int getId() {
+        return id;
+    }
+
+    /**
+     * Sets id.
+     *
+     * @param id New value for id.
+     */
+    public void setId(int id) {
+        this.id = id;
+    }
+
+    /**
+     * Gets name.
+     *
+     * @return Value for name.
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Sets name.
+     *
+     * @param name New value for name.
+     */
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    /**
+     * Gets capacity.
+     *
+     * @return Value for capacity.
+     */
+    public int getCapacity() {
+        return capacity;
+    }
+
+    /**
+     * Sets capacity.
+     *
+     * @param capacity New value for capacity.
+     */
+    public void setCapacity(int capacity) {
+        this.capacity = capacity;
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean equals(Object o) {
+        if (this == o)
+            return true;
+        
+        if (!(o instanceof Parking))
+            return false;
+
+        Parking that = (Parking)o;
+
+        if (id != that.id)
+            return false;
+
+        if (name != null ? !name.equals(that.name) : that.name != null)
+            return false;
+
+        if (capacity != that.capacity)
+            return false;
+
+        return true;
+    }
+
+    /** {@inheritDoc} */
+    @Override public int hashCode() {
+        int res = id;
+
+        res = 31 * res + (name != null ? name.hashCode() : 0);
+
+        res = 31 * res + capacity;
+
+        return res;
+    }
+
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        return "Parking [id=" + id +
+            ", name=" + name +
+            ", capacity=" + capacity +
+            ']';
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-web/src/main/js/agents/agent-manager.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/agents/agent-manager.js b/modules/control-center-web/src/main/js/agents/agent-manager.js
index 6205198..9f631b9 100644
--- a/modules/control-center-web/src/main/js/agents/agent-manager.js
+++ b/modules/control-center-web/src/main/js/agents/agent-manager.js
@@ -113,14 +113,15 @@ function Client(ws, manager) {
 }
 
 /**
- * @param {String} path
+ * @param {String} uri
  * @param {Object} params
+ * @param {Boolean} demo
  * @param {String} [method]
  * @param {Object} [headers]
  * @param {String} [body]
  * @param {Function} [cb] Callback. Take 3 arguments: {String} error, {number} httpCode, {string} response.
  */
-Client.prototype.executeRest = function(path, params, method, headers, body, cb) {
+Client.prototype.executeRest = function(uri, params, demo, method, headers, body, cb) {
     if (typeof(params) != 'object')
         throw '"params" argument must be an object';
 
@@ -143,7 +144,7 @@ Client.prototype.executeRest = function(path, params, method, headers, body, cb)
 
     var newArgs = argsToArray(arguments);
 
-    newArgs[5] = function(ex, res) {
+    newArgs[6] = function(ex, res) {
         if (ex)
             cb(ex.message);
         else
@@ -250,7 +251,9 @@ Client.prototype._rmtAuthMessage = function(msg) {
 
             self._manager._addClient(account._id, self);
 
-            self._ignite = new apacheIgnite.Ignite(new AgentServer(self));
+            self._cluster = new apacheIgnite.Ignite(new AgentServer(self));
+
+            self._demo = new apacheIgnite.Ignite(new AgentServer(self, true));
         }
     });
 };
@@ -271,8 +274,8 @@ Client.prototype._rmtCallRes = function(msg) {
 /**
  * @returns {Ignite}
  */
-Client.prototype.ignite = function() {
-    return this._ignite;
+Client.prototype.ignite = function(demo) {
+    return demo ? this._demo : this._cluster;
 };
 
 function removeFromArray(arr, val) {

http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-web/src/main/js/agents/agent-server.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/agents/agent-server.js b/modules/control-center-web/src/main/js/agents/agent-server.js
index 76bdeb4..ae5a87c 100644
--- a/modules/control-center-web/src/main/js/agents/agent-server.js
+++ b/modules/control-center-web/src/main/js/agents/agent-server.js
@@ -22,10 +22,12 @@ var _ = require('lodash');
  *
  * @constructor
  * @this {AgentServer}
- * @param {Client} client connected client
+ * @param {Client} client Connected client
+ * @param {Boolean} demo Use demo node for request
  */
-function AgentServer(client) {
+function AgentServer(client, demo) {
     this._client = client;
+    this._demo = !!demo;
 }
 
 /**
@@ -56,9 +58,10 @@ AgentServer.prototype.runCommand = function(cmd, callback) {
         headers = {'JSONObject': 'application/json'};
     }
 
-    this._client.executeRest("ignite", params, method, headers, body, function(error, code, message) {
+    this._client.executeRest("ignite", params, this._demo, method, headers, body, function(error, code, message) {
         if (error) {
             callback(error);
+
             return
         }
 
@@ -71,22 +74,16 @@ AgentServer.prototype.runCommand = function(cmd, callback) {
             return;
         }
 
-        var igniteResponse;
-
         try {
-            igniteResponse = JSON.parse(message);
+            var igniteResponse = JSON.parse(message);
+
+            if (igniteResponse.successStatus)
+                callback.call(null, igniteResponse.error, null);
+            else
+                callback.call(null, null, igniteResponse.response);
         }
         catch (e) {
             callback.call(null, e, null);
-
-            return;
-        }
-
-        if (igniteResponse.successStatus) {
-            callback.call(null, igniteResponse.error, null)
-        }
-        else {
-            callback.call(null, null, igniteResponse.response);
         }
     });
 };

http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-web/src/main/js/app/index.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/index.js b/modules/control-center-web/src/main/js/app/index.js
index a552939..6fcaad5 100644
--- a/modules/control-center-web/src/main/js/app/index.js
+++ b/modules/control-center-web/src/main/js/app/index.js
@@ -59,6 +59,7 @@ import './modules/User/index';
 import './modules/Auth/index';
 import './modules/Form/index';
 import './modules/JavaTypes/index';
+import './modules/QueryNotebooks/index';
 
 import './modules/states/login/index';
 import './modules/states/logout/index';
@@ -102,6 +103,7 @@ angular
     'ignite-console.User',
     'ignite-console.Form',
     'ignite-console.JavaTypes',
+    'ignite-console.QueryNotebooks',
     // States.
     'ignite-console.states.login',
     'ignite-console.states.logout',

http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-web/src/main/js/app/modules/QueryNotebooks/index.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/QueryNotebooks/index.js b/modules/control-center-web/src/main/js/app/modules/QueryNotebooks/index.js
new file mode 100644
index 0000000..702b107
--- /dev/null
+++ b/modules/control-center-web/src/main/js/app/modules/QueryNotebooks/index.js
@@ -0,0 +1,111 @@
+/*
+ * 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.
+ */
+
+import angular from 'angular';
+
+angular
+    .module('ignite-console.QueryNotebooks', [
+
+    ])
+    .provider('QueryNotebooks', function() {
+        const _demoNotebook = {
+            name: 'SQL demo',
+            paragraphs: [
+                {
+                    name: 'Simple query',
+                    cacheName: 'CarCache',
+                    pageSize: 50,
+                    query: 'SELECT * FROM Car',
+                    result: 'table',
+                    queryArgs: {
+                        type: 'QUERY',
+                        query: 'SELECT * FROM Car',
+                        pageSize: 50,
+                        cacheName: 'CarCache'
+                    },
+                    rate: {
+                        value: 1,
+                        unit: 60000,
+                        installed: false
+                    }
+                },
+                {
+                    name: 'Query with aggregates',
+                    cacheName: 'CarCache',
+                    pageSize: 50,
+                    query: 'SELECT * FROM Car',
+                    result: 'table',
+                    queryArgs: {
+                        type: 'QUERY',
+                        query: 'SELECT * FROM Car',
+                        pageSize: 50,
+                        cacheName: 'CarCache'
+                    },
+                    rate: {
+                        value: 1,
+                        unit: 60000,
+                        installed: false
+                    }
+                },
+                {
+                    name: 'Query with refresh rate',
+                    cacheName: 'CarCache',
+                    pageSize: 50,
+                    query: 'SELECT * FROM Car',
+                    result: 'table',
+                    queryArgs: {
+                        type: 'QUERY',
+                        query: 'SELECT * FROM Car',
+                        pageSize: 50,
+                        cacheName: 'CarCache'
+                    },
+                    rate: {
+                        value: 1,
+                        unit: 60000,
+                        installed: false
+                    }
+                }
+            ],
+            expandedParagraphs: [0, 1, 2]
+        };
+
+        this.$get = ['$q', '$http', ($q, $http) => {
+            return {
+                read(demo, noteId) {
+                    if (demo) {
+                        return $http.post('/api/v1/agent/demo/sql/start')
+                            .then(() => {
+                                return angular.copy(_demoNotebook);
+                            });
+                    }
+
+                    return $http.post('/api/v1/notebooks/get', {noteId})
+                        .then(({data}) => {
+                            return data;
+                        });
+                },
+                save(demo, notebook) {
+                    if (demo)
+                        return $http.post('/api/v1/notebooks/save', notebook);
+
+                    return $q.when();
+                },
+                remove(demo, nodeId) {
+                }
+            };
+        }];
+    });

http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-web/src/main/js/app/modules/states/configuration/index.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/configuration/index.js b/modules/control-center-web/src/main/js/app/modules/states/configuration/index.js
index 0700950..90558d4 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/configuration/index.js
+++ b/modules/control-center-web/src/main/js/app/modules/states/configuration/index.js
@@ -41,7 +41,7 @@ angular
         },
         resolve: {
             $title: () => {
-                return 'Create and Configure Ignite Clusters';
+                return 'Configure Clusters - Ignite Console';
             }
         }
     })
@@ -53,7 +53,7 @@ angular
         },
         resolve: {
             $title: () => {
-                return 'Create and Configure Ignite Caches';
+                return 'Configure Caches - Ignite Console';
             }
         }
     })
@@ -65,7 +65,7 @@ angular
         },
         resolve: {
             $title: () => {
-                return 'Create and Configure Cache Type Metadata';
+                return 'Configure Cache Type Metadata - Ignite Console';
             }
         }
     })
@@ -77,7 +77,7 @@ angular
         },
         resolve: {
             $title: () => {
-                return 'Create and Configure IGFS';
+                return 'Configure IGFS - Ignite Console';
             }
         }
     })
@@ -91,7 +91,7 @@ angular
         },
         resolve: {
             $title: () => {
-                return 'Configurations Summary';
+                return 'Configurations Summary - Ignite Console';
             }
         }
     });

http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-web/src/main/js/app/modules/states/login/index.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/login/index.js b/modules/control-center-web/src/main/js/app/modules/states/login/index.js
index 316aecd..008ffb7 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/login/index.js
+++ b/modules/control-center-web/src/main/js/app/modules/states/login/index.js
@@ -28,7 +28,12 @@ angular
     $stateProvider
     .state('login', {
         url: '/login',
-        templateUrl: '/login.html'
+        templateUrl: '/login.html',
+        resolve: {
+            $title: () => {
+                return 'Sign In - Ignite Console';
+            }
+        }
     });
 }])
 .run(['$rootScope', '$state', 'Auth', 'igniteTerms', function($root, $state, Auth, igniteTerms) {

http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-web/src/main/js/app/modules/states/sql/index.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/states/sql/index.js b/modules/control-center-web/src/main/js/app/modules/states/sql/index.js
index 852724b..672d829 100644
--- a/modules/control-center-web/src/main/js/app/modules/states/sql/index.js
+++ b/modules/control-center-web/src/main/js/app/modules/states/sql/index.js
@@ -25,14 +25,31 @@ angular
     // set up the states
     $stateProvider
     .state('base.sql', {
-        url: '/sql/{id}',
+        url: '/sql',
+        abstract: true,
+        template: '<ui-view></ui-view>'
+    })
+    .state('base.sql.notebook', {
+        url: '/notebook/{noteId}',
         templateUrl: '/sql/sql.html',
         data: {
             loading: 'Loading notebook screen...'
         },
         resolve: {
             $title: () => {
-                return 'SQL notebook';
+                return 'Query notebook';
+            }
+        }
+    })
+    .state('base.sql.demo', {
+        url: '/demo',
+        templateUrl: '/sql/sql.html',
+        data: {
+            loading: 'Enable SQL demo...'
+        },
+        resolve: {
+            $title: () => {
+                return 'SQL demo';
             }
         }
     });

http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-web/src/main/js/controllers/common-module.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/controllers/common-module.js b/modules/control-center-web/src/main/js/controllers/common-module.js
index cafca42..e995175 100644
--- a/modules/control-center-web/src/main/js/controllers/common-module.js
+++ b/modules/control-center-web/src/main/js/controllers/common-module.js
@@ -2143,10 +2143,10 @@ consoleModule.service('$agentDownload', [
              * @param attr
              * @param mtr
              */
-            startTopologyListening: function (success, attr, mtr) {
+            startTopologyListening: function (success, demo, attr, mtr) {
                 _agentDownloadModal.check = {
                     url: '/api/v1/agent/topology',
-                    params: {attr: !!attr, mtr: !!mtr},
+                    params: {demo: !!demo,  attr: !!attr, mtr: !!mtr},
                     cb: success
                 };
 
@@ -2196,16 +2196,15 @@ consoleModule.controller('notebooks', ['$scope', '$modal', '$state', '$http', '$
 
     $scope.$root.rebuildDropdown = function() {
         $scope.notebookDropdown = [
-            {text: 'Create new notebook', click: 'inputNotebookName()'}
+            {text: 'Create new notebook', click: 'inputNotebookName()'},
+            {divider: true},
+            {text: 'SQL demo', sref: 'base.sql.demo'}
         ];
 
-        if ($scope.$root.notebooks.length > 0)
-            $scope.notebookDropdown.push({divider: true});
-
         _.forEach($scope.$root.notebooks, function (notebook) {
             $scope.notebookDropdown.push({
                 text: notebook.name,
-                href: '/sql/' + notebook._id
+                sref: 'base.sql.notebook({noteId:"' + notebook._id + '"})'
             });
         });
     };

http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-web/src/main/js/controllers/sql-controller.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/controllers/sql-controller.js b/modules/control-center-web/src/main/js/controllers/sql-controller.js
index c3a029e..69fbc85 100644
--- a/modules/control-center-web/src/main/js/controllers/sql-controller.js
+++ b/modules/control-center-web/src/main/js/controllers/sql-controller.js
@@ -17,7 +17,7 @@
 
 // Controller for SQL notebook screen.
 consoleModule.controller('sqlController', function ($http, $timeout, $interval, $scope, $animate,  $location, $anchorScroll, $state,
-    $modal, $popover, $loading, $common, $confirm, $agentDownload, uiGridExporterConstants) {
+    $modal, $popover, $loading, $common, $confirm, $agentDownload, QueryNotebooks, uiGridExporterConstants) {
 
     $scope.joinTip = $common.joinTip;
 
@@ -56,10 +56,16 @@ consoleModule.controller('sqlController', function ($http, $timeout, $interval,
         }
     };
 
+    var _demo = $state.includes('**.sql.demo');
+
     var _mask = function (cacheName) {
         return _.isEmpty(cacheName) ? '<default>' : cacheName;
     };
 
+    var _handleException = function(errMsg) {
+        $common.showError(errMsg);
+    };
+
     // Time line X axis descriptor.
     var TIME_LINE = {value: -1, type: 'java.sql.Date', label: 'TIME_LINE'};
 
@@ -245,52 +251,47 @@ consoleModule.controller('sqlController', function ($http, $timeout, $interval,
         $state.go('/configuration/clusters');
     };
 
-    var loadNotebook = function () {
-        $loading.start('loading');
+    var loadNotebook = function (notebook) {
+        $scope.notebook = notebook;
 
-        $http.post('/api/v1/notebooks/get', {noteId: $state.params.id})
-            .success(function (notebook) {
-                $scope.notebook = notebook;
+        $scope.notebook_name = notebook.name;
 
-                $scope.notebook_name = notebook.name;
+        if (!$scope.notebook.expandedParagraphs)
+            $scope.notebook.expandedParagraphs = [];
 
-                if (!$scope.notebook.expandedParagraphs)
-                    $scope.notebook.expandedParagraphs = [];
+        if (!$scope.notebook.paragraphs)
+            $scope.notebook.paragraphs = [];
 
-                if (!$scope.notebook.paragraphs)
-                    $scope.notebook.paragraphs = [];
+        _.forEach(notebook.paragraphs, function (paragraph) {
+            paragraph.id = 'paragraph-' + paragraphId++;
 
-                _.forEach(notebook.paragraphs, function (paragraph) {
-                    paragraph.id = 'paragraph-' + paragraphId++;
+            enhanceParagraph(paragraph);
+        });
 
-                    enhanceParagraph(paragraph);
-                });
+        if (!notebook.paragraphs || notebook.paragraphs.length == 0)
+            $scope.addParagraph();
+        else
+            $scope.rebuildScrollParagraphs();
 
-                if (!notebook.paragraphs || notebook.paragraphs.length == 0)
-                    $scope.addParagraph();
-                else
-                    $scope.rebuildScrollParagraphs();
+        $agentDownload.startTopologyListening(getTopology, _demo);
+    };
 
-                $agentDownload.startTopologyListening(getTopology);
-            })
-            .error(function () {
-                $scope.notebook = undefined;
-            })
-            .finally(function () {
-                $scope.loaded = true;
+    $loading.start('loading');
 
-                $loading.finish('loading');
-            });
-    };
+    QueryNotebooks.read(_demo, $state.params.noteId)
+        .then(loadNotebook)
+        .catch(function(err) {
+            $scope.notebook = undefined;
+        })
+        .finally(function() {
+            $scope.loaded = true;
 
-    loadNotebook();
+            $loading.finish('loading');
+        });
 
-    var _saveNotebook = function (f) {
-        $http.post('/api/v1/notebooks/save', $scope.notebook)
-            .success(f || function() {})
-            .error(function (errMsg) {
-                $common.showError(errMsg);
-            });
+    var _saveNotebook = function (cb) {
+        QueryNotebooks.save(_demo, $scope.notebook)
+            .catch(_handleException);
     };
 
     $scope.renameNotebook = function (name) {
@@ -300,19 +301,21 @@ consoleModule.controller('sqlController', function ($http, $timeout, $interval,
         if ($scope.notebook.name != name) {
             $scope.notebook.name = name;
 
-            _saveNotebook(function () {
-                var idx = _.findIndex($scope.$root.notebooks, function (item) {
-                    return item._id == $scope.notebook._id;
-                });
+            QueryNotebooks.save(_demo, $scope.notebook)
+                .then(function() {
+                    var idx = _.findIndex($scope.$root.notebooks, function (item) {
+                        return item._id == $scope.notebook._id;
+                    });
 
-                if (idx >= 0) {
-                    $scope.$root.notebooks[idx].name = name;
+                    if (idx >= 0) {
+                        $scope.$root.notebooks[idx].name = name;
 
-                    $scope.$root.rebuildDropdown();
-                }
+                        $scope.$root.rebuildDropdown();
+                    }
 
-                $scope.notebook.edit = false;
-            });
+                    $scope.notebook.edit = false;
+                })
+                .catch(_handleException);
         }
         else
             $scope.notebook.edit = false
@@ -353,7 +356,9 @@ consoleModule.controller('sqlController', function ($http, $timeout, $interval,
 
             $scope.rebuildScrollParagraphs();
 
-            _saveNotebook(function () { paragraph.edit = false; });
+            QueryNotebooks.save(_demo, $scope.notebook)
+                .then(function () { paragraph.edit = false; })
+                .catch(_handleException);
         }
         else
             paragraph.edit = false
@@ -365,7 +370,6 @@ consoleModule.controller('sqlController', function ($http, $timeout, $interval,
         var paragraph = {
             id: 'paragraph-' + paragraphId++,
             name: 'Query' + (sz ==0 ? '' : sz),
-            editor: true,
             query: '',
             pageSize: $scope.pageSizes[0],
             timeLineSpan: $scope.timeLineSpans[0],
@@ -431,7 +435,8 @@ consoleModule.controller('sqlController', function ($http, $timeout, $interval,
 
                     $scope.rebuildScrollParagraphs();
 
-                    _saveNotebook();
+                    QueryNotebooks.save(_demo, $scope.notebook)
+                        .catch(_handleException);
             });
     };
 
@@ -683,7 +688,8 @@ consoleModule.controller('sqlController', function ($http, $timeout, $interval,
     };
 
     $scope.execute = function (paragraph) {
-        _saveNotebook();
+        QueryNotebooks.save(_demo, $scope.notebook)
+            .catch(_handleException);
 
         paragraph.prevQuery = paragraph.queryArgs ? paragraph.queryArgs.query : paragraph.query;
 
@@ -692,6 +698,7 @@ consoleModule.controller('sqlController', function ($http, $timeout, $interval,
         _tryCloseQueryResult(paragraph.queryId);
 
         paragraph.queryArgs = {
+            demo: _demo,
             type: "QUERY",
             query: paragraph.query,
             pageSize: paragraph.pageSize,
@@ -720,7 +727,8 @@ consoleModule.controller('sqlController', function ($http, $timeout, $interval,
     };
 
     $scope.explain = function (paragraph) {
-        _saveNotebook();
+        QueryNotebooks.save(_demo, $scope.notebook)
+            .catch(_handleException);
 
         _cancelRefresh(paragraph);
 
@@ -729,6 +737,7 @@ consoleModule.controller('sqlController', function ($http, $timeout, $interval,
         _tryCloseQueryResult(paragraph.queryId);
 
         paragraph.queryArgs = {
+            demo: _demo,
             type: "EXPLAIN",
             query: 'EXPLAIN ' + paragraph.query,
             pageSize: paragraph.pageSize,
@@ -747,7 +756,8 @@ consoleModule.controller('sqlController', function ($http, $timeout, $interval,
     };
 
     $scope.scan = function (paragraph) {
-        _saveNotebook();
+        QueryNotebooks.save(_demo, $scope.notebook)
+            .catch(_handleException);
 
         _cancelRefresh(paragraph);
 
@@ -756,6 +766,7 @@ consoleModule.controller('sqlController', function ($http, $timeout, $interval,
         _tryCloseQueryResult(paragraph.queryId);
 
         paragraph.queryArgs = {
+            demo: _demo,
             type: "SCAN",
             pageSize: paragraph.pageSize,
             cacheName: paragraph.cacheName || undefined
@@ -775,7 +786,7 @@ consoleModule.controller('sqlController', function ($http, $timeout, $interval,
     $scope.nextPage = function(paragraph) {
         _showLoading(paragraph, true);
 
-        $http.post('/api/v1/agent/query/fetch', {queryId: paragraph.queryId, pageSize: paragraph.pageSize, cacheName: paragraph.queryArgs.cacheName})
+        $http.post('/api/v1/agent/query/fetch', {demo: _demo, queryId: paragraph.queryId, pageSize: paragraph.pageSize, cacheName: paragraph.queryArgs.cacheName})
             .success(function (res) {
                 paragraph.page++;
 
@@ -862,7 +873,7 @@ consoleModule.controller('sqlController', function ($http, $timeout, $interval,
     };
 
     $scope.exportCsvAll = function(paragraph) {
-        $http.post('/api/v1/agent/query/getAll', {query: paragraph.query, cacheName: paragraph.cacheName})
+        $http.post('/api/v1/agent/query/getAll', {demo: _demo, query: paragraph.query, cacheName: paragraph.cacheName})
             .success(function (item) {
                 _export(paragraph.name + '-all.csv', item.meta, item.rows);
             })
@@ -1463,7 +1474,7 @@ consoleModule.controller('sqlController', function ($http, $timeout, $interval,
 
         $scope.metadata = [];
 
-        $http.post('/api/v1/agent/cache/metadata')
+        $http.post('/api/v1/agent/cache/metadata', {demo: _demo})
             .success(function (metadata) {
                 $scope.metadata = _.sortBy(metadata, _.filter(metadata, function (meta) {
                     var cacheName = _mask(meta.cacheName);

http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-web/src/main/js/gulpfile.js/tasks/copy.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/gulpfile.js/tasks/copy.js b/modules/control-center-web/src/main/js/gulpfile.js/tasks/copy.js
index 0f05f32..c1dbb21 100644
--- a/modules/control-center-web/src/main/js/gulpfile.js/tasks/copy.js
+++ b/modules/control-center-web/src/main/js/gulpfile.js/tasks/copy.js
@@ -40,7 +40,7 @@ var legacyPaths = [
     './helpers/*.js',
     './helpers/**/*.js',
     './public/**/*.png',
-    './public/*.png'
+    './public/*.ico'
 ];
 
 var igniteModulePaths = [

http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-web/src/main/js/routes/agent.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/routes/agent.js b/modules/control-center-web/src/main/js/routes/agent.js
index 12f8f01..9229a3f 100644
--- a/modules/control-center-web/src/main/js/routes/agent.js
+++ b/modules/control-center-web/src/main/js/routes/agent.js
@@ -67,7 +67,7 @@ router.get('/download/zip', function (req, res) {
 
         zip.file(agentFld + '/default.properties', prop.join('\n'));
 
-        var buffer = zip.generate({type:"nodebuffer", platform: "UNIX"});
+        var buffer = zip.generate({type: 'nodebuffer', platform: 'UNIX'});
 
         // Set the archive name.
         res.attachment(agentZip);
@@ -81,7 +81,7 @@ router.post('/topology', function (req, res) {
     var client = _client(req, res);
 
     if (client) {
-        client.ignite().cluster(req.body.attr, req.body.mtr).then(
+        client.ignite(req.body.demo).cluster(req.body.attr, req.body.mtr).then(
             function (clusters) {
                 res.json(clusters);
             },
@@ -105,7 +105,7 @@ router.post('/query', function (req, res) {
         qry.setPageSize(req.body.pageSize);
 
         // Get query cursor.
-        client.ignite().cache(req.body.cacheName).query(qry).nextPage().then(function (cursor) {
+        client.ignite(req.body.demo).cache(req.body.cacheName).query(qry).nextPage().then(function (cursor) {
             res.json({meta: cursor.fieldsMetadata(), rows: cursor.page(), queryId: cursor.queryId()});
         }, function (err) {
             res.status(500).send(err);
@@ -125,7 +125,7 @@ router.post('/query/getAll', function (req, res) {
         qry.setPageSize(1024);
 
         // Get query cursor.
-        var cursor = client.ignite().cache(req.body.cacheName).query(qry);
+        var cursor = client.ignite(req.body.demo).cache(req.body.cacheName).query(qry);
 
         cursor.getAll().then(function (rows) {
             res.json({meta: cursor.fieldsMetadata(), rows: rows});
@@ -147,7 +147,7 @@ router.post('/scan', function (req, res) {
         qry.setPageSize(req.body.pageSize);
 
         // Get query cursor.
-        client.ignite().cache(req.body.cacheName).query(qry).nextPage().then(function (cursor) {
+        client.ignite(req.body.demo).cache(req.body.cacheName).query(qry).nextPage().then(function (cursor) {
             res.json({meta: cursor.fieldsMetadata(), rows: cursor.page(), queryId: cursor.queryId()});
         }, function (err) {
             res.status(500).send(err);
@@ -160,7 +160,7 @@ router.post('/query/fetch', function (req, res) {
     var client = _client(req, res);
 
     if (client) {
-        var cache = client.ignite().cache(req.body.cacheName);
+        var cache = client.ignite(req.body.demo).cache(req.body.cacheName);
 
         var cmd = cache._createCommand('qryfetch').addParam('qryId', req.body.queryId).
             addParam('pageSize', req.body.pageSize);
@@ -178,7 +178,7 @@ router.post('/query/close', function (req, res) {
     var client = _client(req, res);
 
     if (client) {
-        var cache = client.ignite().cache(req.body.cacheName);
+        var cache = client.ignite(req.body.demo).cache(req.body.cacheName);
 
         var cmd = cache._createCommand('qrycls').addParam('qryId', req.body.queryId);
 
@@ -195,7 +195,7 @@ router.post('/cache/metadata', function (req, res) {
     var client = _client(req, res);
 
     if (client) {
-        client.ignite().cache(req.body.cacheName).metadata().then(function (caches) {
+        client.ignite(req.body.demo).cache(req.body.cacheName).metadata().then(function (caches) {
             var types = [];
 
             for (var meta of caches) {
@@ -275,9 +275,12 @@ router.post('/demo/sql/start', function (req, res) {
     if (client) {
         client.startDemoSQL(function (err, enabled) {
             if (err)
-                return res.status(500).send(err);
+                return res.status(500).send(err.message);
+
+            if (!enabled)
+                return res.status(500).send('Failed to start SQL demo');
 
-            res.status(200).send(enabled);
+            res.sendStatus(200);
         });
     }
 });

http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-web/src/main/js/routes/notebooks.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/routes/notebooks.js b/modules/control-center-web/src/main/js/routes/notebooks.js
index 6dd02c2..93defd4 100644
--- a/modules/control-center-web/src/main/js/routes/notebooks.js
+++ b/modules/control-center-web/src/main/js/routes/notebooks.js
@@ -68,8 +68,8 @@ router.post('/get', function (req, res) {
 
         // Get all metadata for spaces.
         db.Notebook.findOne({space: {$in: space_ids}, _id: req.body.noteId}).exec(function (err, notebook) {
-            if (err || notebook == null)
-                return res.sendStatus(500);
+            if (err)
+                return res.status(500).send(err.message);
 
             res.json(notebook);
         });

http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-web/src/main/js/views/templates/agent-download.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/views/templates/agent-download.jade b/modules/control-center-web/src/main/js/views/templates/agent-download.jade
index 8ece589..d2a1442 100644
--- a/modules/control-center-web/src/main/js/views/templates/agent-download.jade
+++ b/modules/control-center-web/src/main/js/views/templates/agent-download.jade
@@ -51,5 +51,4 @@
                         | &nbsp; in agent folder for more information
             .modal-footer
                 button.btn.btn-default(ng-click='back()') {{::backText}}
-                button.btn.btn-primary(ng-if='nodeFailedConnection' ng-click='startDemoSQL()') Start demo
                 button.btn.btn-primary(ng-if='!nodeFailedConnection' ng-click='downloadAgent()') Download zip


[5/6] ignite git commit: Merge remote-tracking branch 'origin/ignite-843-rc2' into ignite-843-rc2

Posted by an...@apache.org.
Merge remote-tracking branch 'origin/ignite-843-rc2' into ignite-843-rc2


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

Branch: refs/heads/ignite-843-rc2
Commit: 7812853e24fc2a6ac9505485163b389a32dd883e
Parents: 975dec8 f6629ca
Author: Andrey <an...@gridgain.com>
Authored: Fri Jan 15 18:02:22 2016 +0700
Committer: Andrey <an...@gridgain.com>
Committed: Fri Jan 15 18:02:22 2016 +0700

----------------------------------------------------------------------
 .../src/main/js/controllers/caches-controller.js    | 16 ++++++----------
 1 file changed, 6 insertions(+), 10 deletions(-)
----------------------------------------------------------------------



[2/6] ignite git commit: IGNITE-843 WIP

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-agent/src/main/java/org/apache/ignite/agent/demo/model/Employee.java
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/agent/demo/model/Employee.java b/modules/control-center-agent/src/main/java/org/apache/ignite/agent/demo/model/Employee.java
deleted file mode 100644
index 9238845..0000000
--- a/modules/control-center-agent/src/main/java/org/apache/ignite/agent/demo/model/Employee.java
+++ /dev/null
@@ -1,358 +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.agent.demo.model;
-
-import java.io.Serializable;
-
-/**
- * Employee definition.
- *
- * Code generated by Apache Ignite Schema Import utility: 08/24/2015.
- */
-public class Employee implements Serializable {
-    /** */
-    private static final long serialVersionUID = 0L;
-
-    /** Value for employeeId. */
-    private int employeeId;
-
-    /** Value for firstName. */
-    private String firstName;
-
-    /** Value for lastName. */
-    private String lastName;
-
-    /** Value for email. */
-    private String email;
-
-    /** Value for phoneNumber. */
-    private String phoneNumber;
-
-    /** Value for hireDate. */
-    private java.sql.Date hireDate;
-
-    /** Value for job. */
-    private String job;
-
-    /** Value for salary. */
-    private Double salary;
-
-    /** Value for managerId. */
-    private Integer managerId;
-
-    /** Value for departmentId. */
-    private Integer departmentId;
-
-    /**
-     * Empty constructor.
-     */
-    public Employee() {
-        // No-op.
-    }
-
-    /**
-     * Full constructor.
-     */
-    public Employee(
-        int employeeId,
-        String firstName,
-        String lastName,
-        String email,
-        String phoneNumber,
-        java.sql.Date hireDate,
-        String job,
-        Double salary,
-        Integer managerId,
-        Integer departmentId
-    ) {
-        this.employeeId = employeeId;
-        this.firstName = firstName;
-        this.lastName = lastName;
-        this.email = email;
-        this.phoneNumber = phoneNumber;
-        this.hireDate = hireDate;
-        this.job = job;
-        this.salary = salary;
-        this.managerId = managerId;
-        this.departmentId = departmentId;
-    }
-
-    /**
-     * Gets employeeId.
-     *
-     * @return Value for employeeId.
-     */
-    public int getEmployeeId() {
-        return employeeId;
-    }
-
-    /**
-     * Sets employeeId.
-     *
-     * @param employeeId New value for employeeId.
-     */
-    public void setEmployeeId(int employeeId) {
-        this.employeeId = employeeId;
-    }
-
-    /**
-     * Gets firstName.
-     *
-     * @return Value for firstName.
-     */
-    public String getFirstName() {
-        return firstName;
-    }
-
-    /**
-     * Sets firstName.
-     *
-     * @param firstName New value for firstName.
-     */
-    public void setFirstName(String firstName) {
-        this.firstName = firstName;
-    }
-
-    /**
-     * Gets lastName.
-     *
-     * @return Value for lastName.
-     */
-    public String getLastName() {
-        return lastName;
-    }
-
-    /**
-     * Sets lastName.
-     *
-     * @param lastName New value for lastName.
-     */
-    public void setLastName(String lastName) {
-        this.lastName = lastName;
-    }
-
-    /**
-     * Gets email.
-     *
-     * @return Value for email.
-     */
-    public String getEmail() {
-        return email;
-    }
-
-    /**
-     * Sets email.
-     *
-     * @param email New value for email.
-     */
-    public void setEmail(String email) {
-        this.email = email;
-    }
-
-    /**
-     * Gets phoneNumber.
-     *
-     * @return Value for phoneNumber.
-     */
-    public String getPhoneNumber() {
-        return phoneNumber;
-    }
-
-    /**
-     * Sets phoneNumber.
-     *
-     * @param phoneNumber New value for phoneNumber.
-     */
-    public void setPhoneNumber(String phoneNumber) {
-        this.phoneNumber = phoneNumber;
-    }
-
-    /**
-     * Gets hireDate.
-     *
-     * @return Value for hireDate.
-     */
-    public java.sql.Date getHireDate() {
-        return hireDate;
-    }
-
-    /**
-     * Sets hireDate.
-     *
-     * @param hireDate New value for hireDate.
-     */
-    public void setHireDate(java.sql.Date hireDate) {
-        this.hireDate = hireDate;
-    }
-
-    /**
-     * Gets job.
-     *
-     * @return Value for job.
-     */
-    public String getJob() {
-        return job;
-    }
-
-    /**
-     * Sets job.
-     *
-     * @param job New value for job.
-     */
-    public void setJob(String job) {
-        this.job = job;
-    }
-
-    /**
-     * Gets salary.
-     *
-     * @return Value for salary.
-     */
-    public Double getSalary() {
-        return salary;
-    }
-
-    /**
-     * Sets salary.
-     *
-     * @param salary New value for salary.
-     */
-    public void setSalary(Double salary) {
-        this.salary = salary;
-    }
-
-    /**
-     * Gets managerId.
-     *
-     * @return Value for managerId.
-     */
-    public Integer getManagerId() {
-        return managerId;
-    }
-
-    /**
-     * Sets managerId.
-     *
-     * @param managerId New value for managerId.
-     */
-    public void setManagerId(Integer managerId) {
-        this.managerId = managerId;
-    }
-
-    /**
-     * Gets departmentId.
-     *
-     * @return Value for departmentId.
-     */
-    public Integer getDepartmentId() {
-        return departmentId;
-    }
-
-    /**
-     * Sets departmentId.
-     *
-     * @param departmentId New value for departmentId.
-     */
-    public void setDepartmentId(Integer departmentId) {
-        this.departmentId = departmentId;
-    }
-
-    /** {@inheritDoc} */
-    @Override public boolean equals(Object o) {
-        if (this == o)
-            return true;
-
-        if (!(o instanceof Employee))
-            return false;
-
-        Employee that = (Employee)o;
-
-        if (employeeId != that.employeeId)
-            return false;
-
-        if (firstName != null ? !firstName.equals(that.firstName) : that.firstName != null)
-            return false;
-
-        if (lastName != null ? !lastName.equals(that.lastName) : that.lastName != null)
-            return false;
-
-        if (email != null ? !email.equals(that.email) : that.email != null)
-            return false;
-
-        if (phoneNumber != null ? !phoneNumber.equals(that.phoneNumber) : that.phoneNumber != null)
-            return false;
-
-        if (hireDate != null ? !hireDate.equals(that.hireDate) : that.hireDate != null)
-            return false;
-
-        if (job != null ? !job.equals(that.job) : that.job != null)
-            return false;
-
-        if (salary != null ? !salary.equals(that.salary) : that.salary != null)
-            return false;
-
-        if (managerId != null ? !managerId.equals(that.managerId) : that.managerId != null)
-            return false;
-
-        if (departmentId != null ? !departmentId.equals(that.departmentId) : that.departmentId != null)
-            return false;
-
-        return true;
-    }
-
-    /** {@inheritDoc} */
-    @Override public int hashCode() {
-        int res = employeeId;
-
-        res = 31 * res + (firstName != null ? firstName.hashCode() : 0);
-
-        res = 31 * res + (lastName != null ? lastName.hashCode() : 0);
-
-        res = 31 * res + (email != null ? email.hashCode() : 0);
-
-        res = 31 * res + (phoneNumber != null ? phoneNumber.hashCode() : 0);
-
-        res = 31 * res + (hireDate != null ? hireDate.hashCode() : 0);
-
-        res = 31 * res + (job != null ? job.hashCode() : 0);
-
-        res = 31 * res + (salary != null ? salary.hashCode() : 0);
-
-        res = 31 * res + (managerId != null ? managerId.hashCode() : 0);
-
-        res = 31 * res + (departmentId != null ? departmentId.hashCode() : 0);
-
-        return res;
-    }
-
-    /** {@inheritDoc} */
-    @Override public String toString() {
-        return "Employee [employeeId=" + employeeId +
-            ", firstName=" + firstName +
-            ", lastName=" + lastName +
-            ", email=" + email +
-            ", phoneNumber=" + phoneNumber +
-            ", hireDate=" + hireDate +
-            ", job=" + job +
-            ", salary=" + salary +
-            ", managerId=" + managerId +
-            ", departmentId=" + departmentId +
-            "]";
-    }
-}
-

http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-agent/src/main/java/org/apache/ignite/agent/demo/model/EmployeeKey.java
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/agent/demo/model/EmployeeKey.java b/modules/control-center-agent/src/main/java/org/apache/ignite/agent/demo/model/EmployeeKey.java
deleted file mode 100644
index 6a9f4c0..0000000
--- a/modules/control-center-agent/src/main/java/org/apache/ignite/agent/demo/model/EmployeeKey.java
+++ /dev/null
@@ -1,97 +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.agent.demo.model;
-
-import java.io.Serializable;
-
-/**
- * EmployeeKey definition.
- *
- * Code generated by Apache Ignite Schema Import utility: 08/24/2015.
- */
-public class EmployeeKey implements Serializable {
-    /** */
-    private static final long serialVersionUID = 0L;
-
-    /** Value for employeeId. */
-    private int employeeId;
-
-    /**
-     * Empty constructor.
-     */
-    public EmployeeKey() {
-        // No-op.
-    }
-
-    /**
-     * Full constructor.
-     */
-    public EmployeeKey(
-        int employeeId
-    ) {
-        this.employeeId = employeeId;
-    }
-
-    /**
-     * Gets employeeId.
-     *
-     * @return Value for employeeId.
-     */
-    public int getEmployeeId() {
-        return employeeId;
-    }
-
-    /**
-     * Sets employeeId.
-     *
-     * @param employeeId New value for employeeId.
-     */
-    public void setEmployeeId(int employeeId) {
-        this.employeeId = employeeId;
-    }
-
-    /** {@inheritDoc} */
-    @Override public boolean equals(Object o) {
-        if (this == o)
-            return true;
-
-        if (!(o instanceof EmployeeKey))
-            return false;
-
-        EmployeeKey that = (EmployeeKey)o;
-
-        if (employeeId != that.employeeId)
-            return false;
-
-        return true;
-    }
-
-    /** {@inheritDoc} */
-    @Override public int hashCode() {
-        int res = employeeId;
-
-        return res;
-    }
-
-    /** {@inheritDoc} */
-    @Override public String toString() {
-        return "EmployeeKey [employeeId=" + employeeId +
-            "]";
-    }
-}
-

http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-agent/src/main/java/org/apache/ignite/agent/demo/model/Parking.java
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/agent/demo/model/Parking.java b/modules/control-center-agent/src/main/java/org/apache/ignite/agent/demo/model/Parking.java
deleted file mode 100644
index 7613760..0000000
--- a/modules/control-center-agent/src/main/java/org/apache/ignite/agent/demo/model/Parking.java
+++ /dev/null
@@ -1,126 +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.agent.demo.model;
-
-import java.io.Serializable;
-
-/**
- * Parking definition.
- *
- * Code generated by Apache Ignite Schema Import utility: 08/24/2015.
- */
-public class Parking implements Serializable {
-    /** */
-    private static final long serialVersionUID = 0L;
-
-    /** Value for parkingId. */
-    private int parkingId;
-
-    /** Value for parkingName. */
-    private String parkingName;
-
-    /**
-     * Empty constructor.
-     */
-    public Parking() {
-        // No-op.
-    }
-
-    /**
-     * Full constructor.
-     */
-    public Parking(
-        int parkingId,
-        String parkingName
-    ) {
-        this.parkingId = parkingId;
-        this.parkingName = parkingName;
-    }
-
-    /**
-     * Gets parkingId.
-     *
-     * @return Value for parkingId.
-     */
-    public int getParkingId() {
-        return parkingId;
-    }
-
-    /**
-     * Sets parkingId.
-     *
-     * @param parkingId New value for parkingId.
-     */
-    public void setParkingId(int parkingId) {
-        this.parkingId = parkingId;
-    }
-
-    /**
-     * Gets parkingName.
-     *
-     * @return Value for parkingName.
-     */
-    public String getParkingName() {
-        return parkingName;
-    }
-
-    /**
-     * Sets parkingName.
-     *
-     * @param parkingName New value for parkingName.
-     */
-    public void setParkingName(String parkingName) {
-        this.parkingName = parkingName;
-    }
-
-    /** {@inheritDoc} */
-    @Override public boolean equals(Object o) {
-        if (this == o)
-            return true;
-
-        if (!(o instanceof Parking))
-            return false;
-
-        Parking that = (Parking)o;
-
-        if (parkingId != that.parkingId)
-            return false;
-
-        if (parkingName != null ? !parkingName.equals(that.parkingName) : that.parkingName != null)
-            return false;
-
-        return true;
-    }
-
-    /** {@inheritDoc} */
-    @Override public int hashCode() {
-        int res = parkingId;
-
-        res = 31 * res + (parkingName != null ? parkingName.hashCode() : 0);
-
-        return res;
-    }
-
-    /** {@inheritDoc} */
-    @Override public String toString() {
-        return "Parking [parkingId=" + parkingId +
-            ", parkingName=" + parkingName +
-            "]";
-    }
-}
-

http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-agent/src/main/java/org/apache/ignite/agent/demo/model/ParkingKey.java
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/agent/demo/model/ParkingKey.java b/modules/control-center-agent/src/main/java/org/apache/ignite/agent/demo/model/ParkingKey.java
deleted file mode 100644
index a68e8e5..0000000
--- a/modules/control-center-agent/src/main/java/org/apache/ignite/agent/demo/model/ParkingKey.java
+++ /dev/null
@@ -1,97 +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.agent.demo.model;
-
-import java.io.Serializable;
-
-/**
- * ParkingKey definition.
- *
- * Code generated by Apache Ignite Schema Import utility: 08/24/2015.
- */
-public class ParkingKey implements Serializable {
-    /** */
-    private static final long serialVersionUID = 0L;
-
-    /** Value for parkingId. */
-    private int parkingId;
-
-    /**
-     * Empty constructor.
-     */
-    public ParkingKey() {
-        // No-op.
-    }
-
-    /**
-     * Full constructor.
-     */
-    public ParkingKey(
-        int parkingId
-    ) {
-        this.parkingId = parkingId;
-    }
-
-    /**
-     * Gets parkingId.
-     *
-     * @return Value for parkingId.
-     */
-    public int getParkingId() {
-        return parkingId;
-    }
-
-    /**
-     * Sets parkingId.
-     *
-     * @param parkingId New value for parkingId.
-     */
-    public void setParkingId(int parkingId) {
-        this.parkingId = parkingId;
-    }
-
-    /** {@inheritDoc} */
-    @Override public boolean equals(Object o) {
-        if (this == o)
-            return true;
-
-        if (!(o instanceof ParkingKey))
-            return false;
-
-        ParkingKey that = (ParkingKey)o;
-
-        if (parkingId != that.parkingId)
-            return false;
-
-        return true;
-    }
-
-    /** {@inheritDoc} */
-    @Override public int hashCode() {
-        int res = parkingId;
-
-        return res;
-    }
-
-    /** {@inheritDoc} */
-    @Override public String toString() {
-        return "ParkingKey [parkingId=" + parkingId +
-            "]";
-    }
-}
-

http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-agent/src/main/java/org/apache/ignite/agent/handlers/DatabaseMetadataExtractor.java
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/agent/handlers/DatabaseMetadataExtractor.java b/modules/control-center-agent/src/main/java/org/apache/ignite/agent/handlers/DatabaseMetadataExtractor.java
deleted file mode 100644
index 0498656..0000000
--- a/modules/control-center-agent/src/main/java/org/apache/ignite/agent/handlers/DatabaseMetadataExtractor.java
+++ /dev/null
@@ -1,205 +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.agent.handlers;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FilenameFilter;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.net.URL;
-import java.sql.Connection;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Properties;
-import org.apache.ignite.agent.AgentConfiguration;
-import org.apache.ignite.agent.remote.Remote;
-import org.apache.ignite.agent.demo.AgentMetadataDemo;
-import org.apache.ignite.schema.parser.DbMetadataReader;
-import org.apache.ignite.schema.parser.DbTable;
-import org.apache.log4j.Logger;
-
-import static org.apache.ignite.agent.AgentUtils.resolvePath;
-
-/**
- * Remote API to extract database metadata.
- */
-public class DatabaseMetadataExtractor {
-    /** */
-    private static final Logger log = Logger.getLogger(DatabaseMetadataExtractor.class.getName());
-
-    /** */
-    private final File driversFolder;
-
-    /**
-     * @param cfg Config.
-     */
-    public DatabaseMetadataExtractor(AgentConfiguration cfg) {
-        driversFolder = resolvePath(cfg.driversFolder() == null ? "jdbc-drivers" : cfg.driversFolder());
-    }
-
-    /**
-     * @param jdbcDriverJarPath JDBC driver JAR path.
-     * @param jdbcDriverCls JDBC driver class.
-     * @param jdbcUrl JDBC URL.
-     * @param jdbcInfo Properties to connect to database.
-     * @return Connection to database.
-     * @throws SQLException
-     */
-    private Connection connect(String jdbcDriverJarPath, String jdbcDriverCls, String jdbcUrl, Properties jdbcInfo) throws SQLException {
-        if (!new File(jdbcDriverJarPath).isAbsolute() && driversFolder != null)
-            jdbcDriverJarPath = new File(driversFolder, jdbcDriverJarPath).getPath();
-
-        if (AgentMetadataDemo.isTestDriveUrl(jdbcUrl))
-            AgentMetadataDemo.testDrive();
-
-        return DbMetadataReader.getInstance().connect(jdbcDriverJarPath, jdbcDriverCls, jdbcUrl, jdbcInfo);
-    }
-
-    /**
-     * @param jdbcDriverJarPath JDBC driver JAR path.
-     * @param jdbcDriverCls JDBC driver class.
-     * @param jdbcUrl JDBC URL.
-     * @param jdbcInfo Properties to connect to database.
-     * @return Collection of schema names.
-     * @throws SQLException
-     */
-    @Remote
-    public Collection<String> schemas(String jdbcDriverJarPath, String jdbcDriverCls, String jdbcUrl,
-        Properties jdbcInfo) throws SQLException {
-        log.debug("Start collecting database schemas [driver jar=" + jdbcDriverJarPath +
-            ", driver class=" + jdbcDriverCls + ", url=" + jdbcUrl + "]");
-
-        try (Connection conn = connect(jdbcDriverJarPath, jdbcDriverCls, jdbcUrl, jdbcInfo)) {
-            Collection<String> schemas = DbMetadataReader.getInstance().schemas(conn);
-
-            log.debug("Finished collection of schemas [url=" + jdbcUrl + ", count="+ schemas.size() +"]");
-
-            return schemas;
-        }
-        catch (Throwable e) {
-            log.error("Failed to collect schemas", e);
-
-            throw new SQLException("Failed to collect schemas", e);
-        }
-    }
-
-    /**
-     * @param jdbcDriverJarPath JDBC driver JAR path.
-     * @param jdbcDriverCls JDBC driver class.
-     * @param jdbcUrl JDBC URL.
-     * @param jdbcInfo Properties to connect to database.
-     * @param schemas List of schema names to process.
-     * @param tblsOnly If {@code true} then only tables will be processed otherwise views also will be processed.
-     * @return Collection of tables.
-     */
-    @Remote
-    public Collection<DbTable> metadata(String jdbcDriverJarPath, String jdbcDriverCls, String jdbcUrl,
-        Properties jdbcInfo, List<String> schemas, boolean tblsOnly) throws SQLException {
-        log.debug("Start collecting database metadata [driver jar=" + jdbcDriverJarPath +
-            ", driver class=" + jdbcDriverCls + ", url=" + jdbcUrl + "]");
-
-        try (Connection conn = connect(jdbcDriverJarPath, jdbcDriverCls, jdbcUrl, jdbcInfo)) {
-            Collection<DbTable> metadata = DbMetadataReader.getInstance().metadata(conn, schemas, tblsOnly);
-
-            log.debug("Finished collection of metadata [url=" + jdbcUrl + ", count="+ metadata.size() +"]");
-
-            return metadata;
-        }
-        catch (Throwable e) {
-            log.error("Failed to collect metadata", e);
-
-            throw new SQLException("Failed to collect metadata", e);
-        }
-    }
-
-    /**
-     * @return Drivers in drivers folder
-     * @see AgentConfiguration#driversFolder
-     */
-    @Remote
-    public List<JdbcDriver> availableDrivers() {
-        if (driversFolder == null) {
-            log.info("JDBC drivers folder not specified, returning empty list");
-
-            return Collections.emptyList();
-        }
-
-        log.debug("Collecting JDBC drivers in folder: " + driversFolder.getPath());
-
-        File[] list = driversFolder.listFiles(new FilenameFilter() {
-            @Override public boolean accept(File dir, String name) {
-                return name.endsWith(".jar");
-            }
-        });
-
-        if (list == null) {
-            log.info("JDBC drivers folder has no files, returning empty list");
-
-            return Collections.emptyList();
-        }
-
-        List<JdbcDriver> res = new ArrayList<>();
-
-        for (File file : list) {
-            try {
-                boolean win = System.getProperty("os.name").contains("win");
-
-                URL url = new URL("jar", null, "file:" + (win ? "/" : "") + file.getPath() + "!/META-INF/services/java.sql.Driver");
-
-                try (BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream()))) {
-                    String jdbcDriverCls = reader.readLine();
-
-                    res.add(new JdbcDriver(file.getName(), jdbcDriverCls));
-
-                    log.debug("Found: [driver=" + file + ", class=" + jdbcDriverCls + "]");
-                }
-            }
-            catch (IOException e) {
-                res.add(new JdbcDriver(file.getName(), null));
-
-                log.info("Found: [driver=" + file + "]");
-                log.info("Failed to detect driver class: " + e.getMessage());
-            }
-        }
-
-        return res;
-    }
-
-    /**
-     * Wrapper class for later to be transformed to JSON and send to Web Console.
-     */
-    private static class JdbcDriver {
-        /** */
-        private final String jdbcDriverJar;
-        /** */
-        private final String jdbcDriverClass;
-
-        /**
-         * @param jdbcDriverJar File name of driver jar file.
-         * @param jdbcDriverClass Optional JDBC driver class.
-         */
-        public JdbcDriver(String jdbcDriverJar, String jdbcDriverClass) {
-            this.jdbcDriverJar = jdbcDriverJar;
-            this.jdbcDriverClass = jdbcDriverClass;
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-agent/src/main/java/org/apache/ignite/agent/handlers/RestExecutor.java
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/agent/handlers/RestExecutor.java b/modules/control-center-agent/src/main/java/org/apache/ignite/agent/handlers/RestExecutor.java
deleted file mode 100644
index 99b5626..0000000
--- a/modules/control-center-agent/src/main/java/org/apache/ignite/agent/handlers/RestExecutor.java
+++ /dev/null
@@ -1,195 +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.agent.handlers;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.net.ConnectException;
-import java.net.URISyntaxException;
-import java.nio.charset.Charset;
-import java.util.List;
-import java.util.Map;
-import org.apache.commons.codec.Charsets;
-import org.apache.http.Header;
-import org.apache.http.NameValuePair;
-import org.apache.http.client.entity.UrlEncodedFormEntity;
-import org.apache.http.client.methods.CloseableHttpResponse;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.client.methods.HttpPost;
-import org.apache.http.client.methods.HttpRequestBase;
-import org.apache.http.client.utils.URIBuilder;
-import org.apache.http.entity.StringEntity;
-import org.apache.http.impl.client.CloseableHttpClient;
-import org.apache.http.impl.client.HttpClientBuilder;
-import org.apache.ignite.agent.AgentConfiguration;
-import org.apache.ignite.agent.remote.Remote;
-import org.apache.ignite.agent.demo.AgentSqlDemo;
-import org.apache.log4j.Logger;
-
-import static org.apache.ignite.agent.AgentConfiguration.DFLT_NODE_PORT;
-
-/**
- * Executor for REST requests.
- */
-public class RestExecutor {
-    /** */
-    private static final Logger log = Logger.getLogger(RestExecutor.class.getName());
-
-    /** */
-    private final AgentConfiguration cfg;
-
-    /** */
-    private CloseableHttpClient httpClient;
-
-    /**
-     * @param cfg Config.
-     */
-    public RestExecutor(AgentConfiguration cfg) {
-        this.cfg = cfg;
-    }
-
-    /**
-     *
-     */
-    public void start() {
-        httpClient = HttpClientBuilder.create().build();
-    }
-
-    /**
-     *
-     */
-    public void stop() throws IOException {
-        if (httpClient != null)
-            httpClient.close();
-    }
-
-    /**
-     * @param path Path.
-     * @param mtd Method.
-     * @param params Params.
-     * @param headers Headers.
-     * @param body Body.
-     */
-    @Remote
-    public RestResult executeRest(String path, Map<String, String> params, String mtd, Map<String, String> headers,
-        String body) throws IOException, URISyntaxException {
-        log.debug("Start execute REST command [url=/" + path + ", method=" + mtd +
-            ", parameters=" + params + "]");
-
-        URIBuilder builder = new URIBuilder(cfg.nodeUri());
-
-        if (builder.getPort() == -1)
-            builder.setPort(DFLT_NODE_PORT);
-
-        if (path != null) {
-            if (!path.startsWith("/") && !cfg.nodeUri().endsWith("/"))
-                path = '/' + path;
-
-            builder.setPath(path);
-        }
-
-        if (params != null) {
-            for (Map.Entry<String, String> entry : params.entrySet())
-                builder.addParameter(entry.getKey(), entry.getValue());
-        }
-
-        HttpRequestBase httpReq;
-
-        if ("GET".equalsIgnoreCase(mtd))
-            httpReq = new HttpGet(builder.build());
-        else if ("POST".equalsIgnoreCase(mtd)) {
-            HttpPost post;
-
-            if (body == null) {
-                List<NameValuePair> nvps = builder.getQueryParams();
-
-                builder.clearParameters();
-
-                post = new HttpPost(builder.build());
-
-                if (!nvps.isEmpty())
-                    post.setEntity(new UrlEncodedFormEntity(nvps));
-            }
-            else {
-                post = new HttpPost(builder.build());
-
-                post.setEntity(new StringEntity(body));
-            }
-
-            httpReq = post;
-        }
-        else
-            throw new IOException("Unknown HTTP-method: " + mtd);
-
-        if (headers != null) {
-            for (Map.Entry<String, String> entry : headers.entrySet())
-                httpReq.addHeader(entry.getKey(), entry.getValue());
-        }
-
-        try (CloseableHttpResponse resp = httpClient.execute(httpReq)) {
-            ByteArrayOutputStream out = new ByteArrayOutputStream();
-
-            resp.getEntity().writeTo(out);
-
-            Charset charset = Charsets.UTF_8;
-
-            Header encodingHdr = resp.getEntity().getContentEncoding();
-
-            if (encodingHdr != null) {
-                String encoding = encodingHdr.getValue();
-
-                charset = Charsets.toCharset(encoding);
-            }
-
-            return new RestResult(resp.getStatusLine().getStatusCode(), new String(out.toByteArray(), charset));
-        }
-        catch (ConnectException e) {
-            log.debug("Failed connect to node and execute REST command [uri=" + builder.build() + "]");
-
-            return new RestResult(404, "Failed connect to node and execute REST command.");
-        }
-    }
-
-    /**
-     * Enable test-drive SQL.
-     */
-    @Remote
-    public boolean startDemoSQL() {
-        return AgentSqlDemo.testDrive(cfg);
-    }
-
-    /**
-     * Request result.
-     */
-    public static class RestResult {
-        /** Status code. */
-        private int code;
-
-        /** Message. */
-        private String message;
-
-        /**
-         * @param code Code.
-         * @param msg Message.
-         */
-        public RestResult(int code, String msg) {
-            this.code = code;
-            message = msg;
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-agent/src/main/java/org/apache/ignite/agent/remote/Remote.java
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/agent/remote/Remote.java b/modules/control-center-agent/src/main/java/org/apache/ignite/agent/remote/Remote.java
deleted file mode 100644
index 8fe49bd..0000000
--- a/modules/control-center-agent/src/main/java/org/apache/ignite/agent/remote/Remote.java
+++ /dev/null
@@ -1,37 +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.agent.remote;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * Use this annotation to associate methods with remote NodeJS server commands.
- */
-@Target(ElementType.METHOD)
-@Retention(RetentionPolicy.RUNTIME)
-public @interface Remote {
-    /**
-     * Whether or not method should be executed synchronously.
-     *
-     * @return {@code true} if method will be executed in separated thread otherwise if method will be executed in handler thread.
-     */
-    boolean async() default true;
-}

http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-agent/src/main/java/org/apache/ignite/agent/remote/RemoteHandler.java
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/agent/remote/RemoteHandler.java b/modules/control-center-agent/src/main/java/org/apache/ignite/agent/remote/RemoteHandler.java
deleted file mode 100644
index e15280f..0000000
--- a/modules/control-center-agent/src/main/java/org/apache/ignite/agent/remote/RemoteHandler.java
+++ /dev/null
@@ -1,252 +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.agent.remote;
-
-import com.google.gson.Gson;
-import com.google.gson.JsonArray;
-import com.google.gson.JsonElement;
-import com.google.gson.JsonNull;
-import com.google.gson.JsonObject;
-import com.google.gson.JsonPrimitive;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Type;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import org.apache.http.auth.AuthenticationException;
-import org.apache.log4j.Logger;
-
-/**
- * Allow to execute methods remotely from NodeJS server by web-socket command.
- */
-public class RemoteHandler implements AutoCloseable {
-    /** */
-    public static final Gson GSON = new Gson();
-
-    /** */
-    public static final Object[] EMPTY_OBJECTS = new Object[0];
-
-    /** */
-    private static final Logger log = Logger.getLogger(RemoteHandler.class.getName());
-
-    /** */
-    private static final String INTERNAL_EXCEPTION_TYPE = "org.apache.ignite.agent.AgentException";
-
-    /** */
-    private final WebSocketSender snd;
-
-    /** */
-    private final Map<String, MethodDescriptor> mtds = new HashMap<>();
-
-    /** */
-    private final ExecutorService executorSrvc = Executors.newFixedThreadPool(Runtime.getRuntime()
-        .availableProcessors());
-
-    /**
-     * @param snd Session.
-     * @param hnds Handlers.
-     */
-    private RemoteHandler(WebSocketSender snd, Object ... hnds) {
-        this.snd = snd;
-
-        for (Object hnd : hnds) {
-            for (Method method : hnd.getClass().getMethods()) {
-                Remote remoteAnn = method.getAnnotation(Remote.class);
-
-                if (remoteAnn != null) {
-                    MethodDescriptor old = mtds.put(method.getName(), new MethodDescriptor(method, hnd,
-                        remoteAnn.async()));
-
-                    if (old != null)
-                        throw new IllegalArgumentException("Duplicated method: " + method.getName());
-                }
-            }
-        }
-    }
-
-    /**
-     * @param hnds Handler.
-     * @param snd Sender.
-     */
-    public static RemoteHandler wrap(WebSocketSender snd, Object ... hnds) {
-        return new RemoteHandler(snd, hnds);
-    }
-
-    /**
-     * @param req Request.
-     */
-    public void onMessage(JsonObject req) {
-        JsonPrimitive reqIdJson = req.getAsJsonPrimitive("reqId");
-
-        final Long reqId = reqIdJson == null ? null : reqIdJson.getAsLong();
-
-        String mtdName = req.getAsJsonPrimitive("mtdName").getAsString();
-
-        final MethodDescriptor desc = mtds.get(mtdName);
-
-        if (desc == null) {
-            sendException(reqId, INTERNAL_EXCEPTION_TYPE, "Unknown method: " + mtdName);
-
-            return;
-        }
-
-        Type[] paramTypes = desc.mtd.getGenericParameterTypes();
-
-        JsonArray argsJson = req.getAsJsonArray("args");
-
-        final Object[] args;
-
-        if (paramTypes.length > 0) {
-            args = new Object[paramTypes.length];
-
-            if (argsJson == null || argsJson.size() != paramTypes.length) {
-                sendException(reqId, INTERNAL_EXCEPTION_TYPE, "Inconsistent parameters");
-
-                return;
-            }
-
-            for (int i = 0; i < paramTypes.length; i++)
-                args[i] = GSON.fromJson(argsJson.get(i), paramTypes[i]);
-        }
-        else {
-            args = EMPTY_OBJECTS;
-
-            if (argsJson != null && argsJson.size() > 0) {
-                sendException(reqId, INTERNAL_EXCEPTION_TYPE, "Inconsistent parameters");
-
-                return;
-            }
-        }
-
-        Runnable run = new Runnable() {
-            @Override public void run() {
-                final Object res;
-
-                try {
-                    res = desc.mtd.invoke(desc.hnd, args);
-                }
-                catch (Throwable e) {
-                    if (e instanceof AuthenticationException) {
-                        close();
-
-                        return;
-                    }
-
-                    if (e instanceof InvocationTargetException)
-                        e = ((InvocationTargetException)e).getTargetException();
-
-                    if (reqId != null)
-                        sendException(reqId, e.getClass().getName(), e.getMessage());
-                    else
-                        log.error("Exception on execute remote method.", e);
-
-                    return;
-                }
-
-                sendResponse(reqId, res, desc.returnType);
-            }
-        };
-
-        if (desc.async)
-            executorSrvc.submit(run);
-        else
-            run.run();
-    }
-
-    /**
-     * @param reqId Request id.
-     * @param exType Exception class name.
-     * @param exMsg Exception message.
-     */
-    protected void sendException(Long reqId, String exType, String exMsg) {
-        if (reqId == null)
-            return;
-
-        JsonObject res = new JsonObject();
-
-        res.addProperty("type", "CallRes");
-        res.addProperty("reqId", reqId);
-
-        JsonObject exJson = new JsonObject();
-        exJson.addProperty("type", exType);
-        exJson.addProperty("message", exMsg);
-
-        res.add("ex", exJson);
-
-        snd.send(res);
-    }
-
-    /**
-     * @param reqId Request id.
-     * @param res Result.
-     * @param type Type.
-     */
-    private void sendResponse(Long reqId, Object res, Type type) {
-        if (reqId == null)
-            return;
-
-        JsonObject resp = new JsonObject();
-
-        resp.addProperty("type", "CallRes");
-
-        resp.addProperty("reqId", reqId);
-
-        JsonElement resJson = type == void.class ? JsonNull.INSTANCE : GSON.toJsonTree(res, type);
-
-        resp.add("res", resJson);
-
-        snd.send(resp);
-    }
-
-    /** {@inheritDoc} */
-    @Override public void close() {
-        executorSrvc.shutdown();
-    }
-
-    /**
-     *
-     */
-    private static class MethodDescriptor {
-        /** */
-        private final Method mtd;
-
-        /** */
-        private final Object hnd;
-
-        /** */
-        private final Type returnType;
-
-        /** */
-        private final boolean async;
-
-        /**
-         * @param mtd Method.
-         * @param hnd Handler.
-         * @param async Async.
-         */
-        MethodDescriptor(Method mtd, Object hnd, boolean async) {
-            this.mtd = mtd;
-            this.hnd = hnd;
-            this.async = async;
-
-            returnType = mtd.getGenericReturnType();
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-agent/src/main/java/org/apache/ignite/agent/remote/WebSocketSender.java
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/agent/remote/WebSocketSender.java b/modules/control-center-agent/src/main/java/org/apache/ignite/agent/remote/WebSocketSender.java
deleted file mode 100644
index 655ff85..0000000
--- a/modules/control-center-agent/src/main/java/org/apache/ignite/agent/remote/WebSocketSender.java
+++ /dev/null
@@ -1,39 +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.agent.remote;
-
-import com.google.gson.JsonObject;
-
-/**
- * Sender for messages to web-socket.
- */
-public interface WebSocketSender {
-    /**
-     * Send message.
-     * @param msg Message.
-     * @return {@code true} if message sent successfully.
-     */
-    public boolean send(String msg);
-
-    /**
-     * Send message.
-     * @param msg Message.
-     * @return {@code true} if message sent successfully.
-     */
-    public boolean send(JsonObject msg);
-}

http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/AgentConfiguration.java
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/AgentConfiguration.java b/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/AgentConfiguration.java
new file mode 100644
index 0000000..6259cca
--- /dev/null
+++ b/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/AgentConfiguration.java
@@ -0,0 +1,255 @@
+/*
+ * 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.console.agent;
+
+import com.beust.jcommander.Parameter;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.net.URL;
+import java.util.Properties;
+
+/**
+ * Agent configuration.
+ */
+public class AgentConfiguration {
+    /** Default server port. */
+    public static final int DFLT_SERVER_PORT = 3001;
+
+    /** Default Ignite node HTTP port. */
+    public static final int DFLT_NODE_PORT = 8080;
+
+    /** Default path to agent property file. */
+    public static final String DFLT_CFG_PATH = "default.properties";
+
+    /** Default server URI. */
+    private static final String DFLT_SERVER_URI = "wss://localhost:3001";
+
+    /** Default Ignite node HTTP URI. */
+    private static final String DFLT_NODE_URI = "http://localhost:8080";
+
+    /** */
+    @Parameter(names = {"-t", "--token"}, description = "User's security token used to establish connection to Ignite Console.")
+    private String tok;
+
+    /** */
+    @Parameter(names = {"-s", "--server-uri"}, description = "URI for connect to Ignite Console via web-socket protocol" +
+        "           " +
+        "      Default value: " + DFLT_SERVER_URI)
+    private String srvUri;
+
+    /** */
+    @Parameter(names = {"-n", "--node-uri"}, description = "URI for connect to Ignite node REST server" +
+        "                        " +
+        "      Default value: " + DFLT_NODE_URI)
+    private String nodeUri;
+
+    /** URI for connect to Ignite demo node REST server */
+    private String demoNodeUri;
+
+    /** */
+    @Parameter(names = {"-c", "--config"}, description = "Path to agent property file" +
+        "                                  " +
+        "      Default value: " + DFLT_CFG_PATH)
+    private String cfgPath;
+
+    /** */
+    @Parameter(names = {"-d", "--driver-folder"}, description = "Path to folder with JDBC drivers" +
+        "                             " +
+        "      Default value: ./jdbc-drivers")
+    private String driversFolder;
+
+    /** */
+    @Parameter(names = { "-h", "--help" }, help = true, description = "Print this help message")
+    private Boolean help;
+
+    /**
+     * @return Token.
+     */
+    public String token() {
+        return tok;
+    }
+
+    /**
+     * @param tok Token.
+     */
+    public void token(String tok) {
+        this.tok = tok;
+    }
+
+    /**
+     * @return Server URI.
+     */
+    public String serverUri() {
+        return srvUri;
+    }
+
+    /**
+     * @param srvUri URI.
+     */
+    public void serverUri(String srvUri) {
+        this.srvUri = srvUri;
+    }
+
+    /**
+     * @return Node URI.
+     */
+    public String nodeUri() {
+        return nodeUri;
+    }
+
+    /**
+     * @param nodeUri Node URI.
+     */
+    public void nodeUri(String nodeUri) {
+        this.nodeUri = nodeUri;
+    }
+
+    /**
+     * @return Demo node URI.
+     */
+    public String demoNodeUri() {
+        return demoNodeUri;
+    }
+
+    /**
+     * @param demoNodeUri Demo node URI.
+     */
+    public void demoNodeUri(String demoNodeUri) {
+        this.demoNodeUri = demoNodeUri;
+    }
+
+    /**
+     * @return Configuration path.
+     */
+    public String configPath() {
+        return cfgPath == null ? DFLT_CFG_PATH : cfgPath;
+    }
+
+    /**
+     * @return Configured drivers folder.
+     */
+    public String driversFolder() {
+        return driversFolder;
+    }
+
+    /**
+     * @param driversFolder Driver folder.
+     */
+    public void driversFolder(String driversFolder) {
+        this.driversFolder = driversFolder;
+    }
+
+    /**
+     * @return {@code true} If agent options usage should be printed.
+     */
+    public Boolean help() {
+        return help != null ? help : false;
+    }
+
+    /**
+     * @param cfgUrl URL.
+     */
+    public void load(URL cfgUrl) throws IOException {
+        Properties props = new Properties();
+
+        try (Reader reader = new InputStreamReader(cfgUrl.openStream())) {
+            props.load(reader);
+        }
+
+        String val = (String)props.remove("token");
+
+        if (val != null)
+            token(val);
+
+        val = (String)props.remove("server-uri");
+
+        if (val != null)
+            serverUri(val);
+
+        val = (String)props.remove("node-uri");
+
+        if (val != null)
+            nodeUri(val);
+
+        val = (String)props.remove("driver-folder");
+
+        if (val != null)
+            driversFolder(val);
+    }
+
+    /**
+     * @param cmd Command.
+     */
+    public void merge(AgentConfiguration cmd) {
+        if (tok == null)
+            token(cmd.token());
+
+        if (srvUri == null)
+            serverUri(cmd.serverUri());
+
+        if (srvUri == null)
+            serverUri(DFLT_SERVER_URI);
+
+        if (nodeUri == null)
+            nodeUri(cmd.nodeUri());
+
+        if (nodeUri == null)
+            nodeUri(DFLT_NODE_URI);
+
+        if (driversFolder == null)
+            driversFolder(cmd.driversFolder());
+    }
+
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        StringBuilder sb = new StringBuilder();
+
+        if (tok != null && tok.length() > 0) {
+            sb.append("User's security token         : ");
+
+            if (tok.length() > 4) {
+                sb.append(new String(new char[tok.length() - 4]).replace("\0", "*"));
+
+                sb.append(tok.substring(tok.length() - 4));
+            }
+            else
+                sb.append(new String(new char[tok.length()]).replace("\0", "*"));
+
+            sb.append('\n');
+        }
+
+        sb.append("URI to Ignite node REST server: ").append(nodeUri == null ? DFLT_NODE_URI : nodeUri).append('\n');
+        sb.append("URI to Ignite Console server  : ").append(srvUri == null ? DFLT_SERVER_URI : srvUri).append('\n');
+        sb.append("Path to agent property file   : ").append(configPath()).append('\n');
+
+        String drvFld = driversFolder();
+
+        if (drvFld == null) {
+            File agentHome = AgentUtils.getAgentHome();
+
+            if (agentHome != null)
+                drvFld = new File(agentHome, "jdbc-drivers").getPath();
+        }
+
+        sb.append("Path to JDBC drivers folder   : ").append(drvFld);
+
+        return sb.toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/AgentLauncher.java
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/AgentLauncher.java b/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/AgentLauncher.java
new file mode 100644
index 0000000..ed08d78
--- /dev/null
+++ b/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/AgentLauncher.java
@@ -0,0 +1,164 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.console.agent;
+
+import com.beust.jcommander.JCommander;
+import java.io.File;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.Arrays;
+
+import com.beust.jcommander.ParameterException;
+import org.apache.ignite.console.agent.handlers.RestExecutor;
+import org.apache.log4j.Logger;
+import org.eclipse.jetty.util.ssl.SslContextFactory;
+import org.eclipse.jetty.websocket.client.WebSocketClient;
+
+import static org.apache.ignite.console.agent.AgentConfiguration.DFLT_SERVER_PORT;
+
+/**
+ * Control Center Agent launcher.
+ */
+public class AgentLauncher {
+    /** */
+    private static final Logger log = Logger.getLogger(AgentLauncher.class.getName());
+
+    /** */
+    private static final int RECONNECT_INTERVAL = 3000;
+
+    /**
+     * @param args Args.
+     */
+    @SuppressWarnings("BusyWait")
+    public static void main(String[] args) throws Exception {
+        log.info("Starting Apache Ignite Web Console Agent...");
+
+        AgentConfiguration cfg = new AgentConfiguration();
+
+        JCommander jCommander = new JCommander(cfg);
+
+        String osName = System.getProperty("os.name").toLowerCase();
+
+        jCommander.setProgramName("ignite-web-agent." + (osName.contains("win") ? "bat" : "sh"));
+
+        try {
+            jCommander.parse(args);
+        }
+        catch (ParameterException pe) {
+            log.error("Failed to parse command line parameters: " + Arrays.toString(args), pe);
+
+            jCommander.usage();
+
+            return;
+        }
+
+        String prop = cfg.configPath();
+
+        AgentConfiguration propCfg = new AgentConfiguration();
+
+        try {
+            File f = AgentUtils.resolvePath(prop);
+
+            if (f == null)
+                log.warn("Failed to find agent property file: '" + prop + "'");
+            else
+                propCfg.load(f.toURI().toURL());
+        }
+        catch (IOException ignore) {
+            if (!AgentConfiguration.DFLT_CFG_PATH.equals(prop))
+                log.warn("Failed to load agent property file: '" + prop + "'", ignore);
+        }
+
+        cfg.merge(propCfg);
+
+        if (cfg.help()) {
+            jCommander.usage();
+
+            return;
+        }
+
+        System.out.println();
+        System.out.println("Agent configuration:");
+        System.out.println(cfg);
+        System.out.println();
+
+        if (cfg.token() == null) {
+            String webHost;
+
+            try {
+                webHost = new URI(cfg.serverUri()).getHost();
+            }
+            catch (URISyntaxException e) {
+                log.error("Failed to parse Ignite Web Console uri", e);
+
+                return;
+            }
+
+            System.out.println("Security token is required to establish connection to the web console.");
+            System.out.println(String.format("It is available on the Profile page: https://%s/profile", webHost));
+
+            System.out.print("Enter security token: ");
+
+            cfg.token(System.console().readLine().trim());
+        }
+
+        RestExecutor restExecutor = new RestExecutor(cfg);
+
+        restExecutor.start();
+
+        try {
+            SslContextFactory sslCtxFactory = new SslContextFactory();
+
+            // Workaround for use self-signed certificate:
+            if (Boolean.getBoolean("trust.all"))
+                sslCtxFactory.setTrustAll(true);
+
+            WebSocketClient client = new WebSocketClient(sslCtxFactory);
+
+            client.setMaxIdleTimeout(Long.MAX_VALUE);
+
+            client.start();
+
+            try {
+                while (!Thread.interrupted()) {
+                    AgentSocket agentSock = new AgentSocket(cfg, restExecutor);
+
+                    log.info("Connecting to: " + cfg.serverUri());
+
+                    URI uri = URI.create(cfg.serverUri());
+
+                    if (uri.getPort() == -1)
+                        uri = URI.create(cfg.serverUri() + ":" + DFLT_SERVER_PORT);
+
+                    client.connect(agentSock, uri);
+
+                    agentSock.waitForClose();
+
+                    Thread.sleep(RECONNECT_INTERVAL);
+                }
+            }
+            finally {
+                client.stop();
+            }
+        }
+        finally {
+            restExecutor.stop();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/AgentSocket.java
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/AgentSocket.java b/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/AgentSocket.java
new file mode 100644
index 0000000..80816fa
--- /dev/null
+++ b/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/AgentSocket.java
@@ -0,0 +1,189 @@
+/*
+ * 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.console.agent;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import java.io.IOException;
+import java.net.ConnectException;
+import java.util.concurrent.CountDownLatch;
+import javax.net.ssl.SSLHandshakeException;
+import org.apache.ignite.console.agent.handlers.DatabaseMetadataExtractor;
+import org.apache.ignite.console.agent.handlers.RestExecutor;
+import org.apache.ignite.console.agent.remote.Remote;
+import org.apache.ignite.console.agent.remote.RemoteHandler;
+import org.apache.ignite.console.agent.remote.WebSocketSender;
+import org.apache.log4j.Logger;
+import org.eclipse.jetty.websocket.api.Session;
+import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose;
+import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect;
+import org.eclipse.jetty.websocket.api.annotations.OnWebSocketError;
+import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage;
+import org.eclipse.jetty.websocket.api.annotations.WebSocket;
+
+/**
+ * Handler for web-socket connection.
+ */
+@WebSocket
+public class AgentSocket implements WebSocketSender {
+    /** */
+    public static final Gson GSON = new Gson();
+
+    /** */
+    public static final JsonParser PARSER = new JsonParser();
+
+    /** */
+    private static final Logger log = Logger.getLogger(AgentSocket.class.getName());
+
+    /** */
+    private final CountDownLatch closeLatch = new CountDownLatch(1);
+
+    /** */
+    private final AgentConfiguration cfg;
+
+    /** */
+    private final RestExecutor restExecutor;
+
+    /** */
+    private RemoteHandler remote;
+
+    /** */
+    private Session ses;
+
+    /**
+     * @param cfg Config.
+     */
+    public AgentSocket(AgentConfiguration cfg, RestExecutor restExecutor) {
+        this.cfg = cfg;
+        this.restExecutor = restExecutor;
+    }
+
+    /**
+     * @param statusCode Status code.
+     * @param reason Reason.
+     */
+    @OnWebSocketClose
+    public void onClose(int statusCode, String reason) {
+        log.warn(String.format("Connection closed: %d - %s.", statusCode, reason));
+
+        if (remote != null)
+            remote.close();
+
+        closeLatch.countDown();
+    }
+
+    /**
+     * @param ses Session.
+     */
+    @OnWebSocketConnect
+    public void onConnect(Session ses) {
+        log.info("Connection established.");
+
+        this.ses = ses;
+
+        remote = RemoteHandler.wrap(this, this, restExecutor, new DatabaseMetadataExtractor(cfg));
+
+        JsonObject authMsg = new JsonObject();
+
+        authMsg.addProperty("type", "AuthMessage");
+        authMsg.addProperty("token", cfg.token());
+
+        send(authMsg);
+    }
+
+    /**
+     * @param msg Message.
+     * @return Whether or not message was sent.
+     */
+    @Override public boolean send(JsonObject msg) {
+        return send(GSON.toJson(msg));
+    }
+
+    /**
+     * @param msg Message.
+     * @return Whether or not message was sent.
+     */
+    @Override public boolean send(String msg) {
+        try {
+            ses.getRemote().sendString(msg);
+
+            return true;
+        }
+        catch (IOException ignored) {
+            log.error("Failed to send message to Control Center.");
+
+            return false;
+        }
+    }
+
+    /**
+     * @param ses Session.
+     * @param error Error.
+     */
+    @OnWebSocketError
+    public void onError(Session ses, Throwable error) {
+        if (error instanceof ConnectException)
+            log.warn(error.getMessage());
+        else if (error instanceof SSLHandshakeException) {
+            log.error("Failed to establish SSL connection to Ignite Console. Start agent with " +
+                "\"-Dtrust.all=true\" to skip certificate validation in case of using self-signed certificate.", error);
+
+            System.exit(1);
+        }
+        else
+            log.error("Connection error.", error);
+
+        if (remote != null)
+            remote.close();
+
+        closeLatch.countDown();
+    }
+
+    /**
+     * @param msg Message.
+     */
+    @OnWebSocketMessage
+    public void onMessage(String msg) {
+        JsonElement jsonElement = PARSER.parse(msg);
+
+        remote.onMessage((JsonObject)jsonElement);
+    }
+
+    /**
+     * @param errorMsg Authentication failed message or {@code null} if authentication success.
+     */
+    @Remote
+    public void authResult(String errorMsg) {
+        if (errorMsg != null) {
+            onClose(401, "Authentication failed: " + errorMsg);
+
+            System.exit(1);
+        }
+
+        log.info("Authentication success.");
+    }
+
+    /**
+     * Await socket close.
+     */
+    public void waitForClose() throws InterruptedException {
+        closeLatch.await();
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/AgentUtils.java
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/AgentUtils.java b/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/AgentUtils.java
new file mode 100644
index 0000000..349eea1
--- /dev/null
+++ b/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/AgentUtils.java
@@ -0,0 +1,115 @@
+/*
+ * 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.console.agent;
+
+import org.apache.log4j.Logger;
+
+import java.io.File;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.security.ProtectionDomain;
+
+/**
+ * Utility methods.
+ */
+public class AgentUtils {
+    /** */
+    private static final Logger log = Logger.getLogger(AgentUtils.class.getName());
+
+    /**
+     * Default constructor.
+     */
+    private AgentUtils() {
+        // No-op.
+    }
+
+    /**
+     * @param path Path to normalize.
+     * @return Normalized file path.
+     */
+    public static String normalizePath(String path) {
+        return path != null ? path.replace('\\', '/') : null;
+    }
+
+    /**
+     * @return App folder.
+     */
+    public static File getAgentHome() {
+        try {
+            ProtectionDomain domain = AgentLauncher.class.getProtectionDomain();
+
+            // Should not happen, but to make sure our code is not broken.
+            if (domain == null || domain.getCodeSource() == null || domain.getCodeSource().getLocation() == null) {
+                log.warn("Failed to resolve agent jar location!");
+
+                return null;
+            }
+
+            // Resolve path to class-file.
+            URI classesUri = domain.getCodeSource().getLocation().toURI();
+
+            boolean win = System.getProperty("os.name").toLowerCase().contains("win");
+
+            // Overcome UNC path problem on Windows (http://www.tomergabel.com/JavaMishandlesUNCPathsOnWindows.aspx)
+            if (win && classesUri.getAuthority() != null)
+                classesUri = new URI(classesUri.toString().replace("file://", "file:/"));
+
+            return new File(classesUri).getParentFile();
+        }
+        catch (URISyntaxException | SecurityException ignored) {
+            log.warn("Failed to resolve agent jar location!");
+
+            return null;
+        }
+    }
+
+    /**
+     * Gets file associated with path.
+     * <p>
+     * First check if path is relative to agent home.
+     * If not, check if path is absolute.
+     * If all checks fail, then {@code null} is returned.
+     * <p>
+     *
+     * @param path Path to resolve.
+     * @return Resolved path as file, or {@code null} if path cannot be resolved.
+     */
+    public static File resolvePath(String path) {
+        assert path != null;
+
+        File home = getAgentHome();
+
+        if (home != null) {
+            File file = new File(home, normalizePath(path));
+
+            if (file.exists())
+                return file;
+        }
+
+        /*
+         * 2. Check given path as absolute.
+         */
+
+        File file = new File(path);
+
+        if (file.exists())
+            return file;
+
+        return null;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/handlers/DatabaseMetadataExtractor.java
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/handlers/DatabaseMetadataExtractor.java b/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/handlers/DatabaseMetadataExtractor.java
new file mode 100644
index 0000000..48d5236
--- /dev/null
+++ b/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/handlers/DatabaseMetadataExtractor.java
@@ -0,0 +1,205 @@
+/*
+ * 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.console.agent.handlers;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Properties;
+import org.apache.ignite.console.agent.AgentConfiguration;
+import org.apache.ignite.console.agent.remote.Remote;
+import org.apache.ignite.console.demo.AgentMetadataDemo;
+import org.apache.ignite.schema.parser.DbMetadataReader;
+import org.apache.ignite.schema.parser.DbTable;
+import org.apache.log4j.Logger;
+
+import static org.apache.ignite.console.agent.AgentUtils.resolvePath;
+
+/**
+ * Remote API to extract database metadata.
+ */
+public class DatabaseMetadataExtractor {
+    /** */
+    private static final Logger log = Logger.getLogger(DatabaseMetadataExtractor.class.getName());
+
+    /** */
+    private final File driversFolder;
+
+    /**
+     * @param cfg Config.
+     */
+    public DatabaseMetadataExtractor(AgentConfiguration cfg) {
+        driversFolder = resolvePath(cfg.driversFolder() == null ? "jdbc-drivers" : cfg.driversFolder());
+    }
+
+    /**
+     * @param jdbcDriverJarPath JDBC driver JAR path.
+     * @param jdbcDriverCls JDBC driver class.
+     * @param jdbcUrl JDBC URL.
+     * @param jdbcInfo Properties to connect to database.
+     * @return Connection to database.
+     * @throws SQLException
+     */
+    private Connection connect(String jdbcDriverJarPath, String jdbcDriverCls, String jdbcUrl, Properties jdbcInfo) throws SQLException {
+        if (!new File(jdbcDriverJarPath).isAbsolute() && driversFolder != null)
+            jdbcDriverJarPath = new File(driversFolder, jdbcDriverJarPath).getPath();
+
+        if (AgentMetadataDemo.isTestDriveUrl(jdbcUrl))
+            AgentMetadataDemo.testDrive();
+
+        return DbMetadataReader.getInstance().connect(jdbcDriverJarPath, jdbcDriverCls, jdbcUrl, jdbcInfo);
+    }
+
+    /**
+     * @param jdbcDriverJarPath JDBC driver JAR path.
+     * @param jdbcDriverCls JDBC driver class.
+     * @param jdbcUrl JDBC URL.
+     * @param jdbcInfo Properties to connect to database.
+     * @return Collection of schema names.
+     * @throws SQLException
+     */
+    @Remote
+    public Collection<String> schemas(String jdbcDriverJarPath, String jdbcDriverCls, String jdbcUrl,
+        Properties jdbcInfo) throws SQLException {
+        log.debug("Start collecting database schemas [driver jar=" + jdbcDriverJarPath +
+            ", driver class=" + jdbcDriverCls + ", url=" + jdbcUrl + "]");
+
+        try (Connection conn = connect(jdbcDriverJarPath, jdbcDriverCls, jdbcUrl, jdbcInfo)) {
+            Collection<String> schemas = DbMetadataReader.getInstance().schemas(conn);
+
+            log.debug("Finished collection of schemas [url=" + jdbcUrl + ", count="+ schemas.size() +"]");
+
+            return schemas;
+        }
+        catch (Throwable e) {
+            log.error("Failed to collect schemas", e);
+
+            throw new SQLException("Failed to collect schemas", e);
+        }
+    }
+
+    /**
+     * @param jdbcDriverJarPath JDBC driver JAR path.
+     * @param jdbcDriverCls JDBC driver class.
+     * @param jdbcUrl JDBC URL.
+     * @param jdbcInfo Properties to connect to database.
+     * @param schemas List of schema names to process.
+     * @param tblsOnly If {@code true} then only tables will be processed otherwise views also will be processed.
+     * @return Collection of tables.
+     */
+    @Remote
+    public Collection<DbTable> metadata(String jdbcDriverJarPath, String jdbcDriverCls, String jdbcUrl,
+        Properties jdbcInfo, List<String> schemas, boolean tblsOnly) throws SQLException {
+        log.debug("Start collecting database metadata [driver jar=" + jdbcDriverJarPath +
+            ", driver class=" + jdbcDriverCls + ", url=" + jdbcUrl + "]");
+
+        try (Connection conn = connect(jdbcDriverJarPath, jdbcDriverCls, jdbcUrl, jdbcInfo)) {
+            Collection<DbTable> metadata = DbMetadataReader.getInstance().metadata(conn, schemas, tblsOnly);
+
+            log.debug("Finished collection of metadata [url=" + jdbcUrl + ", count="+ metadata.size() +"]");
+
+            return metadata;
+        }
+        catch (Throwable e) {
+            log.error("Failed to collect metadata", e);
+
+            throw new SQLException("Failed to collect metadata", e);
+        }
+    }
+
+    /**
+     * @return Drivers in drivers folder
+     * @see AgentConfiguration#driversFolder
+     */
+    @Remote
+    public List<JdbcDriver> availableDrivers() {
+        if (driversFolder == null) {
+            log.info("JDBC drivers folder not specified, returning empty list");
+
+            return Collections.emptyList();
+        }
+
+        log.debug("Collecting JDBC drivers in folder: " + driversFolder.getPath());
+
+        File[] list = driversFolder.listFiles(new FilenameFilter() {
+            @Override public boolean accept(File dir, String name) {
+                return name.endsWith(".jar");
+            }
+        });
+
+        if (list == null) {
+            log.info("JDBC drivers folder has no files, returning empty list");
+
+            return Collections.emptyList();
+        }
+
+        List<JdbcDriver> res = new ArrayList<>();
+
+        for (File file : list) {
+            try {
+                boolean win = System.getProperty("os.name").contains("win");
+
+                URL url = new URL("jar", null, "file:" + (win ? "/" : "") + file.getPath() + "!/META-INF/services/java.sql.Driver");
+
+                try (BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream()))) {
+                    String jdbcDriverCls = reader.readLine();
+
+                    res.add(new JdbcDriver(file.getName(), jdbcDriverCls));
+
+                    log.debug("Found: [driver=" + file + ", class=" + jdbcDriverCls + "]");
+                }
+            }
+            catch (IOException e) {
+                res.add(new JdbcDriver(file.getName(), null));
+
+                log.info("Found: [driver=" + file + "]");
+                log.info("Failed to detect driver class: " + e.getMessage());
+            }
+        }
+
+        return res;
+    }
+
+    /**
+     * Wrapper class for later to be transformed to JSON and send to Web Console.
+     */
+    private static class JdbcDriver {
+        /** */
+        private final String jdbcDriverJar;
+        /** */
+        private final String jdbcDriverClass;
+
+        /**
+         * @param jdbcDriverJar File name of driver jar file.
+         * @param jdbcDriverClass Optional JDBC driver class.
+         */
+        public JdbcDriver(String jdbcDriverJar, String jdbcDriverClass) {
+            this.jdbcDriverJar = jdbcDriverJar;
+            this.jdbcDriverClass = jdbcDriverClass;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/handlers/RestExecutor.java
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/handlers/RestExecutor.java b/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/handlers/RestExecutor.java
new file mode 100644
index 0000000..ee6742a
--- /dev/null
+++ b/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/handlers/RestExecutor.java
@@ -0,0 +1,195 @@
+/*
+ * 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.console.agent.handlers;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.net.ConnectException;
+import java.net.URISyntaxException;
+import java.nio.charset.Charset;
+import java.util.List;
+import java.util.Map;
+import org.apache.commons.codec.Charsets;
+import org.apache.http.Header;
+import org.apache.http.NameValuePair;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.methods.HttpRequestBase;
+import org.apache.http.client.utils.URIBuilder;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.apache.ignite.console.agent.AgentConfiguration;
+import org.apache.ignite.console.agent.remote.Remote;
+import org.apache.ignite.console.demo.AgentSqlDemo;
+import org.apache.log4j.Logger;
+
+import static org.apache.ignite.console.agent.AgentConfiguration.DFLT_NODE_PORT;
+
+/**
+ * Executor for REST requests.
+ */
+public class RestExecutor {
+    /** */
+    private static final Logger log = Logger.getLogger(RestExecutor.class.getName());
+
+    /** */
+    private final AgentConfiguration cfg;
+
+    /** */
+    private CloseableHttpClient httpClient;
+
+    /**
+     * @param cfg Config.
+     */
+    public RestExecutor(AgentConfiguration cfg) {
+        this.cfg = cfg;
+    }
+
+    /**
+     *
+     */
+    public void start() {
+        httpClient = HttpClientBuilder.create().build();
+    }
+
+    /**
+     *
+     */
+    public void stop() throws IOException {
+        if (httpClient != null)
+            httpClient.close();
+    }
+
+    /**
+     * @param uri Url.
+     * @param params Params.
+     * @param demo Use demo node.
+     * @param mtd Method.
+     * @param headers Headers.
+     * @param body Body.
+     */
+    @Remote
+    public RestResult executeRest(String uri, Map<String, String> params, boolean demo,
+        String mtd, Map<String, String> headers, String body) throws IOException, URISyntaxException {
+        log.debug("Start execute REST command [method=" + mtd + ", uri=/" + uri + ", parameters=" + params + "]");
+
+        URIBuilder builder = new URIBuilder(demo ? cfg.demoNodeUri() : cfg.nodeUri());
+
+        if (builder.getPort() == -1)
+            builder.setPort(DFLT_NODE_PORT);
+
+        if (uri != null) {
+            if (!uri.startsWith("/") && !cfg.nodeUri().endsWith("/"))
+                uri = '/' + uri;
+
+            builder.setPath(uri);
+        }
+
+        if (params != null) {
+            for (Map.Entry<String, String> entry : params.entrySet())
+                builder.addParameter(entry.getKey(), entry.getValue());
+        }
+
+        HttpRequestBase httpReq;
+
+        if ("GET".equalsIgnoreCase(mtd))
+            httpReq = new HttpGet(builder.build());
+        else if ("POST".equalsIgnoreCase(mtd)) {
+            HttpPost post;
+
+            if (body == null) {
+                List<NameValuePair> nvps = builder.getQueryParams();
+
+                builder.clearParameters();
+
+                post = new HttpPost(builder.build());
+
+                if (!nvps.isEmpty())
+                    post.setEntity(new UrlEncodedFormEntity(nvps));
+            }
+            else {
+                post = new HttpPost(builder.build());
+
+                post.setEntity(new StringEntity(body));
+            }
+
+            httpReq = post;
+        }
+        else
+            throw new IOException("Unknown HTTP-method: " + mtd);
+
+        if (headers != null) {
+            for (Map.Entry<String, String> entry : headers.entrySet())
+                httpReq.addHeader(entry.getKey(), entry.getValue());
+        }
+
+        try (CloseableHttpResponse resp = httpClient.execute(httpReq)) {
+            ByteArrayOutputStream out = new ByteArrayOutputStream();
+
+            resp.getEntity().writeTo(out);
+
+            Charset charset = Charsets.UTF_8;
+
+            Header encodingHdr = resp.getEntity().getContentEncoding();
+
+            if (encodingHdr != null) {
+                String encoding = encodingHdr.getValue();
+
+                charset = Charsets.toCharset(encoding);
+            }
+
+            return new RestResult(resp.getStatusLine().getStatusCode(), new String(out.toByteArray(), charset));
+        }
+        catch (ConnectException e) {
+            log.debug("Failed connect to node and execute REST command [uri=" + builder.build() + "]");
+
+            return new RestResult(404, "Failed connect to node and execute REST command.");
+        }
+    }
+
+    /**
+     * Enable test-drive SQL.
+     */
+    @Remote
+    public boolean startDemoSQL() {
+        return AgentSqlDemo.testDrive(cfg);
+    }
+
+    /**
+     * Request result.
+     */
+    public static class RestResult {
+        /** Status code. */
+        private int code;
+
+        /** Message. */
+        private String message;
+
+        /**
+         * @param code Code.
+         * @param msg Message.
+         */
+        public RestResult(int code, String msg) {
+            this.code = code;
+            message = msg;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/remote/Remote.java
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/remote/Remote.java b/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/remote/Remote.java
new file mode 100644
index 0000000..71b2bc0
--- /dev/null
+++ b/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/remote/Remote.java
@@ -0,0 +1,37 @@
+/*
+ * 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.console.agent.remote;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Use this annotation to associate methods with remote NodeJS server commands.
+ */
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Remote {
+    /**
+     * Whether or not method should be executed synchronously.
+     *
+     * @return {@code true} if method will be executed in separated thread otherwise if method will be executed in handler thread.
+     */
+    boolean async() default true;
+}


[3/6] ignite git commit: IGNITE-843 WIP

Posted by an...@apache.org.
IGNITE-843 WIP


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

Branch: refs/heads/ignite-843-rc2
Commit: 54a24746b936ae3bec3712061b54460ae989bf31
Parents: 16b51e5
Author: Andrey <an...@gridgain.com>
Authored: Fri Jan 15 16:03:43 2016 +0700
Committer: Andrey <an...@gridgain.com>
Committed: Fri Jan 15 16:03:43 2016 +0700

----------------------------------------------------------------------
 .../assembly/release-control-center-agent.xml   |   5 +-
 modules/control-center-agent/demo/db-init.sql   | 102 ++++
 modules/control-center-agent/demo/demo-db.sql   |  58 --
 modules/control-center-agent/pom.xml            |   2 +-
 .../apache/ignite/agent/AgentConfiguration.java | 238 --------
 .../org/apache/ignite/agent/AgentLauncher.java  | 165 ------
 .../org/apache/ignite/agent/AgentSocket.java    | 189 -------
 .../org/apache/ignite/agent/AgentUtils.java     | 115 ----
 .../ignite/agent/demo/AgentMetadataDemo.java    |  88 ---
 .../apache/ignite/agent/demo/AgentSqlDemo.java  | 495 -----------------
 .../org/apache/ignite/agent/demo/model/Car.java | 155 ------
 .../apache/ignite/agent/demo/model/CarKey.java  |  97 ----
 .../apache/ignite/agent/demo/model/Country.java | 126 -----
 .../ignite/agent/demo/model/CountryKey.java     |  97 ----
 .../ignite/agent/demo/model/Department.java     | 184 -------
 .../ignite/agent/demo/model/DepartmentKey.java  |  97 ----
 .../ignite/agent/demo/model/Employee.java       | 358 ------------
 .../ignite/agent/demo/model/EmployeeKey.java    |  97 ----
 .../apache/ignite/agent/demo/model/Parking.java | 126 -----
 .../ignite/agent/demo/model/ParkingKey.java     |  97 ----
 .../handlers/DatabaseMetadataExtractor.java     | 205 -------
 .../ignite/agent/handlers/RestExecutor.java     | 195 -------
 .../org/apache/ignite/agent/remote/Remote.java  |  37 --
 .../ignite/agent/remote/RemoteHandler.java      | 252 ---------
 .../ignite/agent/remote/WebSocketSender.java    |  39 --
 .../console/agent/AgentConfiguration.java       | 255 +++++++++
 .../ignite/console/agent/AgentLauncher.java     | 164 ++++++
 .../ignite/console/agent/AgentSocket.java       | 189 +++++++
 .../apache/ignite/console/agent/AgentUtils.java | 115 ++++
 .../handlers/DatabaseMetadataExtractor.java     | 205 +++++++
 .../console/agent/handlers/RestExecutor.java    | 195 +++++++
 .../ignite/console/agent/remote/Remote.java     |  37 ++
 .../console/agent/remote/RemoteHandler.java     | 252 +++++++++
 .../console/agent/remote/WebSocketSender.java   |  39 ++
 .../ignite/console/demo/AgentMetadataDemo.java  |  88 +++
 .../ignite/console/demo/AgentSqlDemo.java       | 551 +++++++++++++++++++
 .../apache/ignite/console/demo/model/Car.java   | 137 +++++
 .../ignite/console/demo/model/Country.java      | 137 +++++
 .../ignite/console/demo/model/Department.java   | 137 +++++
 .../ignite/console/demo/model/Employee.java     | 341 ++++++++++++
 .../ignite/console/demo/model/Parking.java      | 137 +++++
 .../src/main/js/agents/agent-manager.js         |  15 +-
 .../src/main/js/agents/agent-server.js          |  27 +-
 .../control-center-web/src/main/js/app/index.js |   2 +
 .../main/js/app/modules/QueryNotebooks/index.js | 111 ++++
 .../app/modules/states/configuration/index.js   |  10 +-
 .../main/js/app/modules/states/login/index.js   |   7 +-
 .../src/main/js/app/modules/states/sql/index.js |  21 +-
 .../src/main/js/controllers/common-module.js    |  13 +-
 .../src/main/js/controllers/sql-controller.js   | 121 ++--
 .../src/main/js/gulpfile.js/tasks/copy.js       |   2 +-
 .../src/main/js/routes/agent.js                 |  23 +-
 .../src/main/js/routes/notebooks.js             |   4 +-
 .../main/js/views/templates/agent-download.jade |   1 -
 54 files changed, 3337 insertions(+), 3618 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-agent/assembly/release-control-center-agent.xml
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/assembly/release-control-center-agent.xml b/modules/control-center-agent/assembly/release-control-center-agent.xml
index cebc757..90a9415 100644
--- a/modules/control-center-agent/assembly/release-control-center-agent.xml
+++ b/modules/control-center-agent/assembly/release-control-center-agent.xml
@@ -38,8 +38,9 @@
             <directory>${basedir}</directory>
             <outputDirectory>/</outputDirectory>
             <includes>
-                <include>jdbc-drivers/*.*</include>
-                <include>demo/*.*</include>
+                <include>jdbc-drivers/README*</include>
+                <include>demo/README*</include>
+                <include>demo/*.sql</include>
                 <include>README*</include>
                 <include>LICENSE*</include>
                 <include>NOTICE*</include>

http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-agent/demo/db-init.sql
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/demo/db-init.sql b/modules/control-center-agent/demo/db-init.sql
new file mode 100644
index 0000000..0688ea0
--- /dev/null
+++ b/modules/control-center-agent/demo/db-init.sql
@@ -0,0 +1,102 @@
+--
+--  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.
+--
+
+CREATE TABLE COUNTRY (
+    ID         INTEGER NOT NULL PRIMARY KEY,
+    NAME       VARCHAR(50),
+    POPULATION INTEGER NOT NULL
+);
+
+CREATE TABLE DEPARTMENT (
+    ID         INTEGER NOT NULL PRIMARY KEY,
+    COUNTRY_ID INTEGER NOT NULL,
+    NAME       VARCHAR(50) NOT NULL
+);
+
+CREATE TABLE EMPLOYEE (
+    ID            INTEGER NOT NULL PRIMARY KEY,
+    DEPARTMENT_ID INTEGER NOT NULL,
+    MANAGER_ID    INTEGER,
+    FIRST_NAME    VARCHAR(50) NOT NULL,
+    LAST_NAME     VARCHAR(50) NOT NULL,
+    EMAIL         VARCHAR(50) NOT NULL,
+    PHONE_NUMBER  VARCHAR(50),
+    HIRE_DATE     DATE        NOT NULL,
+    JOB           VARCHAR(50) NOT NULL,
+    SALARY        DOUBLE
+);
+
+CREATE INDEX EMP_SALARY ON EMPLOYEE (SALARY ASC);
+CREATE INDEX EMP_NAMES ON EMPLOYEE (FIRST_NAME ASC, LAST_NAME ASC);
+
+CREATE SCHEMA CARS;
+
+CREATE TABLE CARS.PARKING (
+    ID       INTEGER     NOT NULL PRIMARY KEY,
+    NAME     VARCHAR(50) NOT NULL,
+    CAPACITY INTEGER NOT NULL
+);
+
+CREATE TABLE CARS.CAR (
+    ID         INTEGER NOT NULL PRIMARY KEY,
+    PARKING_ID INTEGER NOT NULL,
+    NAME       VARCHAR(50) NOT NULL
+);
+
+INSERT INTO COUNTRY(ID, NAME, POPULATION) VALUES(0, 'Country #1', 10000000);
+INSERT INTO COUNTRY(ID, NAME, POPULATION) VALUES(1, 'Country #2', 20000000);
+INSERT INTO COUNTRY(ID, NAME, POPULATION) VALUES(2, 'Country #3', 30000000);
+
+INSERT INTO DEPARTMENT(ID, COUNTRY_ID, NAME) VALUES(0, 0, 'Department #1');
+INSERT INTO DEPARTMENT(ID, COUNTRY_ID, NAME) VALUES(1, 0, 'Department #2');
+INSERT INTO DEPARTMENT(ID, COUNTRY_ID, NAME) VALUES(2, 2, 'Department #3');
+INSERT INTO DEPARTMENT(ID, COUNTRY_ID, NAME) VALUES(3, 1, 'Department #4');
+INSERT INTO DEPARTMENT(ID, COUNTRY_ID, NAME) VALUES(4, 1, 'Department #5');
+INSERT INTO DEPARTMENT(ID, COUNTRY_ID, NAME) VALUES(5, 1, 'Department #6');
+
+INSERT INTO EMPLOYEE(ID, DEPARTMENT_ID, FIRST_NAME, LAST_NAME, EMAIL, PHONE_NUMBER, HIRE_DATE, JOB, SALARY) VALUES(0, 0, 'First name manager #1', 'Last name manager #1', 'Email manager #1', 'Phone number manager #1', '2014-01-01', 'Job manager #1', 1100.00);
+INSERT INTO EMPLOYEE(ID, DEPARTMENT_ID, FIRST_NAME, LAST_NAME, EMAIL, PHONE_NUMBER, HIRE_DATE, JOB, SALARY) VALUES(1, 1, 'First name manager #2', 'Last name manager #2', 'Email manager #2', 'Phone number manager #2', '2014-01-01', 'Job manager #2', 2100.00);
+INSERT INTO EMPLOYEE(ID, DEPARTMENT_ID, FIRST_NAME, LAST_NAME, EMAIL, PHONE_NUMBER, HIRE_DATE, JOB, SALARY) VALUES(2, 2, 'First name manager #3', 'Last name manager #3', 'Email manager #3', 'Phone number manager #3', '2014-01-01', 'Job manager #3', 3100.00);
+INSERT INTO EMPLOYEE(ID, DEPARTMENT_ID, FIRST_NAME, LAST_NAME, EMAIL, PHONE_NUMBER, HIRE_DATE, JOB, SALARY) VALUES(3, 3, 'First name manager #4', 'Last name manager #4', 'Email manager #4', 'Phone number manager #4', '2014-01-01', 'Job manager #4', 1500.00);
+INSERT INTO EMPLOYEE(ID, DEPARTMENT_ID, FIRST_NAME, LAST_NAME, EMAIL, PHONE_NUMBER, HIRE_DATE, JOB, SALARY) VALUES(4, 4, 'First name manager #5', 'Last name manager #5', 'Email manager #5', 'Phone number manager #5', '2014-01-01', 'Job manager #5', 1700.00);
+INSERT INTO EMPLOYEE(ID, DEPARTMENT_ID, FIRST_NAME, LAST_NAME, EMAIL, PHONE_NUMBER, HIRE_DATE, JOB, SALARY) VALUES(5, 5, 'First name manager #6', 'Last name manager #6', 'Email manager #6', 'Phone number manager #6', '2014-01-01', 'Job manager #6', 1300.00);
+
+INSERT INTO EMPLOYEE(ID, DEPARTMENT_ID, MANAGER_ID, FIRST_NAME, LAST_NAME, EMAIL, PHONE_NUMBER, HIRE_DATE, JOB, SALARY) VALUES(101, 0, 0, 'First name employee #1', 'Last name employee #1', 'Email employee #1', 'Phone number employee #1', '2014-01-01', 'Job employee #1', 600.00);
+INSERT INTO EMPLOYEE(ID, DEPARTMENT_ID, MANAGER_ID, FIRST_NAME, LAST_NAME, EMAIL, PHONE_NUMBER, HIRE_DATE, JOB, SALARY) VALUES(102, 0, 0, 'First name employee #2', 'Last name employee #2', 'Email employee #2', 'Phone number employee #2', '2014-01-01', 'Job employee #2', 1600.00);
+INSERT INTO EMPLOYEE(ID, DEPARTMENT_ID, MANAGER_ID, FIRST_NAME, LAST_NAME, EMAIL, PHONE_NUMBER, HIRE_DATE, JOB, SALARY) VALUES(103, 1, 1, 'First name employee #3', 'Last name employee #3', 'Email employee #3', 'Phone number employee #3', '2014-01-01', 'Job employee #3', 2600.00);
+INSERT INTO EMPLOYEE(ID, DEPARTMENT_ID, MANAGER_ID, FIRST_NAME, LAST_NAME, EMAIL, PHONE_NUMBER, HIRE_DATE, JOB, SALARY) VALUES(104, 2, 2, 'First name employee #4', 'Last name employee #4', 'Email employee #4', 'Phone number employee #4', '2014-01-01', 'Job employee #4', 1000.00);
+INSERT INTO EMPLOYEE(ID, DEPARTMENT_ID, MANAGER_ID, FIRST_NAME, LAST_NAME, EMAIL, PHONE_NUMBER, HIRE_DATE, JOB, SALARY) VALUES(105, 2, 2, 'First name employee #5', 'Last name employee #5', 'Email employee #5', 'Phone number employee #5', '2014-01-01', 'Job employee #5', 1200.00);
+INSERT INTO EMPLOYEE(ID, DEPARTMENT_ID, MANAGER_ID, FIRST_NAME, LAST_NAME, EMAIL, PHONE_NUMBER, HIRE_DATE, JOB, SALARY) VALUES(106, 2, 2, 'First name employee #6', 'Last name employee #6', 'Email employee #6', 'Phone number employee #6', '2014-01-01', 'Job employee #6', 800.00);
+INSERT INTO EMPLOYEE(ID, DEPARTMENT_ID, MANAGER_ID, FIRST_NAME, LAST_NAME, EMAIL, PHONE_NUMBER, HIRE_DATE, JOB, SALARY) VALUES(107, 3, 3, 'First name employee #7', 'Last name employee #7', 'Email employee #7', 'Phone number employee #7', '2014-01-01', 'Job employee #7', 1400.00);
+INSERT INTO EMPLOYEE(ID, DEPARTMENT_ID, MANAGER_ID, FIRST_NAME, LAST_NAME, EMAIL, PHONE_NUMBER, HIRE_DATE, JOB, SALARY) VALUES(108, 4, 4, 'First name employee #8', 'Last name employee #8', 'Email employee #8', 'Phone number employee #8', '2014-01-01', 'Job employee #8', 800.00);
+INSERT INTO EMPLOYEE(ID, DEPARTMENT_ID, MANAGER_ID, FIRST_NAME, LAST_NAME, EMAIL, PHONE_NUMBER, HIRE_DATE, JOB, SALARY) VALUES(109, 4, 4, 'First name employee #9', 'Last name employee #9', 'Email employee #9', 'Phone number employee #9', '2014-01-01', 'Job employee #9', 1490.00);
+INSERT INTO EMPLOYEE(ID, DEPARTMENT_ID, MANAGER_ID, FIRST_NAME, LAST_NAME, EMAIL, PHONE_NUMBER, HIRE_DATE, JOB, SALARY) VALUES(110, 4, 4, 'First name employee #10', 'Last name employee #12', 'Email employee #10', 'Phone number employee #10', '2014-01-01', 'Job employee #10', 1600.00);
+INSERT INTO EMPLOYEE(ID, DEPARTMENT_ID, MANAGER_ID, FIRST_NAME, LAST_NAME, EMAIL, PHONE_NUMBER, HIRE_DATE, JOB, SALARY) VALUES(111, 5, 5, 'First name employee #11', 'Last name employee #11', 'Email employee #11', 'Phone number employee #11', '2014-01-01', 'Job employee #11', 400.00);
+
+INSERT INTO CARS.PARKING(ID, NAME, CAPACITY) VALUES(0, 'Parking #1', 10);
+INSERT INTO CARS.PARKING(ID, NAME, CAPACITY) VALUES(1, 'Parking #2', 20);
+INSERT INTO CARS.PARKING(ID, NAME, CAPACITY) VALUES(2, 'Parking #3', 30);
+
+INSERT INTO CARS.CAR(ID, PARKING_ID, NAME) VALUES(0, 0, 'Car #1');
+INSERT INTO CARS.CAR(ID, PARKING_ID, NAME) VALUES(1, 0, 'Car #2');
+INSERT INTO CARS.CAR(ID, PARKING_ID, NAME) VALUES(2, 0, 'Car #3');
+INSERT INTO CARS.CAR(ID, PARKING_ID, NAME) VALUES(3, 1, 'Car #4');
+INSERT INTO CARS.CAR(ID, PARKING_ID, NAME) VALUES(4, 1, 'Car #5');
+INSERT INTO CARS.CAR(ID, PARKING_ID, NAME) VALUES(5, 2, 'Car #6');
+INSERT INTO CARS.CAR(ID, PARKING_ID, NAME) VALUES(6, 2, 'Car #7');
+INSERT INTO CARS.CAR(ID, PARKING_ID, NAME) VALUES(7, 2, 'Car #8');
+INSERT INTO CARS.CAR(ID, PARKING_ID, NAME) VALUES(8, 2, 'Car #9');

http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-agent/demo/demo-db.sql
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/demo/demo-db.sql b/modules/control-center-agent/demo/demo-db.sql
deleted file mode 100644
index a7deafa..0000000
--- a/modules/control-center-agent/demo/demo-db.sql
+++ /dev/null
@@ -1,58 +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.
- */
-
-CREATE TABLE COUNTRY (
-    ID           INTEGER NOT NULL PRIMARY KEY,
-    COUNTRY_NAME VARCHAR(100)
-);
-
-CREATE TABLE DEPARTMENT (
-    DEPARTMENT_ID   INTEGER     NOT NULL PRIMARY KEY,
-    DEPARTMENT_NAME VARCHAR(50) NOT NULL,
-    COUNTRY_ID      INTEGER,
-    MANAGER_ID      INTEGER
-);
-
-CREATE TABLE EMPLOYEE (
-    EMPLOYEE_ID   INTEGER     NOT NULL PRIMARY KEY,
-    FIRST_NAME    VARCHAR(20) NOT NULL,
-    LAST_NAME     VARCHAR(30) NOT NULL,
-    EMAIL         VARCHAR(25) NOT NULL,
-    PHONE_NUMBER  VARCHAR(20),
-    HIRE_DATE     DATE        NOT NULL,
-    JOB           VARCHAR(50) NOT NULL,
-    SALARY        DOUBLE,
-    MANAGER_ID    INTEGER,
-    DEPARTMENT_ID INTEGER
-);
-
-CREATE INDEX EMP_SALARY_A ON EMPLOYEE (SALARY ASC);
-CREATE INDEX EMP_SALARY_B ON EMPLOYEE (SALARY DESC);
-CREATE INDEX EMP_NAMES ON EMPLOYEE (FIRST_NAME ASC, LAST_NAME ASC);
-
-CREATE SCHEMA CARS;
-
-CREATE TABLE CARS.PARKING (
-    PARKING_ID   INTEGER     NOT NULL PRIMARY KEY,
-    PARKING_NAME VARCHAR(50) NOT NULL
-);
-
-CREATE TABLE CARS.CAR (
-    CAR_ID     INTEGER     NOT NULL PRIMARY KEY,
-    PARKING_ID INTEGER     NOT NULL,
-    CAR_NAME   VARCHAR(50) NOT NULL
-);

http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-agent/pom.xml
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/pom.xml b/modules/control-center-agent/pom.xml
index 0db5d36..b90cec0 100644
--- a/modules/control-center-agent/pom.xml
+++ b/modules/control-center-agent/pom.xml
@@ -98,7 +98,7 @@
                 <configuration>
                     <archive>
                         <manifest>
-                            <mainClass>org.apache.ignite.agent.AgentLauncher</mainClass>
+                            <mainClass>org.apache.ignite.console.agent.AgentLauncher</mainClass>
                         </manifest>
                     </archive>
                 </configuration>

http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-agent/src/main/java/org/apache/ignite/agent/AgentConfiguration.java
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/agent/AgentConfiguration.java b/modules/control-center-agent/src/main/java/org/apache/ignite/agent/AgentConfiguration.java
deleted file mode 100644
index cb08fe7..0000000
--- a/modules/control-center-agent/src/main/java/org/apache/ignite/agent/AgentConfiguration.java
+++ /dev/null
@@ -1,238 +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.agent;
-
-import com.beust.jcommander.Parameter;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.Reader;
-import java.net.URL;
-import java.util.Properties;
-
-/**
- * Agent configuration.
- */
-public class AgentConfiguration {
-    /** Default server port. */
-    public static final int DFLT_SERVER_PORT = 3001;
-
-    /** Default Ignite node HTTP port. */
-    public static final int DFLT_NODE_PORT = 8080;
-
-    /** Default path to agent property file. */
-    public static final String DFLT_CFG_PATH = "default.properties";
-
-    /** Default server URI. */
-    private static final String DFLT_SERVER_URI = "wss://localhost:3001";
-
-    /** Default Ignite node HTTP URI. */
-    private static final String DFLT_NODE_URI = "http://localhost:8080";
-
-    /** */
-    @Parameter(names = {"-t", "--token"}, description = "User's security token used to establish connection to Ignite Console.")
-    private String tok;
-
-    /** */
-    @Parameter(names = {"-s", "--server-uri"}, description = "URI for connect to Ignite Console via web-socket protocol" +
-        "           " +
-        "      Default value: " + DFLT_SERVER_URI)
-    private String srvUri;
-
-    /** */
-    @Parameter(names = {"-n", "--node-uri"}, description = "URI for connect to Ignite node REST server" +
-        "                        " +
-        "      Default value: " + DFLT_NODE_URI)
-    private String nodeUri;
-
-    /** */
-    @Parameter(names = {"-c", "--config"}, description = "Path to agent property file" +
-        "                                  " +
-        "      Default value: " + DFLT_CFG_PATH)
-    private String cfgPath;
-
-    /** */
-    @Parameter(names = {"-d", "--driver-folder"}, description = "Path to folder with JDBC drivers" +
-        "                             " +
-        "      Default value: ./jdbc-drivers")
-    private String driversFolder;
-
-    /** */
-    @Parameter(names = { "-h", "--help" }, help = true, description = "Print this help message")
-    private Boolean help;
-
-    /**
-     * @return Token.
-     */
-    public String token() {
-        return tok;
-    }
-
-    /**
-     * @param tok Token.
-     */
-    public void token(String tok) {
-        this.tok = tok;
-    }
-
-    /**
-     * @return Server URI.
-     */
-    public String serverUri() {
-        return srvUri;
-    }
-
-    /**
-     * @param srvUri URI.
-     */
-    public void serverUri(String srvUri) {
-        this.srvUri = srvUri;
-    }
-
-    /**
-     * @return Node URI.
-     */
-    public String nodeUri() {
-        return nodeUri;
-    }
-
-    /**
-     * @param nodeUri Node URI.
-     */
-    public void nodeUri(String nodeUri) {
-        this.nodeUri = nodeUri;
-    }
-
-    /**
-     * @return Configuration path.
-     */
-    public String configPath() {
-        return cfgPath == null ? DFLT_CFG_PATH : cfgPath;
-    }
-
-    /**
-     * @return Configured drivers folder.
-     */
-    public String driversFolder() {
-        return driversFolder;
-    }
-
-    /**
-     * @param driversFolder Driver folder.
-     */
-    public void driversFolder(String driversFolder) {
-        this.driversFolder = driversFolder;
-    }
-
-    /**
-     * @return {@code true} If agent options usage should be printed.
-     */
-    public Boolean help() {
-        return help != null ? help : false;
-    }
-
-    /**
-     * @param cfgUrl URL.
-     */
-    public void load(URL cfgUrl) throws IOException {
-        Properties props = new Properties();
-
-        try (Reader reader = new InputStreamReader(cfgUrl.openStream())) {
-            props.load(reader);
-        }
-
-        String val = (String)props.remove("token");
-
-        if (val != null)
-            token(val);
-
-        val = (String)props.remove("server-uri");
-
-        if (val != null)
-            serverUri(val);
-
-        val = (String)props.remove("node-uri");
-
-        if (val != null)
-            nodeUri(val);
-
-        val = (String)props.remove("driver-folder");
-
-        if (val != null)
-            driversFolder(val);
-    }
-
-    /**
-     * @param cmd Command.
-     */
-    public void merge(AgentConfiguration cmd) {
-        if (tok == null)
-            token(cmd.token());
-
-        if (srvUri == null)
-            serverUri(cmd.serverUri());
-
-        if (srvUri == null)
-            serverUri(DFLT_SERVER_URI);
-
-        if (nodeUri == null)
-            nodeUri(cmd.nodeUri());
-
-        if (nodeUri == null)
-            nodeUri(DFLT_NODE_URI);
-
-        if (driversFolder == null)
-            driversFolder(cmd.driversFolder());
-    }
-
-    /** {@inheritDoc} */
-    @Override public String toString() {
-        StringBuilder sb = new StringBuilder();
-
-        if (tok != null && tok.length() > 0) {
-            sb.append("User's security token         : ");
-
-            if (tok.length() > 4) {
-                sb.append(new String(new char[tok.length() - 4]).replace("\0", "*"));
-
-                sb.append(tok.substring(tok.length() - 4));
-            }
-            else
-                sb.append(new String(new char[tok.length()]).replace("\0", "*"));
-
-            sb.append('\n');
-        }
-
-        sb.append("URI to Ignite node REST server: ").append(nodeUri == null ? DFLT_NODE_URI : nodeUri).append('\n');
-        sb.append("URI to Ignite Console server  : ").append(srvUri == null ? DFLT_SERVER_URI : srvUri).append('\n');
-        sb.append("Path to agent property file   : ").append(configPath()).append('\n');
-
-        String drvFld = driversFolder();
-
-        if (drvFld == null) {
-            File agentHome = AgentUtils.getAgentHome();
-
-            if (agentHome != null)
-                drvFld = new File(agentHome, "jdbc-drivers").getPath();
-        }
-
-        sb.append("Path to JDBC drivers folder   : ").append(drvFld);
-
-        return sb.toString();
-    }
-}

http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-agent/src/main/java/org/apache/ignite/agent/AgentLauncher.java
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/agent/AgentLauncher.java b/modules/control-center-agent/src/main/java/org/apache/ignite/agent/AgentLauncher.java
deleted file mode 100644
index bc1cea7..0000000
--- a/modules/control-center-agent/src/main/java/org/apache/ignite/agent/AgentLauncher.java
+++ /dev/null
@@ -1,165 +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.agent;
-
-import com.beust.jcommander.JCommander;
-import java.io.File;
-import java.io.IOException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.Arrays;
-
-import com.beust.jcommander.ParameterException;
-import org.apache.ignite.agent.handlers.RestExecutor;
-import org.apache.log4j.Logger;
-import org.eclipse.jetty.util.ssl.SslContextFactory;
-import org.eclipse.jetty.websocket.client.WebSocketClient;
-
-import static org.apache.ignite.agent.AgentConfiguration.DFLT_SERVER_PORT;
-import static org.apache.ignite.agent.AgentUtils.resolvePath;
-
-/**
- * Control Center Agent launcher.
- */
-public class AgentLauncher {
-    /** */
-    private static final Logger log = Logger.getLogger(AgentLauncher.class.getName());
-
-    /** */
-    private static final int RECONNECT_INTERVAL = 3000;
-
-    /**
-     * @param args Args.
-     */
-    @SuppressWarnings("BusyWait")
-    public static void main(String[] args) throws Exception {
-        log.info("Starting Apache Ignite Web Console Agent...");
-
-        AgentConfiguration cfg = new AgentConfiguration();
-
-        JCommander jCommander = new JCommander(cfg);
-
-        String osName = System.getProperty("os.name").toLowerCase();
-
-        jCommander.setProgramName("ignite-web-agent." + (osName.contains("win") ? "bat" : "sh"));
-
-        try {
-            jCommander.parse(args);
-        }
-        catch (ParameterException pe) {
-            log.error("Failed to parse command line parameters: " + Arrays.toString(args), pe);
-
-            jCommander.usage();
-
-            return;
-        }
-
-        String prop = cfg.configPath();
-
-        AgentConfiguration propCfg = new AgentConfiguration();
-
-        try {
-            File f = resolvePath(prop);
-
-            if (f == null)
-                log.warn("Failed to find agent property file: '" + prop + "'");
-            else
-                propCfg.load(f.toURI().toURL());
-        }
-        catch (IOException ignore) {
-            if (!AgentConfiguration.DFLT_CFG_PATH.equals(prop))
-                log.warn("Failed to load agent property file: '" + prop + "'", ignore);
-        }
-
-        cfg.merge(propCfg);
-
-        if (cfg.help()) {
-            jCommander.usage();
-
-            return;
-        }
-
-        System.out.println();
-        System.out.println("Agent configuration:");
-        System.out.println(cfg);
-        System.out.println();
-
-        if (cfg.token() == null) {
-            String webHost;
-
-            try {
-                webHost = new URI(cfg.serverUri()).getHost();
-            }
-            catch (URISyntaxException e) {
-                log.error("Failed to parse Ignite Web Console uri", e);
-
-                return;
-            }
-
-            System.out.println("Security token is required to establish connection to the web console.");
-            System.out.println(String.format("It is available on the Profile page: https://%s/profile", webHost));
-
-            System.out.print("Enter security token: ");
-
-            cfg.token(System.console().readLine().trim());
-        }
-
-        RestExecutor restExecutor = new RestExecutor(cfg);
-
-        restExecutor.start();
-
-        try {
-            SslContextFactory sslCtxFactory = new SslContextFactory();
-
-            // Workaround for use self-signed certificate:
-            if (Boolean.getBoolean("trust.all"))
-                sslCtxFactory.setTrustAll(true);
-
-            WebSocketClient client = new WebSocketClient(sslCtxFactory);
-
-            client.setMaxIdleTimeout(Long.MAX_VALUE);
-
-            client.start();
-
-            try {
-                while (!Thread.interrupted()) {
-                    AgentSocket agentSock = new AgentSocket(cfg, restExecutor);
-
-                    log.info("Connecting to: " + cfg.serverUri());
-
-                    URI uri = URI.create(cfg.serverUri());
-
-                    if (uri.getPort() == -1)
-                        uri = URI.create(cfg.serverUri() + ":" + DFLT_SERVER_PORT);
-
-                    client.connect(agentSock, uri);
-
-                    agentSock.waitForClose();
-
-                    Thread.sleep(RECONNECT_INTERVAL);
-                }
-            }
-            finally {
-                client.stop();
-            }
-        }
-        finally {
-            restExecutor.stop();
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-agent/src/main/java/org/apache/ignite/agent/AgentSocket.java
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/agent/AgentSocket.java b/modules/control-center-agent/src/main/java/org/apache/ignite/agent/AgentSocket.java
deleted file mode 100644
index 271a08e..0000000
--- a/modules/control-center-agent/src/main/java/org/apache/ignite/agent/AgentSocket.java
+++ /dev/null
@@ -1,189 +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.agent;
-
-import com.google.gson.Gson;
-import com.google.gson.JsonElement;
-import com.google.gson.JsonObject;
-import com.google.gson.JsonParser;
-import java.io.IOException;
-import java.net.ConnectException;
-import java.util.concurrent.CountDownLatch;
-import javax.net.ssl.SSLHandshakeException;
-import org.apache.ignite.agent.handlers.DatabaseMetadataExtractor;
-import org.apache.ignite.agent.handlers.RestExecutor;
-import org.apache.ignite.agent.remote.Remote;
-import org.apache.ignite.agent.remote.RemoteHandler;
-import org.apache.ignite.agent.remote.WebSocketSender;
-import org.apache.log4j.Logger;
-import org.eclipse.jetty.websocket.api.Session;
-import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose;
-import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect;
-import org.eclipse.jetty.websocket.api.annotations.OnWebSocketError;
-import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage;
-import org.eclipse.jetty.websocket.api.annotations.WebSocket;
-
-/**
- * Handler for web-socket connection.
- */
-@WebSocket
-public class AgentSocket implements WebSocketSender {
-    /** */
-    public static final Gson GSON = new Gson();
-
-    /** */
-    public static final JsonParser PARSER = new JsonParser();
-
-    /** */
-    private static final Logger log = Logger.getLogger(AgentSocket.class.getName());
-
-    /** */
-    private final CountDownLatch closeLatch = new CountDownLatch(1);
-
-    /** */
-    private final AgentConfiguration cfg;
-
-    /** */
-    private final RestExecutor restExecutor;
-
-    /** */
-    private RemoteHandler remote;
-
-    /** */
-    private Session ses;
-
-    /**
-     * @param cfg Config.
-     */
-    public AgentSocket(AgentConfiguration cfg, RestExecutor restExecutor) {
-        this.cfg = cfg;
-        this.restExecutor = restExecutor;
-    }
-
-    /**
-     * @param statusCode Status code.
-     * @param reason Reason.
-     */
-    @OnWebSocketClose
-    public void onClose(int statusCode, String reason) {
-        log.warn(String.format("Connection closed: %d - %s.", statusCode, reason));
-
-        if (remote != null)
-            remote.close();
-
-        closeLatch.countDown();
-    }
-
-    /**
-     * @param ses Session.
-     */
-    @OnWebSocketConnect
-    public void onConnect(Session ses) {
-        log.info("Connection established.");
-
-        this.ses = ses;
-
-        remote = RemoteHandler.wrap(this, this, restExecutor, new DatabaseMetadataExtractor(cfg));
-
-        JsonObject authMsg = new JsonObject();
-
-        authMsg.addProperty("type", "AuthMessage");
-        authMsg.addProperty("token", cfg.token());
-
-        send(authMsg);
-    }
-
-    /**
-     * @param msg Message.
-     * @return Whether or not message was sent.
-     */
-    @Override public boolean send(JsonObject msg) {
-        return send(GSON.toJson(msg));
-    }
-
-    /**
-     * @param msg Message.
-     * @return Whether or not message was sent.
-     */
-    @Override public boolean send(String msg) {
-        try {
-            ses.getRemote().sendString(msg);
-
-            return true;
-        }
-        catch (IOException ignored) {
-            log.error("Failed to send message to Control Center.");
-
-            return false;
-        }
-    }
-
-    /**
-     * @param ses Session.
-     * @param error Error.
-     */
-    @OnWebSocketError
-    public void onError(Session ses, Throwable error) {
-        if (error instanceof ConnectException)
-            log.warn(error.getMessage());
-        else if (error instanceof SSLHandshakeException) {
-            log.error("Failed to establish SSL connection to Ignite Console. Start agent with " +
-                "\"-Dtrust.all=true\" to skip certificate validation in case of using self-signed certificate.", error);
-
-            System.exit(1);
-        }
-        else
-            log.error("Connection error.", error);
-
-        if (remote != null)
-            remote.close();
-
-        closeLatch.countDown();
-    }
-
-    /**
-     * @param msg Message.
-     */
-    @OnWebSocketMessage
-    public void onMessage(String msg) {
-        JsonElement jsonElement = PARSER.parse(msg);
-
-        remote.onMessage((JsonObject)jsonElement);
-    }
-
-    /**
-     * @param errorMsg Authentication failed message or {@code null} if authentication success.
-     */
-    @Remote
-    public void authResult(String errorMsg) {
-        if (errorMsg != null) {
-            onClose(401, "Authentication failed: " + errorMsg);
-
-            System.exit(1);
-        }
-
-        log.info("Authentication success.");
-    }
-
-    /**
-     * Await socket close.
-     */
-    public void waitForClose() throws InterruptedException {
-        closeLatch.await();
-    }
-}

http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-agent/src/main/java/org/apache/ignite/agent/AgentUtils.java
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/agent/AgentUtils.java b/modules/control-center-agent/src/main/java/org/apache/ignite/agent/AgentUtils.java
deleted file mode 100644
index acce22d..0000000
--- a/modules/control-center-agent/src/main/java/org/apache/ignite/agent/AgentUtils.java
+++ /dev/null
@@ -1,115 +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.agent;
-
-import org.apache.log4j.Logger;
-
-import java.io.File;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.security.ProtectionDomain;
-
-/**
- * Utility methods.
- */
-public class AgentUtils {
-    /** */
-    private static final Logger log = Logger.getLogger(AgentUtils.class.getName());
-
-    /**
-     * Default constructor.
-     */
-    private AgentUtils() {
-        // No-op.
-    }
-
-    /**
-     * @param path Path to normalize.
-     * @return Normalized file path.
-     */
-    public static String normalizePath(String path) {
-        return path != null ? path.replace('\\', '/') : null;
-    }
-
-    /**
-     * @return App folder.
-     */
-    public static File getAgentHome() {
-        try {
-            ProtectionDomain domain = AgentLauncher.class.getProtectionDomain();
-
-            // Should not happen, but to make sure our code is not broken.
-            if (domain == null || domain.getCodeSource() == null || domain.getCodeSource().getLocation() == null) {
-                log.warn("Failed to resolve agent jar location!");
-
-                return null;
-            }
-
-            // Resolve path to class-file.
-            URI classesUri = domain.getCodeSource().getLocation().toURI();
-
-            boolean win = System.getProperty("os.name").toLowerCase().contains("win");
-
-            // Overcome UNC path problem on Windows (http://www.tomergabel.com/JavaMishandlesUNCPathsOnWindows.aspx)
-            if (win && classesUri.getAuthority() != null)
-                classesUri = new URI(classesUri.toString().replace("file://", "file:/"));
-
-            return new File(classesUri).getParentFile();
-        }
-        catch (URISyntaxException | SecurityException ignored) {
-            log.warn("Failed to resolve agent jar location!");
-
-            return null;
-        }
-    }
-
-    /**
-     * Gets file associated with path.
-     * <p>
-     * First check if path is relative to agent home.
-     * If not, check if path is absolute.
-     * If all checks fail, then {@code null} is returned.
-     * <p>
-     *
-     * @param path Path to resolve.
-     * @return Resolved path as file, or {@code null} if path cannot be resolved.
-     */
-    public static File resolvePath(String path) {
-        assert path != null;
-
-        File home = getAgentHome();
-
-        if (home != null) {
-            File file = new File(home, normalizePath(path));
-
-            if (file.exists())
-                return file;
-        }
-
-        /*
-         * 2. Check given path as absolute.
-         */
-
-        File file = new File(path);
-
-        if (file.exists())
-            return file;
-
-        return null;
-    }
-}

http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-agent/src/main/java/org/apache/ignite/agent/demo/AgentMetadataDemo.java
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/agent/demo/AgentMetadataDemo.java b/modules/control-center-agent/src/main/java/org/apache/ignite/agent/demo/AgentMetadataDemo.java
deleted file mode 100644
index 30237cf..0000000
--- a/modules/control-center-agent/src/main/java/org/apache/ignite/agent/demo/AgentMetadataDemo.java
+++ /dev/null
@@ -1,88 +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.agent.demo;
-
-import java.io.File;
-import java.io.FileReader;
-import java.sql.Connection;
-import java.sql.DriverManager;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import org.apache.log4j.Logger;
-import org.h2.tools.RunScript;
-import org.h2.tools.Server;
-
-import static org.apache.ignite.agent.AgentUtils.resolvePath;
-
-/**
- * Demo for metadata load from database.
- *
- * H2 database will be started and several tables will be created.
- */
-public class AgentMetadataDemo {
-    /** */
-    private static final Logger log = Logger.getLogger(AgentMetadataDemo.class.getName());
-
-    /** */
-    private static final AtomicBoolean initLatch = new AtomicBoolean();
-
-    /**
-     * @param jdbcUrl Connection url.
-     * @return true if url is used for test-drive.
-     */
-    public static boolean isTestDriveUrl(String jdbcUrl) {
-        return "jdbc:h2:mem:demo-db".equals(jdbcUrl);
-    }
-
-    /**
-     * Start H2 database and populate it with several tables.
-     */
-    public static void testDrive() {
-        if (initLatch.compareAndSet(false, true)) {
-            log.info("DEMO: Prepare in-memory H2 database...");
-
-            try {
-                Connection conn = DriverManager.getConnection("jdbc:h2:mem:demo-db;DB_CLOSE_DELAY=-1", "sa", "");
-
-                File sqlScript = resolvePath("demo/demo-db.sql");
-
-                if (sqlScript == null) {
-                    log.error("DEMO: Failed to find demo database init script file: demo/demo-db.sql");
-                    log.error("DEMO: Failed to start demo for metadata");
-
-                    return;
-                }
-
-                RunScript.execute(conn, new FileReader(sqlScript));
-
-                log.info("DEMO: Sample tables created.");
-
-                conn.close();
-
-                Server.createTcpServer("-tcpDaemon").start();
-
-                log.info("DEMO: TcpServer stared.");
-
-                log.info("DEMO: JDBC URL for test drive metadata load: jdbc:h2:mem:demo-db");
-            }
-            catch (Exception e) {
-                log.error("DEMO: Failed to start test drive for metadata!", e);
-            }
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-agent/src/main/java/org/apache/ignite/agent/demo/AgentSqlDemo.java
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/agent/demo/AgentSqlDemo.java b/modules/control-center-agent/src/main/java/org/apache/ignite/agent/demo/AgentSqlDemo.java
deleted file mode 100644
index 06da854..0000000
--- a/modules/control-center-agent/src/main/java/org/apache/ignite/agent/demo/AgentSqlDemo.java
+++ /dev/null
@@ -1,495 +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.agent.demo;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.LinkedHashMap;
-import java.util.Random;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ScheduledThreadPoolExecutor;
-import java.util.concurrent.ThreadFactory;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicInteger;
-import org.apache.ignite.Ignite;
-import org.apache.ignite.IgniteCache;
-import org.apache.ignite.Ignition;
-import org.apache.ignite.agent.AgentConfiguration;
-import org.apache.ignite.agent.demo.model.Car;
-import org.apache.ignite.agent.demo.model.CarKey;
-import org.apache.ignite.agent.demo.model.Country;
-import org.apache.ignite.agent.demo.model.CountryKey;
-import org.apache.ignite.agent.demo.model.Department;
-import org.apache.ignite.agent.demo.model.DepartmentKey;
-import org.apache.ignite.agent.demo.model.Employee;
-import org.apache.ignite.agent.demo.model.EmployeeKey;
-import org.apache.ignite.agent.demo.model.Parking;
-import org.apache.ignite.agent.demo.model.ParkingKey;
-import org.apache.ignite.cache.QueryEntity;
-import org.apache.ignite.cache.QueryIndex;
-import org.apache.ignite.cache.QueryIndexType;
-import org.apache.ignite.configuration.CacheConfiguration;
-import org.apache.ignite.configuration.IgniteConfiguration;
-import org.apache.ignite.internal.IgniteEx;
-import org.apache.ignite.internal.IgniteNodeAttributes;
-import org.apache.ignite.internal.util.typedef.F;
-import org.apache.ignite.logger.NullLogger;
-import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
-import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
-import org.apache.log4j.Logger;
-
-/**
- * Demo for SQL.
- *
- * Cache will be created and populated with data to query.
- */
-public class AgentSqlDemo {
-    /** */
-    private static final Logger log = Logger.getLogger(AgentMetadataDemo.class.getName());
-
-    /** */
-    private static final AtomicBoolean initLatch = new AtomicBoolean();
-
-    /** */
-    private static final String EMPLOYEE_CACHE_NAME = "demo-employee";
-
-    /** */
-    private static final String CAR_CACHE_NAME = "demo-car";
-
-    /** */
-    private static final Random rnd = new Random();
-
-    /** Countries count. */
-    private static final int CNTR_CNT = 10;
-
-    /** Departments count */
-    private static final int DEP_CNT = 100;
-
-    /** Employees count. */
-    private static final int EMPL_CNT = 1000;
-
-    /** Countries count. */
-    private static final int CAR_CNT = 100;
-
-    /** Departments count */
-    private static final int PARK_CNT = 10;
-
-    /** Counter for threads in pool. */
-    private static final AtomicInteger THREAD_CNT = new AtomicInteger(0);
-
-    /**
-     * Configure cacheEmployee.
-     *
-     * @param name Cache name.
-     */
-    private static <K, V> CacheConfiguration<K, V> cacheEmployee(String name) {
-        CacheConfiguration<K, V> ccfg = new CacheConfiguration<>(name);
-
-        // Configure cacheEmployee types.
-        Collection<QueryEntity> queryEntities = new ArrayList<>();
-
-        // COUNTRY.
-        QueryEntity type = new QueryEntity();
-
-        queryEntities.add(type);
-
-        type.setKeyType(CountryKey.class.getName());
-        type.setValueType(Country.class.getName());
-
-        // Query fields for COUNTRY.
-        LinkedHashMap<String, String> qryFlds = new LinkedHashMap<>();
-
-        qryFlds.put("id", "java.lang.Integer");
-        qryFlds.put("countryName", "java.lang.String");
-
-        type.setFields(qryFlds);
-
-        // Indexes for COUNTRY.
-        type.setIndexes(Collections.singletonList(new QueryIndex("id")));
-
-        ccfg.setQueryEntities(queryEntities);
-
-        // DEPARTMENT.
-        type = new QueryEntity();
-
-        queryEntities.add(type);
-
-        type.setKeyType(DepartmentKey.class.getName());
-        type.setValueType(Department.class.getName());
-
-        // Query fields for DEPARTMENT.
-        qryFlds = new LinkedHashMap<>();
-
-        qryFlds.put("departmentId", "java.lang.Integer");
-        qryFlds.put("departmentName", "java.lang.String");
-        qryFlds.put("countryId", "java.lang.Integer");
-        qryFlds.put("managerId", "java.lang.Integer");
-
-        type.setFields(qryFlds);
-
-        // Indexes for DEPARTMENT.
-        type.setIndexes(Collections.singletonList(new QueryIndex("departmentId")));
-
-        ccfg.setQueryEntities(queryEntities);
-
-        // EMPLOYEE.
-        type = new QueryEntity();
-
-        queryEntities.add(type);
-
-        type.setKeyType(EmployeeKey.class.getName());
-        type.setValueType(Employee.class.getName());
-
-        // Query fields for EMPLOYEE.
-        qryFlds = new LinkedHashMap<>();
-
-        qryFlds.put("employeeId", "java.lang.Integer");
-        qryFlds.put("firstName", "java.lang.String");
-        qryFlds.put("lastName", "java.lang.String");
-        qryFlds.put("email", "java.lang.String");
-        qryFlds.put("phoneNumber", "java.lang.String");
-        qryFlds.put("hireDate", "java.sql.Date");
-        qryFlds.put("job", "java.lang.String");
-        qryFlds.put("salary", "java.lang.Double");
-        qryFlds.put("managerId", "java.lang.Integer");
-        qryFlds.put("departmentId", "java.lang.Integer");
-
-        type.setFields(qryFlds);
-
-        // Indexes for EMPLOYEE.
-        Collection<QueryIndex> indexes = new ArrayList<>();
-
-        indexes.add(new QueryIndex("employeeId"));
-        indexes.add(new QueryIndex("salary", false));
-
-        // Group indexes for EMPLOYEE.
-        LinkedHashMap<String, Boolean> grpItems = new LinkedHashMap<>();
-
-        grpItems.put("firstName", Boolean.FALSE);
-        grpItems.put("lastName", Boolean.TRUE);
-
-        QueryIndex grpIdx = new QueryIndex(grpItems, QueryIndexType.SORTED);
-
-        grpIdx.setName("EMP_NAMES");
-
-        indexes.add(grpIdx);
-
-        type.setIndexes(indexes);
-
-        ccfg.setQueryEntities(queryEntities);
-
-        return ccfg;
-    }
-
-    /**
-     * Configure cacheEmployee.
-     *
-     * @param name Cache name.
-     */
-    private static <K, V> CacheConfiguration<K, V> cacheCar(String name) {
-        CacheConfiguration<K, V> ccfg = new CacheConfiguration<>(name);
-
-        // Configure cacheEmployee types.
-        Collection<QueryEntity> queryEntities = new ArrayList<>();
-
-        // CAR.
-        QueryEntity type = new QueryEntity();
-
-        queryEntities.add(type);
-
-        type.setKeyType(CarKey.class.getName());
-        type.setValueType(Car.class.getName());
-
-        // Query fields for CAR.
-        LinkedHashMap<String, String> qryFlds = new LinkedHashMap<>();
-
-        qryFlds.put("carId", "java.lang.Integer");
-        qryFlds.put("parkingId", "java.lang.Integer");
-        qryFlds.put("carName", "java.lang.String");
-
-        type.setFields(qryFlds);
-
-        // Indexes for CAR.
-        type.setIndexes(Collections.singletonList(new QueryIndex("carId")));
-
-        ccfg.setQueryEntities(queryEntities);
-
-        // PARKING.
-        type = new QueryEntity();
-
-        queryEntities.add(type);
-
-        type.setKeyType(ParkingKey.class.getName());
-        type.setValueType(Parking.class.getName());
-
-        // Query fields for PARKING.
-        qryFlds = new LinkedHashMap<>();
-
-        qryFlds.put("parkingId", "java.lang.Integer");
-        qryFlds.put("parkingName", "java.lang.String");
-
-        type.setFields(qryFlds);
-
-        // Indexes for PARKING.
-        type.setIndexes(Collections.singletonList(new QueryIndex("parkingId")));
-
-        ccfg.setQueryEntities(queryEntities);
-
-        return ccfg;
-    }
-
-    /**
-     * @param val Value to round.
-     * @param places Numbers after point.
-     * @return Rounded value;
-     */
-    private static double round(double val, int places) {
-        if (places < 0)
-            throw new IllegalArgumentException();
-
-        long factor = (long) Math.pow(10, places);
-
-        val *= factor;
-
-        long tmp = Math.round(val);
-
-        return (double) tmp / factor;
-    }
-
-    /**
-     * @param ignite Ignite.
-     * @param name Cache name.
-     * @param range Time range in milliseconds.
-     */
-    private static void populateCacheEmployee(Ignite ignite, String name, long range) {
-        log.trace("DEMO: Start population cache: '" + name + "' with data...");
-
-        IgniteCache<CountryKey, Country> cacheCountry = ignite.cache(name);
-
-        for (int i = 0; i < CNTR_CNT; i++)
-            cacheCountry.put(new CountryKey(i), new Country(i, "State " + (i + 1)));
-
-        IgniteCache<DepartmentKey, Department> cacheDepartment = ignite.cache(name);
-
-        for (int i = 0; i < DEP_CNT; i++) {
-            Integer mgrId = (i == 0 || rnd.nextBoolean()) ? null : rnd.nextInt(i);
-
-            cacheDepartment.put(new DepartmentKey(i),
-                new Department(i, "Department " + (i + 1), rnd.nextInt(CNTR_CNT), mgrId));
-        }
-
-        IgniteCache<EmployeeKey, Employee> cacheEmployee = ignite.cache(name);
-
-        for (int i = 0; i < EMPL_CNT; i++) {
-            Integer mgrId = (i == 0 || rnd.nextBoolean()) ? null : rnd.nextInt(i);
-
-            double r = rnd.nextDouble();
-
-            cacheEmployee.put(new EmployeeKey(i),
-                new Employee(i, "first name " + (i + 1), "last name " + (i + 1), "email " + (i + 1),
-                    "phone number " + (i + 1), new java.sql.Date((long)(r * range)), "job " + (i + 1),
-                    round(r * 5000, 2) , mgrId, rnd.nextInt(DEP_CNT)));
-        }
-
-        log.trace("DEMO: Finished population cache: '" + name + "' with data.");
-    }
-
-    /**
-     * @param ignite Ignite.
-     * @param name Cache name.
-     */
-    private static void populateCacheCar(Ignite ignite, String name) {
-        log.trace("DEMO: Start population cache: '" + name + "' with data...");
-
-        IgniteCache<ParkingKey, Parking> cacheParking = ignite.cache(name);
-
-        for (int i = 0; i < PARK_CNT; i++)
-            cacheParking.put(new ParkingKey(i), new Parking(i, "Parking " + (i + 1)));
-
-        IgniteCache<CarKey, Car> cacheCar = ignite.cache(name);
-
-        for (int i = 0; i < CAR_CNT; i++)
-            cacheCar.put(new CarKey(i), new Car(i, rnd.nextInt(PARK_CNT), "Car " + (i + 1)));
-
-
-        log.trace("DEMO: Finished population cache: '" + name + "' with data.");
-    }
-
-    /**
-     * Creates a thread pool that can schedule commands to run after a given delay, or to execute periodically.
-     *
-     * @param corePoolSize Number of threads to keep in the pool, even if they are idle.
-     * @param threadName Part of thread name that would be used by thread factory.
-     * @return Newly created scheduled thread pool.
-     */
-    private static ScheduledExecutorService newScheduledThreadPool(int corePoolSize, final String threadName) {
-        ScheduledExecutorService srvc = Executors.newScheduledThreadPool(corePoolSize, new ThreadFactory() {
-            @Override public Thread newThread(Runnable r) {
-                Thread thread = new Thread(r, String.format("%s-%d", threadName, THREAD_CNT.getAndIncrement()));
-
-                thread.setDaemon(true);
-
-                return thread;
-            }
-        });
-
-        ScheduledThreadPoolExecutor executor = (ScheduledThreadPoolExecutor) srvc;
-
-        // Setting up shutdown policy.
-        executor.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
-        executor.setContinueExistingPeriodicTasksAfterShutdownPolicy(false);
-
-        return srvc;
-    }
-
-    /**
-     * Starts read and write from cache in background.
-     *
-     * @param ignite Ignite.
-     * @param n - maximum count read/write key
-     */
-    private static void startLoad(final Ignite ignite, final int n) {
-        final long diff = new java.util.Date().getTime();
-
-        populateCacheEmployee(ignite, EMPLOYEE_CACHE_NAME, diff);
-
-        populateCacheCar(ignite, CAR_CACHE_NAME);
-
-        ScheduledExecutorService cachePool = newScheduledThreadPool(2, "demo-sql-load-cache-tasks");
-
-        cachePool.scheduleWithFixedDelay(new Runnable() {
-            @Override public void run() {
-                try {
-                    IgniteCache<EmployeeKey, Employee> cache = ignite.cache(EMPLOYEE_CACHE_NAME);
-
-                    if (cache != null)
-                        for (int i = 0; i < n; i++) {
-                            Integer employeeId = rnd.nextInt(EMPL_CNT);
-
-                            Integer mgrId = (i == 0 || rnd.nextBoolean()) ? null : rnd.nextInt(employeeId);
-
-                            double r = rnd.nextDouble();
-
-                            cache.put(new EmployeeKey(employeeId),
-                                new Employee(employeeId, "first name " + (i + 1), "last name " + (i + 1),
-                                    "email " + (i + 1), "phone number " + (i + 1),
-                                    new java.sql.Date((long)(r * diff)), "job " + (i + 1),
-                                    round(r * 5000, 2), mgrId, rnd.nextInt(DEP_CNT)));
-
-                            if (rnd.nextBoolean())
-                                cache.remove(new EmployeeKey(rnd.nextInt(EMPL_CNT)));
-                        }
-                }
-                catch (IllegalStateException ignored) {
-                    // No-op.
-                }
-                catch (Throwable e) {
-                    if (!e.getMessage().contains("cache is stopped"))
-                        ignite.log().error("Cache write task execution error", e);
-                }
-            }
-        }, 10, 3, TimeUnit.SECONDS);
-
-        cachePool.scheduleWithFixedDelay(new Runnable() {
-            @Override public void run() {
-                try {
-                    IgniteCache<CarKey, Car> cache = ignite.cache(CAR_CACHE_NAME);
-
-                    if (cache != null)
-                        for (int i = 0; i < n; i++) {
-                            Integer carId = rnd.nextInt(CAR_CNT);
-
-                            cache.put(new CarKey(carId), new Car(carId, rnd.nextInt(PARK_CNT), "Car " + (i + 1)));
-
-                            if (rnd.nextBoolean())
-                                cache.remove(new CarKey(rnd.nextInt(CAR_CNT)));
-                        }
-                }
-                catch (IllegalStateException ignored) {
-                }
-                catch (Throwable e) {
-                    if (!e.getMessage().contains("cache is stopped"))
-                        ignite.log().error("Cache write task execution error", e);
-                }
-            }
-        }, 10, 3, TimeUnit.SECONDS);
-    }
-
-    /**
-     * Start ignite node with cacheEmployee and populate it with data.
-     */
-    public static boolean testDrive(AgentConfiguration acfg) {
-        if (initLatch.compareAndSet(false, true)) {
-            log.info("DEMO: Starting embedded node for sql test-drive...");
-
-            try {
-                IgniteConfiguration cfg = new IgniteConfiguration();
-
-                cfg.setLocalHost("127.0.0.1");
-
-                cfg.setMetricsLogFrequency(0);
-
-                cfg.setGridLogger(new NullLogger());
-
-                // Configure discovery SPI.
-                TcpDiscoverySpi discoSpi = new TcpDiscoverySpi();
-
-                TcpDiscoveryVmIpFinder ipFinder = new TcpDiscoveryVmIpFinder();
-
-                ipFinder.setAddresses(Collections.singleton("127.0.0.1:47500..47501"));
-
-                discoSpi.setIpFinder(ipFinder);
-
-                cfg.setDiscoverySpi(discoSpi);
-
-                cfg.setCacheConfiguration(cacheEmployee(EMPLOYEE_CACHE_NAME), cacheCar(CAR_CACHE_NAME));
-
-                log.trace("DEMO: Start embedded node with indexed enabled caches...");
-
-                IgniteEx ignite = (IgniteEx)Ignition.start(cfg);
-
-                String host = ((Collection<String>)
-                    ignite.localNode().attribute(IgniteNodeAttributes.ATTR_REST_JETTY_ADDRS)).iterator().next();
-
-                Integer port = ignite.localNode().attribute(IgniteNodeAttributes.ATTR_REST_JETTY_PORT);
-
-                if (F.isEmpty(host) || port == null) {
-                    log.error("DEMO: Failed to start embedded node with rest!");
-
-                    return false;
-                }
-
-                acfg.nodeUri(String.format("http://%s:%d", "0.0.0.0".equals(host) ? "127.0.0.1" : host, port));
-
-                log.info("DEMO: Embedded node for sql test-drive successfully started");
-
-                startLoad(ignite, 20);
-            }
-            catch (Exception e) {
-                log.error("DEMO: Failed to start embedded node for sql test-drive!", e);
-
-                return false;
-            }
-        }
-
-        return true;
-    }
-}

http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-agent/src/main/java/org/apache/ignite/agent/demo/model/Car.java
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/agent/demo/model/Car.java b/modules/control-center-agent/src/main/java/org/apache/ignite/agent/demo/model/Car.java
deleted file mode 100644
index c7f9dc5..0000000
--- a/modules/control-center-agent/src/main/java/org/apache/ignite/agent/demo/model/Car.java
+++ /dev/null
@@ -1,155 +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.agent.demo.model;
-
-import java.io.Serializable;
-
-/**
- * Car definition.
- *
- * Code generated by Apache Ignite Schema Import utility: 08/24/2015.
- */
-public class Car implements Serializable {
-    /** */
-    private static final long serialVersionUID = 0L;
-
-    /** Value for carId. */
-    private int carId;
-
-    /** Value for parkingId. */
-    private int parkingId;
-
-    /** Value for carName. */
-    private String carName;
-
-    /**
-     * Empty constructor.
-     */
-    public Car() {
-        // No-op.
-    }
-
-    /**
-     * Full constructor.
-     */
-    public Car(
-        int carId,
-        int parkingId,
-        String carName
-    ) {
-        this.carId = carId;
-        this.parkingId = parkingId;
-        this.carName = carName;
-    }
-
-    /**
-     * Gets carId.
-     *
-     * @return Value for carId.
-     */
-    public int getCarId() {
-        return carId;
-    }
-
-    /**
-     * Sets carId.
-     *
-     * @param carId New value for carId.
-     */
-    public void setCarId(int carId) {
-        this.carId = carId;
-    }
-
-    /**
-     * Gets parkingId.
-     *
-     * @return Value for parkingId.
-     */
-    public int getParkingId() {
-        return parkingId;
-    }
-
-    /**
-     * Sets parkingId.
-     *
-     * @param parkingId New value for parkingId.
-     */
-    public void setParkingId(int parkingId) {
-        this.parkingId = parkingId;
-    }
-
-    /**
-     * Gets carName.
-     *
-     * @return Value for carName.
-     */
-    public String getCarName() {
-        return carName;
-    }
-
-    /**
-     * Sets carName.
-     *
-     * @param carName New value for carName.
-     */
-    public void setCarName(String carName) {
-        this.carName = carName;
-    }
-
-    /** {@inheritDoc} */
-    @Override public boolean equals(Object o) {
-        if (this == o)
-            return true;
-
-        if (!(o instanceof Car))
-            return false;
-
-        Car that = (Car)o;
-
-        if (carId != that.carId)
-            return false;
-
-        if (parkingId != that.parkingId)
-            return false;
-
-        if (carName != null ? !carName.equals(that.carName) : that.carName != null)
-            return false;
-
-        return true;
-    }
-
-    /** {@inheritDoc} */
-    @Override public int hashCode() {
-        int res = carId;
-
-        res = 31 * res + parkingId;
-
-        res = 31 * res + (carName != null ? carName.hashCode() : 0);
-
-        return res;
-    }
-
-    /** {@inheritDoc} */
-    @Override public String toString() {
-        return "Car [carId=" + carId +
-            ", parkingId=" + parkingId +
-            ", carName=" + carName +
-            "]";
-    }
-}
-

http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-agent/src/main/java/org/apache/ignite/agent/demo/model/CarKey.java
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/agent/demo/model/CarKey.java b/modules/control-center-agent/src/main/java/org/apache/ignite/agent/demo/model/CarKey.java
deleted file mode 100644
index 70a7a8e..0000000
--- a/modules/control-center-agent/src/main/java/org/apache/ignite/agent/demo/model/CarKey.java
+++ /dev/null
@@ -1,97 +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.agent.demo.model;
-
-import java.io.Serializable;
-
-/**
- * CarKey definition.
- *
- * Code generated by Apache Ignite Schema Import utility: 08/24/2015.
- */
-public class CarKey implements Serializable {
-    /** */
-    private static final long serialVersionUID = 0L;
-
-    /** Value for carId. */
-    private int carId;
-
-    /**
-     * Empty constructor.
-     */
-    public CarKey() {
-        // No-op.
-    }
-
-    /**
-     * Full constructor.
-     */
-    public CarKey(
-        int carId
-    ) {
-        this.carId = carId;
-    }
-
-    /**
-     * Gets carId.
-     *
-     * @return Value for carId.
-     */
-    public int getCarId() {
-        return carId;
-    }
-
-    /**
-     * Sets carId.
-     *
-     * @param carId New value for carId.
-     */
-    public void setCarId(int carId) {
-        this.carId = carId;
-    }
-
-    /** {@inheritDoc} */
-    @Override public boolean equals(Object o) {
-        if (this == o)
-            return true;
-
-        if (!(o instanceof CarKey))
-            return false;
-
-        CarKey that = (CarKey)o;
-
-        if (carId != that.carId)
-            return false;
-
-        return true;
-    }
-
-    /** {@inheritDoc} */
-    @Override public int hashCode() {
-        int res = carId;
-
-        return res;
-    }
-
-    /** {@inheritDoc} */
-    @Override public String toString() {
-        return "CarKey [carId=" + carId +
-            "]";
-    }
-}
-

http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-agent/src/main/java/org/apache/ignite/agent/demo/model/Country.java
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/agent/demo/model/Country.java b/modules/control-center-agent/src/main/java/org/apache/ignite/agent/demo/model/Country.java
deleted file mode 100644
index 2dbb23b..0000000
--- a/modules/control-center-agent/src/main/java/org/apache/ignite/agent/demo/model/Country.java
+++ /dev/null
@@ -1,126 +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.agent.demo.model;
-
-import java.io.Serializable;
-
-/**
- * Country definition.
- *
- * Code generated by Apache Ignite Schema Import utility: 08/24/2015.
- */
-public class Country implements Serializable {
-    /** */
-    private static final long serialVersionUID = 0L;
-
-    /** Value for id. */
-    private int id;
-
-    /** Value for countryName. */
-    private String countryName;
-
-    /**
-     * Empty constructor.
-     */
-    public Country() {
-        // No-op.
-    }
-
-    /**
-     * Full constructor.
-     */
-    public Country(
-        int id,
-        String countryName
-    ) {
-        this.id = id;
-        this.countryName = countryName;
-    }
-
-    /**
-     * Gets id.
-     *
-     * @return Value for id.
-     */
-    public int getId() {
-        return id;
-    }
-
-    /**
-     * Sets id.
-     *
-     * @param id New value for id.
-     */
-    public void setId(int id) {
-        this.id = id;
-    }
-
-    /**
-     * Gets countryName.
-     *
-     * @return Value for countryName.
-     */
-    public String getCountryName() {
-        return countryName;
-    }
-
-    /**
-     * Sets countryName.
-     *
-     * @param countryName New value for countryName.
-     */
-    public void setCountryName(String countryName) {
-        this.countryName = countryName;
-    }
-
-    /** {@inheritDoc} */
-    @Override public boolean equals(Object o) {
-        if (this == o)
-            return true;
-
-        if (!(o instanceof Country))
-            return false;
-
-        Country that = (Country)o;
-
-        if (id != that.id)
-            return false;
-
-        if (countryName != null ? !countryName.equals(that.countryName) : that.countryName != null)
-            return false;
-
-        return true;
-    }
-
-    /** {@inheritDoc} */
-    @Override public int hashCode() {
-        int res = id;
-
-        res = 31 * res + (countryName != null ? countryName.hashCode() : 0);
-
-        return res;
-    }
-
-    /** {@inheritDoc} */
-    @Override public String toString() {
-        return "Country [id=" + id +
-            ", countryName=" + countryName +
-            "]";
-    }
-}
-

http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-agent/src/main/java/org/apache/ignite/agent/demo/model/CountryKey.java
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/agent/demo/model/CountryKey.java b/modules/control-center-agent/src/main/java/org/apache/ignite/agent/demo/model/CountryKey.java
deleted file mode 100644
index c8a998f..0000000
--- a/modules/control-center-agent/src/main/java/org/apache/ignite/agent/demo/model/CountryKey.java
+++ /dev/null
@@ -1,97 +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.agent.demo.model;
-
-import java.io.Serializable;
-
-/**
- * CountryKey definition.
- *
- * Code generated by Apache Ignite Schema Import utility: 08/24/2015.
- */
-public class CountryKey implements Serializable {
-    /** */
-    private static final long serialVersionUID = 0L;
-
-    /** Value for id. */
-    private int id;
-
-    /**
-     * Empty constructor.
-     */
-    public CountryKey() {
-        // No-op.
-    }
-
-    /**
-     * Full constructor.
-     */
-    public CountryKey(
-        int id
-    ) {
-        this.id = id;
-    }
-
-    /**
-     * Gets id.
-     *
-     * @return Value for id.
-     */
-    public int getId() {
-        return id;
-    }
-
-    /**
-     * Sets id.
-     *
-     * @param id New value for id.
-     */
-    public void setId(int id) {
-        this.id = id;
-    }
-
-    /** {@inheritDoc} */
-    @Override public boolean equals(Object o) {
-        if (this == o)
-            return true;
-
-        if (!(o instanceof CountryKey))
-            return false;
-
-        CountryKey that = (CountryKey)o;
-
-        if (id != that.id)
-            return false;
-
-        return true;
-    }
-
-    /** {@inheritDoc} */
-    @Override public int hashCode() {
-        int res = id;
-
-        return res;
-    }
-
-    /** {@inheritDoc} */
-    @Override public String toString() {
-        return "CountryKey [id=" + id +
-            "]";
-    }
-}
-

http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-agent/src/main/java/org/apache/ignite/agent/demo/model/Department.java
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/agent/demo/model/Department.java b/modules/control-center-agent/src/main/java/org/apache/ignite/agent/demo/model/Department.java
deleted file mode 100644
index 5e48b42..0000000
--- a/modules/control-center-agent/src/main/java/org/apache/ignite/agent/demo/model/Department.java
+++ /dev/null
@@ -1,184 +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.agent.demo.model;
-
-import java.io.Serializable;
-
-/**
- * Department definition.
- *
- * Code generated by Apache Ignite Schema Import utility: 08/24/2015.
- */
-public class Department implements Serializable {
-    /** */
-    private static final long serialVersionUID = 0L;
-
-    /** Value for departmentId. */
-    private int departmentId;
-
-    /** Value for departmentName. */
-    private String departmentName;
-
-    /** Value for countryId. */
-    private Integer countryId;
-
-    /** Value for managerId. */
-    private Integer managerId;
-
-    /**
-     * Empty constructor.
-     */
-    public Department() {
-        // No-op.
-    }
-
-    /**
-     * Full constructor.
-     */
-    public Department(
-        int departmentId,
-        String departmentName,
-        Integer countryId,
-        Integer managerId
-    ) {
-        this.departmentId = departmentId;
-        this.departmentName = departmentName;
-        this.countryId = countryId;
-        this.managerId = managerId;
-    }
-
-    /**
-     * Gets departmentId.
-     *
-     * @return Value for departmentId.
-     */
-    public int getDepartmentId() {
-        return departmentId;
-    }
-
-    /**
-     * Sets departmentId.
-     *
-     * @param departmentId New value for departmentId.
-     */
-    public void setDepartmentId(int departmentId) {
-        this.departmentId = departmentId;
-    }
-
-    /**
-     * Gets departmentName.
-     *
-     * @return Value for departmentName.
-     */
-    public String getDepartmentName() {
-        return departmentName;
-    }
-
-    /**
-     * Sets departmentName.
-     *
-     * @param departmentName New value for departmentName.
-     */
-    public void setDepartmentName(String departmentName) {
-        this.departmentName = departmentName;
-    }
-
-    /**
-     * Gets countryId.
-     *
-     * @return Value for countryId.
-     */
-    public Integer getCountryId() {
-        return countryId;
-    }
-
-    /**
-     * Sets countryId.
-     *
-     * @param countryId New value for countryId.
-     */
-    public void setCountryId(Integer countryId) {
-        this.countryId = countryId;
-    }
-
-    /**
-     * Gets managerId.
-     *
-     * @return Value for managerId.
-     */
-    public Integer getManagerId() {
-        return managerId;
-    }
-
-    /**
-     * Sets managerId.
-     *
-     * @param managerId New value for managerId.
-     */
-    public void setManagerId(Integer managerId) {
-        this.managerId = managerId;
-    }
-
-    /** {@inheritDoc} */
-    @Override public boolean equals(Object o) {
-        if (this == o)
-            return true;
-
-        if (!(o instanceof Department))
-            return false;
-
-        Department that = (Department)o;
-
-        if (departmentId != that.departmentId)
-            return false;
-
-        if (departmentName != null ? !departmentName.equals(that.departmentName) : that.departmentName != null)
-            return false;
-
-        if (countryId != null ? !countryId.equals(that.countryId) : that.countryId != null)
-            return false;
-
-        if (managerId != null ? !managerId.equals(that.managerId) : that.managerId != null)
-            return false;
-
-        return true;
-    }
-
-    /** {@inheritDoc} */
-    @Override public int hashCode() {
-        int res = departmentId;
-
-        res = 31 * res + (departmentName != null ? departmentName.hashCode() : 0);
-
-        res = 31 * res + (countryId != null ? countryId.hashCode() : 0);
-
-        res = 31 * res + (managerId != null ? managerId.hashCode() : 0);
-
-        return res;
-    }
-
-    /** {@inheritDoc} */
-    @Override public String toString() {
-        return "Department [departmentId=" + departmentId +
-            ", departmentName=" + departmentName +
-            ", countryId=" + countryId +
-            ", managerId=" + managerId +
-            "]";
-    }
-}
-

http://git-wip-us.apache.org/repos/asf/ignite/blob/54a24746/modules/control-center-agent/src/main/java/org/apache/ignite/agent/demo/model/DepartmentKey.java
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/agent/demo/model/DepartmentKey.java b/modules/control-center-agent/src/main/java/org/apache/ignite/agent/demo/model/DepartmentKey.java
deleted file mode 100644
index a8dc1b8..0000000
--- a/modules/control-center-agent/src/main/java/org/apache/ignite/agent/demo/model/DepartmentKey.java
+++ /dev/null
@@ -1,97 +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.agent.demo.model;
-
-import java.io.Serializable;
-
-/**
- * DepartmentKey definition.
- *
- * Code generated by Apache Ignite Schema Import utility: 08/24/2015.
- */
-public class DepartmentKey implements Serializable {
-    /** */
-    private static final long serialVersionUID = 0L;
-
-    /** Value for departmentId. */
-    private int departmentId;
-
-    /**
-     * Empty constructor.
-     */
-    public DepartmentKey() {
-        // No-op.
-    }
-
-    /**
-     * Full constructor.
-     */
-    public DepartmentKey(
-        int departmentId
-    ) {
-        this.departmentId = departmentId;
-    }
-
-    /**
-     * Gets departmentId.
-     *
-     * @return Value for departmentId.
-     */
-    public int getDepartmentId() {
-        return departmentId;
-    }
-
-    /**
-     * Sets departmentId.
-     *
-     * @param departmentId New value for departmentId.
-     */
-    public void setDepartmentId(int departmentId) {
-        this.departmentId = departmentId;
-    }
-
-    /** {@inheritDoc} */
-    @Override public boolean equals(Object o) {
-        if (this == o)
-            return true;
-
-        if (!(o instanceof DepartmentKey))
-            return false;
-
-        DepartmentKey that = (DepartmentKey)o;
-
-        if (departmentId != that.departmentId)
-            return false;
-
-        return true;
-    }
-
-    /** {@inheritDoc} */
-    @Override public int hashCode() {
-        int res = departmentId;
-
-        return res;
-    }
-
-    /** {@inheritDoc} */
-    @Override public String toString() {
-        return "DepartmentKey [departmentId=" + departmentId +
-            "]";
-    }
-}
-


[4/6] ignite git commit: Merge remote-tracking branch 'origin/ignite-843-rc2' into ignite-843-rc2

Posted by an...@apache.org.
Merge remote-tracking branch 'origin/ignite-843-rc2' into ignite-843-rc2


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

Branch: refs/heads/ignite-843-rc2
Commit: 975dec8587d6ed27b040c01f6c43d40bbd30ef19
Parents: 54a2474 6945cfc
Author: Andrey <an...@gridgain.com>
Authored: Fri Jan 15 16:56:11 2016 +0700
Committer: Andrey <an...@gridgain.com>
Committed: Fri Jan 15 16:56:11 2016 +0700

----------------------------------------------------------------------
 .../main/js/controllers/metadata-controller.js  | 66 +++++++++-----------
 .../main/js/controllers/models/metadata.json    | 29 +++------
 modules/control-center-web/src/main/js/db.js    |  2 +-
 .../js/helpers/generator/generator-common.js    |  4 +-
 .../main/js/helpers/generator/generator-java.js | 41 ++++++------
 .../main/js/helpers/generator/generator-xml.js  | 27 ++++----
 6 files changed, 75 insertions(+), 94 deletions(-)
----------------------------------------------------------------------



[6/6] ignite git commit: IGNITE-843 WIP

Posted by an...@apache.org.
IGNITE-843 WIP


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

Branch: refs/heads/ignite-843-rc2
Commit: d603a53a887b892b24702c5e3c0433553c755a72
Parents: 7812853
Author: Andrey <an...@gridgain.com>
Authored: Fri Jan 15 18:03:50 2016 +0700
Committer: Andrey <an...@gridgain.com>
Committed: Fri Jan 15 18:03:50 2016 +0700

----------------------------------------------------------------------
 .../console/agent/handlers/RestExecutor.java    | 11 ++---
 .../ignite/console/demo/AgentSqlDemo.java       | 12 ++---
 .../main/js/app/modules/QueryNotebooks/index.js | 46 +++++---------------
 .../src/main/js/controllers/common-module.js    |  1 +
 .../src/main/js/controllers/sql-controller.js   | 14 ++----
 .../src/main/js/routes/agent.js                 | 17 --------
 6 files changed, 26 insertions(+), 75 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/d603a53a/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/handlers/RestExecutor.java
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/handlers/RestExecutor.java b/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/handlers/RestExecutor.java
index ee6742a..14252a1 100644
--- a/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/handlers/RestExecutor.java
+++ b/modules/control-center-agent/src/main/java/org/apache/ignite/console/agent/handlers/RestExecutor.java
@@ -91,6 +91,9 @@ public class RestExecutor {
         String mtd, Map<String, String> headers, String body) throws IOException, URISyntaxException {
         log.debug("Start execute REST command [method=" + mtd + ", uri=/" + uri + ", parameters=" + params + "]");
 
+        if (demo)
+            AgentSqlDemo.testDrive(cfg);
+
         URIBuilder builder = new URIBuilder(demo ? cfg.demoNodeUri() : cfg.nodeUri());
 
         if (builder.getPort() == -1)
@@ -166,14 +169,6 @@ public class RestExecutor {
     }
 
     /**
-     * Enable test-drive SQL.
-     */
-    @Remote
-    public boolean startDemoSQL() {
-        return AgentSqlDemo.testDrive(cfg);
-    }
-
-    /**
      * Request result.
      */
     public static class RestResult {

http://git-wip-us.apache.org/repos/asf/ignite/blob/d603a53a/modules/control-center-agent/src/main/java/org/apache/ignite/console/demo/AgentSqlDemo.java
----------------------------------------------------------------------
diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/console/demo/AgentSqlDemo.java b/modules/control-center-agent/src/main/java/org/apache/ignite/console/demo/AgentSqlDemo.java
index 1e63232..7e1d1ce 100644
--- a/modules/control-center-agent/src/main/java/org/apache/ignite/console/demo/AgentSqlDemo.java
+++ b/modules/control-center-agent/src/main/java/org/apache/ignite/console/demo/AgentSqlDemo.java
@@ -322,14 +322,14 @@ public class AgentSqlDemo {
 
         IgniteCache<Integer, Country> cacheCountry = ignite.cache(COUNTRY_CACHE_NAME);
 
-        for (int i = 0, n = i + 1; i < CNTR_CNT; i++)
+        for (int i = 0, n = 1; i < CNTR_CNT; i++, n++)
             cacheCountry.put(i, new Country(i, "Country #" + n, n * 10000000));
 
         IgniteCache<Integer, Department> cacheDepartment = ignite.cache(DEPARTMENT_CACHE_NAME);
 
         IgniteCache<Integer, Employee> cacheEmployee = ignite.cache(EMPLOYEE_CACHE_NAME);
 
-        for (int i = 0, n = i + 1; i < DEP_CNT; i++) {
+        for (int i = 0, n = 1; i < DEP_CNT; i++, n++) {
             cacheDepartment.put(i, new Department(n, rnd.nextInt(CNTR_CNT), "Department #" + n));
 
             double r = rnd.nextDouble();
@@ -339,7 +339,7 @@ public class AgentSqlDemo {
                 new java.sql.Date((long)(r * range)), "Job manager #" + n, 1000 + round(r * 4000, 2)));
         }
 
-        for (int i = 0, n = i + 1; i < EMPL_CNT; i++) {
+        for (int i = 0, n = 1; i < EMPL_CNT; i++, n++) {
             Integer depId = rnd.nextInt(DEP_CNT);
 
             double r = rnd.nextDouble();
@@ -360,12 +360,12 @@ public class AgentSqlDemo {
 
         IgniteCache<Integer, Parking> cacheParking = ignite.cache(PARKING_CACHE_NAME);
 
-        for (int i = 0, n = i + 1; i < PARK_CNT; i++)
+        for (int i = 0, n = 1; i < PARK_CNT; i++, n++)
             cacheParking.put(i, new Parking(i, "Parking #" + n, n * 10));
 
         IgniteCache<Integer, Car> cacheCar = ignite.cache(CAR_CACHE_NAME);
 
-        for (int i = 0, n = i + 1; i < CAR_CNT; i++)
+        for (int i = 0, n = 1; i < CAR_CNT; i++, n++)
             cacheCar.put(i, new Car(i, rnd.nextInt(PARK_CNT), "Car #" + n));
 
         log.trace("DEMO: Finished cars population.");
@@ -419,7 +419,7 @@ public class AgentSqlDemo {
                     IgniteCache<Integer, Employee> cacheEmployee = ignite.cache(EMPLOYEE_CACHE_NAME);
 
                     if (cacheEmployee != null)
-                        for (int i = 0, n = i + 1; i < cnt; i++) {
+                        for (int i = 0, n = 1; i < cnt; i++, n++) {
                             Integer id = rnd.nextInt(EMPL_CNT);
 
                             Integer depId = rnd.nextInt(DEP_CNT);

http://git-wip-us.apache.org/repos/asf/ignite/blob/d603a53a/modules/control-center-web/src/main/js/app/modules/QueryNotebooks/index.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app/modules/QueryNotebooks/index.js b/modules/control-center-web/src/main/js/app/modules/QueryNotebooks/index.js
index 702b107..b87a506 100644
--- a/modules/control-center-web/src/main/js/app/modules/QueryNotebooks/index.js
+++ b/modules/control-center-web/src/main/js/app/modules/QueryNotebooks/index.js
@@ -29,17 +29,11 @@ angular
                     name: 'Simple query',
                     cacheName: 'CarCache',
                     pageSize: 50,
-                    query: 'SELECT * FROM Car',
+                    query: 'SELECT * FROM "CarCache".Car',
                     result: 'table',
-                    queryArgs: {
-                        type: 'QUERY',
-                        query: 'SELECT * FROM Car',
-                        pageSize: 50,
-                        cacheName: 'CarCache'
-                    },
                     rate: {
-                        value: 1,
-                        unit: 60000,
+                        value: 30,
+                        unit: 1000,
                         installed: false
                     }
                 },
@@ -47,17 +41,11 @@ angular
                     name: 'Query with aggregates',
                     cacheName: 'CarCache',
                     pageSize: 50,
-                    query: 'SELECT * FROM Car',
+                    query: 'SELECT p.name, count(*) AS cnt\nFROM "ParkingCache".Parking p\nINNER JOIN "CarCache".Car c\nON (p.id) = (c.parkingId)\nGROUP BY P.NAME',
                     result: 'table',
-                    queryArgs: {
-                        type: 'QUERY',
-                        query: 'SELECT * FROM Car',
-                        pageSize: 50,
-                        cacheName: 'CarCache'
-                    },
                     rate: {
-                        value: 1,
-                        unit: 60000,
+                        value: 30,
+                        unit: 1000,
                         installed: false
                     }
                 },
@@ -65,18 +53,12 @@ angular
                     name: 'Query with refresh rate',
                     cacheName: 'CarCache',
                     pageSize: 50,
-                    query: 'SELECT * FROM Car',
+                    query: 'SELECT * FROM "CarCache".Car',
                     result: 'table',
-                    queryArgs: {
-                        type: 'QUERY',
-                        query: 'SELECT * FROM Car',
-                        pageSize: 50,
-                        cacheName: 'CarCache'
-                    },
                     rate: {
-                        value: 1,
-                        unit: 60000,
-                        installed: false
+                        value: 5,
+                        unit: 1000,
+                        installed: true
                     }
                 }
             ],
@@ -86,12 +68,8 @@ angular
         this.$get = ['$q', '$http', ($q, $http) => {
             return {
                 read(demo, noteId) {
-                    if (demo) {
-                        return $http.post('/api/v1/agent/demo/sql/start')
-                            .then(() => {
-                                return angular.copy(_demoNotebook);
-                            });
-                    }
+                    if (demo)
+                        return $q.when(angular.copy(_demoNotebook));
 
                     return $http.post('/api/v1/notebooks/get', {noteId})
                         .then(({data}) => {

http://git-wip-us.apache.org/repos/asf/ignite/blob/d603a53a/modules/control-center-web/src/main/js/controllers/common-module.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/controllers/common-module.js b/modules/control-center-web/src/main/js/controllers/common-module.js
index e995175..b5f3478 100644
--- a/modules/control-center-web/src/main/js/controllers/common-module.js
+++ b/modules/control-center-web/src/main/js/controllers/common-module.js
@@ -2140,6 +2140,7 @@ consoleModule.service('$agentDownload', [
              * Start listening topology from node.
              *
              * @param success Function to execute by timer when agent available.
+             * @param demo
              * @param attr
              * @param mtr
              */

http://git-wip-us.apache.org/repos/asf/ignite/blob/d603a53a/modules/control-center-web/src/main/js/controllers/sql-controller.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/controllers/sql-controller.js b/modules/control-center-web/src/main/js/controllers/sql-controller.js
index 69fbc85..aeb6c35 100644
--- a/modules/control-center-web/src/main/js/controllers/sql-controller.js
+++ b/modules/control-center-web/src/main/js/controllers/sql-controller.js
@@ -282,18 +282,8 @@ consoleModule.controller('sqlController', function ($http, $timeout, $interval,
         .then(loadNotebook)
         .catch(function(err) {
             $scope.notebook = undefined;
-        })
-        .finally(function() {
-            $scope.loaded = true;
-
-            $loading.finish('loading');
         });
 
-    var _saveNotebook = function (cb) {
-        QueryNotebooks.save(_demo, $scope.notebook)
-            .catch(_handleException);
-    };
-
     $scope.renameNotebook = function (name) {
         if (!name)
             return;
@@ -462,6 +452,10 @@ consoleModule.controller('sqlController', function ($http, $timeout, $interval,
         }), 'name');
 
         _setActiveCache();
+
+        $scope.loaded = true;
+
+        $loading.finish('loading');
     }
 
     var _columnFilter = function(paragraph) {

http://git-wip-us.apache.org/repos/asf/ignite/blob/d603a53a/modules/control-center-web/src/main/js/routes/agent.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/routes/agent.js b/modules/control-center-web/src/main/js/routes/agent.js
index 9229a3f..02d5c7a 100644
--- a/modules/control-center-web/src/main/js/routes/agent.js
+++ b/modules/control-center-web/src/main/js/routes/agent.js
@@ -268,23 +268,6 @@ router.post('/ping', function (req, res) {
         res.sendStatus(200);
 });
 
-/* Enable test-drive for sql. */
-router.post('/demo/sql/start', function (req, res) {
-    var client = _client(req, res);
-
-    if (client) {
-        client.startDemoSQL(function (err, enabled) {
-            if (err)
-                return res.status(500).send(err.message);
-
-            if (!enabled)
-                return res.status(500).send('Failed to start SQL demo');
-
-            res.sendStatus(200);
-        });
-    }
-});
-
 /* Get JDBC drivers list. */
 router.post('/drivers', function (req, res) {
     var client = _client(req, res);