You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by sb...@apache.org on 2016/12/02 09:25:11 UTC

[05/19] ignite git commit: Web console beta-6.

Web console beta-6.


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

Branch: refs/heads/master
Commit: bf330251734018467fa3291fccf0414c9da7dd1b
Parents: 7a47a01
Author: Andrey Novikov <an...@gridgain.com>
Authored: Thu Nov 24 17:08:08 2016 +0700
Committer: Andrey Novikov <an...@gridgain.com>
Committed: Thu Nov 24 17:08:08 2016 +0700

----------------------------------------------------------------------
 modules/web-console/backend/app/agent.js        |  32 ++-
 modules/web-console/backend/app/browser.js      |  13 ++
 modules/web-console/backend/app/mongo.js        |   6 +
 .../backend/config/settings.json.sample         |   7 -
 modules/web-console/backend/index.js            |   6 +-
 modules/web-console/backend/middlewares/host.js |   7 +-
 modules/web-console/backend/routes/agent.js     |   4 +-
 modules/web-console/backend/services/agents.js  |   2 +-
 modules/web-console/backend/services/caches.js  |   2 +
 .../docker/compose/backend/.dockerignore        |   2 +
 .../docker/compose/backend/Dockerfile           |   6 +-
 .../web-console/docker/compose/backend/build.sh |   2 +-
 .../docker/compose/docker-compose.yml           |   5 -
 .../docker/compose/frontend/DockerfileBuild     |   4 +-
 .../docker/compose/frontend/build.sh            |   2 +-
 .../compose/frontend/nginx/web-console.conf     |   9 +
 .../web-console/docker/standalone/.dockerignore |   5 +
 .../web-console/docker/standalone/Dockerfile    |  10 +-
 modules/web-console/docker/standalone/build.sh  |   2 +-
 .../docker/standalone/docker-compose.yml        |   7 +-
 .../docker/standalone/nginx/web-console.conf    |   9 +
 .../frontend/app/data/pom-dependencies.json     |   2 +-
 .../directives/ui-ace-pojos/ui-ace-pojos.jade   |   2 +-
 .../frontend/app/filters/duration.filter.js     |   3 +
 .../helpers/jade/form/form-field-checkbox.jade  |   2 +-
 .../helpers/jade/form/form-field-datalist.jade  |   2 +-
 .../helpers/jade/form/form-field-dropdown.jade  |   2 +-
 .../helpers/jade/form/form-field-number.jade    |   2 +-
 .../helpers/jade/form/form-field-password.jade  |   2 +-
 .../app/helpers/jade/form/form-field-text.jade  |   2 +-
 .../frontend/app/helpers/jade/mixins.jade       |  24 +-
 .../modules/configuration/generator/Beans.js    |   6 +
 .../generator/ConfigurationGenerator.js         | 165 ++++++-------
 .../generator/JavaTransformer.service.js        |  15 +-
 .../generator/Properties.service.js             |  19 ++
 .../generator/SpringTransformer.service.js      |  22 +-
 .../generator/defaults/cache.provider.js        |   8 +
 .../generator/defaults/cluster.provider.js      |   2 +-
 .../app/modules/form/field/tooltip.directive.js |   2 +-
 .../app/modules/form/group/tooltip.directive.js |   2 +-
 .../app/modules/form/panel/field.directive.js   |   4 +-
 .../app/modules/sql/scan-filter-input.jade      |   2 +-
 .../frontend/app/modules/sql/sql.controller.js  |   6 +-
 .../configuration/caches/client-near-cache.jade |   2 +-
 .../configuration/caches/concurrency.jade       |   2 +-
 .../states/configuration/caches/general.jade    |   2 +-
 .../states/configuration/caches/memory.jade     |   2 +-
 .../configuration/caches/near-cache-client.jade |   2 +-
 .../configuration/caches/near-cache-server.jade |   2 +-
 .../configuration/caches/node-filter.jade       |   2 +-
 .../states/configuration/caches/query.jade      |   2 +-
 .../states/configuration/caches/rebalance.jade  |   2 +-
 .../states/configuration/caches/statistics.jade |   2 +-
 .../states/configuration/caches/store.jade      |  20 +-
 .../states/configuration/clusters/atomic.jade   |   2 +-
 .../configuration/clusters/attributes.jade      |   2 +-
 .../states/configuration/clusters/binary.jade   |   2 +-
 .../configuration/clusters/cache-key-cfg.jade   |   2 +-
 .../configuration/clusters/checkpoint.jade      |   8 +-
 .../configuration/clusters/checkpoint/fs.jade   |   2 +-
 .../configuration/clusters/checkpoint/jdbc.jade |  41 ++--
 .../configuration/clusters/checkpoint/s3.jade   | 229 ++++++++++---------
 .../configuration/clusters/collision.jade       |  12 +-
 .../clusters/collision/custom.jade              |   2 +-
 .../clusters/collision/fifo-queue.jade          |   2 +-
 .../clusters/collision/job-stealing.jade        |   2 +-
 .../clusters/collision/priority-queue.jade      |   2 +-
 .../configuration/clusters/communication.jade   |   2 +-
 .../configuration/clusters/connector.jade       |   2 +-
 .../configuration/clusters/deployment.jade      |   2 +-
 .../configuration/clusters/discovery.jade       |   2 +-
 .../states/configuration/clusters/events.jade   |   2 +-
 .../states/configuration/clusters/failover.jade |   2 +-
 .../states/configuration/clusters/general.jade  |   2 +-
 .../clusters/general/discovery/cloud.jade       |   2 +-
 .../clusters/general/discovery/google.jade      |   2 +-
 .../clusters/general/discovery/jdbc.jade        |   3 +-
 .../clusters/general/discovery/multicast.jade   |   2 +-
 .../clusters/general/discovery/s3.jade          |   2 +-
 .../clusters/general/discovery/shared.jade      |   2 +-
 .../clusters/general/discovery/vm.jade          |   2 +-
 .../clusters/general/discovery/zookeeper.jade   |   2 +-
 .../bounded-exponential-backoff.jade            |   2 +-
 .../discovery/zookeeper/retrypolicy/custom.jade |   2 +-
 .../retrypolicy/exponential-backoff.jade        |   2 +-
 .../zookeeper/retrypolicy/forever.jade          |   2 +-
 .../zookeeper/retrypolicy/n-times.jade          |   2 +-
 .../zookeeper/retrypolicy/one-time.jade         |   2 +-
 .../zookeeper/retrypolicy/until-elapsed.jade    |   2 +-
 .../states/configuration/clusters/igfs.jade     |   2 +-
 .../configuration/clusters/load-balancing.jade  |   2 +-
 .../states/configuration/clusters/logger.jade   |   2 +-
 .../configuration/clusters/logger/custom.jade   |   2 +-
 .../configuration/clusters/logger/log4j.jade    |   2 +-
 .../configuration/clusters/logger/log4j2.jade   |   2 +-
 .../configuration/clusters/marshaller.jade      |   2 +-
 .../states/configuration/clusters/metrics.jade  |   2 +-
 .../states/configuration/clusters/odbc.jade     |   2 +-
 .../states/configuration/clusters/ssl.jade      |   2 +-
 .../states/configuration/clusters/swap.jade     |   2 +-
 .../states/configuration/clusters/thread.jade   |   2 +-
 .../states/configuration/clusters/time.jade     |   2 +-
 .../configuration/clusters/transactions.jade    |   2 +-
 .../states/configuration/domains/general.jade   |   2 +-
 .../states/configuration/domains/query.jade     |  16 +-
 .../states/configuration/domains/store.jade     |  12 +-
 .../modules/states/configuration/igfs/dual.jade |   2 +-
 .../states/configuration/igfs/fragmentizer.jade |   2 +-
 .../states/configuration/igfs/general.jade      |   2 +-
 .../modules/states/configuration/igfs/ipc.jade  |   2 +-
 .../modules/states/configuration/igfs/misc.jade |   6 +-
 .../states/configuration/igfs/secondary.jade    |   2 +-
 .../configuration/summary/summary.controller.js |  12 +-
 .../frontend/controllers/clusters-controller.js |  10 +
 .../frontend/controllers/domains-controller.js  |   8 +-
 .../frontend/gulpfile.babel.js/tasks/jade.js    |   4 +-
 .../frontend/gulpfile.babel.js/tasks/test.js    |  92 --------
 .../gulpfile.babel.js/webpack/common.js         |   5 +-
 .../webpack/environments/development.js         |   5 +
 modules/web-console/frontend/package.json       |   2 +-
 .../stylesheets/_font-awesome-custom.scss       |  18 ++
 .../frontend/public/stylesheets/style.scss      |  13 +-
 .../frontend/views/configuration/caches.jade    |  22 +-
 .../frontend/views/configuration/clusters.jade  |  50 ++--
 .../views/configuration/domains-import.jade     |   4 +-
 .../frontend/views/configuration/domains.jade   |   8 +-
 .../frontend/views/configuration/igfs.jade      |  14 +-
 .../frontend/views/configuration/summary.jade   |   2 +-
 .../frontend/views/includes/header.jade         |  15 +-
 .../frontend/views/settings/profile.jade        |   2 +-
 modules/web-console/frontend/views/sql/sql.jade |   2 +-
 .../views/templates/agent-download.jade         |   2 +-
 .../frontend/views/templates/batch-confirm.jade |   2 +-
 .../frontend/views/templates/clone.jade         |   2 +-
 .../frontend/views/templates/confirm.jade       |   2 +-
 modules/web-console/web-agent/README.txt        |   4 +-
 .../web-agent/bin/ignite-web-agent.bat          |   7 +-
 .../web-agent/bin/ignite-web-agent.sh           |   6 +-
 .../console/agent/AgentConfiguration.java       |   5 +-
 .../ignite/console/agent/AgentLauncher.java     |   6 +-
 .../ignite/console/demo/AgentClusterDemo.java   |   1 +
 141 files changed, 667 insertions(+), 563 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/bf330251/modules/web-console/backend/app/agent.js
----------------------------------------------------------------------
diff --git a/modules/web-console/backend/app/agent.js b/modules/web-console/backend/app/agent.js
index 6aa9a12..f74a3f2 100644
--- a/modules/web-console/backend/app/agent.js
+++ b/modules/web-console/backend/app/agent.js
@@ -297,6 +297,23 @@ module.exports.factory = function(_, fs, path, JSZip, socketio, settings, mongo)
 
         /**
          * @param {Boolean} demo Is need run command on demo node.
+         * @param {Array.<String>} nids Node ids.
+         * @param {Number} since Metrics since.
+         * @returns {Promise}
+         */
+        queryDetailMetrics(demo, nids, since) {
+            const cmd = new Command(demo, 'exe')
+                .addParam('name', 'org.apache.ignite.internal.visor.compute.VisorGatewayTask')
+                .addParam('p1', nids)
+                .addParam('p2', 'org.apache.ignite.internal.visor.cache.VisorCacheQueryDetailMetricsCollectorTask')
+                .addParam('p3', 'java.lang.Long')
+                .addParam('p4', since);
+
+            return this.executeRest(cmd);
+        }
+
+        /**
+         * @param {Boolean} demo Is need run command on demo node.
          * @param {String} cacheName Cache name.
          * @returns {Promise}
          */
@@ -634,6 +651,19 @@ module.exports.factory = function(_, fs, path, JSZip, socketio, settings, mongo)
                 });
         }
 
+        attachLegacy(srv) {
+            /**
+             * @type {socketIo.Server}
+             */
+            const io = socketio(srv);
+
+            io.on('connection', (socket) => {
+                socket.on('agent:auth', (data, cb) => {
+                    return cb('You are using an older version of the agent. Please reload agent archive');
+                });
+            });
+        }
+
         /**
          * @param {http.Server|https.Server} srv Server instance that we want to attach agent handler.
          */
@@ -646,7 +676,7 @@ module.exports.factory = function(_, fs, path, JSZip, socketio, settings, mongo)
             /**
              * @type {socketIo.Server}
              */
-            this._socket = socketio(this._server);
+            this._socket = socketio(this._server, {path: '/agents'});
 
             this._socket.on('connection', (socket) => {
                 socket.on('agent:auth', (data, cb) => {

http://git-wip-us.apache.org/repos/asf/ignite/blob/bf330251/modules/web-console/backend/app/browser.js
----------------------------------------------------------------------
diff --git a/modules/web-console/backend/app/browser.js b/modules/web-console/backend/app/browser.js
index 254851d..2710829 100644
--- a/modules/web-console/backend/app/browser.js
+++ b/modules/web-console/backend/app/browser.js
@@ -149,6 +149,19 @@ module.exports.factory = (_, socketio, agentMgr, configure) => {
                         .catch((err) => cb(_errorToJson(err)));
                 });
 
+                // Collect cache query metrics and return result to browser.
+                socket.on('node:query:metrics', (nids, since, cb) => {
+                    agentMgr.findAgent(accountId())
+                        .then((agent) => agent.queryDetailMetrics(demo, nids, since))
+                        .then((data) => {
+                            if (data.finished)
+                                return cb(null, data.result);
+
+                            cb(_errorToJson(data.error));
+                        })
+                        .catch((err) => cb(_errorToJson(err)));
+                });
+
                 // Return cache metadata from all nodes in grid.
                 socket.on('node:cache:metadata', (cacheName, cb) => {
                     agentMgr.findAgent(accountId())

http://git-wip-us.apache.org/repos/asf/ignite/blob/bf330251/modules/web-console/backend/app/mongo.js
----------------------------------------------------------------------
diff --git a/modules/web-console/backend/app/mongo.js b/modules/web-console/backend/app/mongo.js
index e12af2a..0f38eb2 100644
--- a/modules/web-console/backend/app/mongo.js
+++ b/modules/web-console/backend/app/mongo.js
@@ -197,6 +197,12 @@ module.exports.factory = function(passportMongo, settings, pluginMongo, mongoose
                     type: String,
                     enum: ['Generic', 'Oracle', 'DB2', 'SQLServer', 'MySQL', 'PostgreSQL', 'H2']
                 },
+                batchSize: Number,
+                maximumPoolSize: Number,
+                maximumWriteAttempts: Number,
+                parallelLoadCacheMinimumThreshold: Number,
+                hasher: String,
+                transformer: String,
                 sqlEscapeAll: Boolean
             },
             CacheJdbcBlobStoreFactory: {

http://git-wip-us.apache.org/repos/asf/ignite/blob/bf330251/modules/web-console/backend/config/settings.json.sample
----------------------------------------------------------------------
diff --git a/modules/web-console/backend/config/settings.json.sample b/modules/web-console/backend/config/settings.json.sample
index 41f1152..71a64ea 100644
--- a/modules/web-console/backend/config/settings.json.sample
+++ b/modules/web-console/backend/config/settings.json.sample
@@ -10,13 +10,6 @@
     "mongodb": {
         "url": "mongodb://localhost/console"
     },
-    "agentServer": {
-        "port": 3001,
-        "ssl": false,
-        "key": "serve/keys/test.key",
-        "cert": "serve/keys/test.crt",
-        "keyPassphrase": "password"
-    },
     "mail": {
         "service": "",
         "sign": "Kind regards,<br>Apache Ignite Team",

http://git-wip-us.apache.org/repos/asf/ignite/blob/bf330251/modules/web-console/backend/index.js
----------------------------------------------------------------------
diff --git a/modules/web-console/backend/index.js b/modules/web-console/backend/index.js
index 3a8ada9..9eeff35 100644
--- a/modules/web-console/backend/index.js
+++ b/modules/web-console/backend/index.js
@@ -82,9 +82,11 @@ Promise.all([injector('settings'), injector('app'), injector('agent-manager'), i
         server.on('listening', _onListening.bind(null, server.address()));
 
         app.listen(server);
+
+        agentMgr.attach(server);
         browserMgr.attach(server);
 
-        // Start agent server.
+        // Start legacy agent server.
         const agentServer = settings.agent.SSLOptions
             ? https.createServer(settings.agent.SSLOptions) : http.createServer();
 
@@ -92,7 +94,7 @@ Promise.all([injector('settings'), injector('app'), injector('agent-manager'), i
         agentServer.on('error', _onError.bind(null, settings.agent.port));
         agentServer.on('listening', _onListening.bind(null, agentServer.address()));
 
-        agentMgr.attach(agentServer);
+        agentMgr.attachLegacy(agentServer);
 
         // Used for automated test.
         if (process.send)

http://git-wip-us.apache.org/repos/asf/ignite/blob/bf330251/modules/web-console/backend/middlewares/host.js
----------------------------------------------------------------------
diff --git a/modules/web-console/backend/middlewares/host.js b/modules/web-console/backend/middlewares/host.js
index 5ddd918..4c21da2 100644
--- a/modules/web-console/backend/middlewares/host.js
+++ b/modules/web-console/backend/middlewares/host.js
@@ -27,10 +27,11 @@ module.exports = {
                 if (req.headers.origin)
                     return req.headers.origin;
 
-                if (req.headers['x-forwarded-server'])
-                    return `${req.headers['x-forwarded-proto'] || 'http'}://${req.headers['x-forwarded-server']}`;
+                const proto = req.headers['x-forwarded-proto'] || req.protocol;
 
-                return `${req.protocol}://${req.get('host')}`;
+                const host = req.headers['x-forwarded-host'] || req.get('host');
+
+                return `${proto}://${host}`;
             };
 
             next();

http://git-wip-us.apache.org/repos/asf/ignite/blob/bf330251/modules/web-console/backend/routes/agent.js
----------------------------------------------------------------------
diff --git a/modules/web-console/backend/routes/agent.js b/modules/web-console/backend/routes/agent.js
index 3f90fbd..477363f 100644
--- a/modules/web-console/backend/routes/agent.js
+++ b/modules/web-console/backend/routes/agent.js
@@ -36,9 +36,7 @@ module.exports.factory = function(_, express, agentsService) {
 
         /* Get grid topology. */
         router.get('/download/zip', (req, res) => {
-            const host = req.hostname.match(/:/g) ? req.hostname.slice(0, req.hostname.indexOf(':')) : req.hostname;
-
-            agentsService.getArchive(host, req.user.token)
+            agentsService.getArchive(req.origin(), req.user.token)
                 .then(({fileName, buffer}) => {
                     // Set the archive name.
                     res.attachment(fileName);

http://git-wip-us.apache.org/repos/asf/ignite/blob/bf330251/modules/web-console/backend/services/agents.js
----------------------------------------------------------------------
diff --git a/modules/web-console/backend/services/agents.js b/modules/web-console/backend/services/agents.js
index 5c0b6a7..4931bf8 100644
--- a/modules/web-console/backend/services/agents.js
+++ b/modules/web-console/backend/services/agents.js
@@ -63,7 +63,7 @@ module.exports.factory = (_, fs, path, JSZip, settings, agentMgr, errors) => {
                             const prop = [];
 
                             prop.push('tokens=' + token);
-                            prop.push('server-uri=' + (settings.agent.SSLOptions ? 'https' : 'http') + '://' + host + ':' + settings.agent.port);
+                            prop.push(`server-uri=${host}`);
                             prop.push('#Uncomment following options if needed:');
                             prop.push('#node-uri=http://localhost:8080');
                             prop.push('#driver-folder=./jdbc-drivers');

http://git-wip-us.apache.org/repos/asf/ignite/blob/bf330251/modules/web-console/backend/services/caches.js
----------------------------------------------------------------------
diff --git a/modules/web-console/backend/services/caches.js b/modules/web-console/backend/services/caches.js
index e59d51d..646fbea 100644
--- a/modules/web-console/backend/services/caches.js
+++ b/modules/web-console/backend/services/caches.js
@@ -87,6 +87,7 @@ module.exports.factory = (_, mongo, spaceService, errors) => {
      */
     const removeAllBySpaces = (spaceIds) => {
         return mongo.Cluster.update({space: {$in: spaceIds}}, {caches: []}, {multi: true}).exec()
+            .then(() => mongo.Cluster.update({space: {$in: spaceIds}}, {$pull: {checkpointSpi: {kind: 'Cache'}}}, {multi: true}).exec())
             .then(() => mongo.DomainModel.update({space: {$in: spaceIds}}, {caches: []}, {multi: true}).exec())
             .then(() => mongo.Cache.remove({space: {$in: spaceIds}}).exec());
     };
@@ -129,6 +130,7 @@ module.exports.factory = (_, mongo, spaceService, errors) => {
                 return Promise.reject(new errors.IllegalArgumentException('Cache id can not be undefined or null'));
 
             return mongo.Cluster.update({caches: {$in: [cacheId]}}, {$pull: {caches: cacheId}}, {multi: true}).exec()
+                .then(() => mongo.Cluster.update({}, {$pull: {checkpointSpi: {kind: 'Cache', Cache: {cache: cacheId}}}}, {multi: true}).exec())
                 .then(() => mongo.DomainModel.update({caches: {$in: [cacheId]}}, {$pull: {caches: cacheId}}, {multi: true}).exec())
                 .then(() => mongo.Cache.remove({_id: cacheId}).exec())
                 .then(convertRemoveStatus);

http://git-wip-us.apache.org/repos/asf/ignite/blob/bf330251/modules/web-console/docker/compose/backend/.dockerignore
----------------------------------------------------------------------
diff --git a/modules/web-console/docker/compose/backend/.dockerignore b/modules/web-console/docker/compose/backend/.dockerignore
index 6fadfa5..05df665 100644
--- a/modules/web-console/docker/compose/backend/.dockerignore
+++ b/modules/web-console/docker/compose/backend/.dockerignore
@@ -1 +1,3 @@
+build/config/*.json
 build/node_modules
+build/test

http://git-wip-us.apache.org/repos/asf/ignite/blob/bf330251/modules/web-console/docker/compose/backend/Dockerfile
----------------------------------------------------------------------
diff --git a/modules/web-console/docker/compose/backend/Dockerfile b/modules/web-console/docker/compose/backend/Dockerfile
index b4f7c9d..e391ba4 100644
--- a/modules/web-console/docker/compose/backend/Dockerfile
+++ b/modules/web-console/docker/compose/backend/Dockerfile
@@ -15,7 +15,7 @@
 # limitations under the License.
 #
 
-FROM node:4
+FROM node:6
 
 RUN mkdir -p /opt/web-console-backend
 
@@ -23,8 +23,8 @@ WORKDIR /opt/web-console-backend
 
 COPY build .
 
-RUN npm -g update npm && npm install --no-optional
+RUN npm install --only=production --no-optional
 
-EXPOSE 3000 3001
+EXPOSE 3000
 
 CMD ["npm", "start"]

http://git-wip-us.apache.org/repos/asf/ignite/blob/bf330251/modules/web-console/docker/compose/backend/build.sh
----------------------------------------------------------------------
diff --git a/modules/web-console/docker/compose/backend/build.sh b/modules/web-console/docker/compose/backend/build.sh
index f925bd7..d44efbd 100755
--- a/modules/web-console/docker/compose/backend/build.sh
+++ b/modules/web-console/docker/compose/backend/build.sh
@@ -51,7 +51,7 @@ cp -r $IGNITE_WEB_CONSOLE_BACKEND_DIR/. $BUILD_DIR
 cp $IGNITE_HOME/modules/web-console/web-agent/target/ignite-web-agent*.zip $BUILD_DIR/agent_dists/.
 
 echo "Step 4. Build docker image."
-docker build -f=./Dockerfile -t $DOCKER_IMAGE_NAME:$RELEASE_VERSION .
+docker build -f=./Dockerfile -t $DOCKER_IMAGE_NAME:$RELEASE_VERSION -t $DOCKER_IMAGE_NAME:latest .
 
 echo "Step 5. Cleanup."
 rm -Rf $BUILD_DIR

http://git-wip-us.apache.org/repos/asf/ignite/blob/bf330251/modules/web-console/docker/compose/docker-compose.yml
----------------------------------------------------------------------
diff --git a/modules/web-console/docker/compose/docker-compose.yml b/modules/web-console/docker/compose/docker-compose.yml
index a2c2f8b..8b9b86a 100644
--- a/modules/web-console/docker/compose/docker-compose.yml
+++ b/modules/web-console/docker/compose/docker-compose.yml
@@ -26,9 +26,6 @@ backend:
   links:
     # Link mongodb container as with mongodb hostname.
     - mongodb:mongodb
-  ports:
-    # Proxy 3001 port from docker container to 3001 port host machine. (HOST_PORT:DOCKER_PORT)
-    - 3001:3001
   # Restart on crash.
   restart: always  
   environment:
@@ -38,8 +35,6 @@ backend:
     - server_sessionSecret=CHANGE ME
     # URL for mongodb connection
     - mongodb_url=mongodb://mongodb/console
-    # Port for web-agent.
-    - agentServer_port=3001
     # Mail connection settings. Leave empty if no needed. See also settings, https://github.com/nodemailer/nodemailer
     - mail_service=
     - mail_sign=

http://git-wip-us.apache.org/repos/asf/ignite/blob/bf330251/modules/web-console/docker/compose/frontend/DockerfileBuild
----------------------------------------------------------------------
diff --git a/modules/web-console/docker/compose/frontend/DockerfileBuild b/modules/web-console/docker/compose/frontend/DockerfileBuild
index 277991f..2d61f4c 100644
--- a/modules/web-console/docker/compose/frontend/DockerfileBuild
+++ b/modules/web-console/docker/compose/frontend/DockerfileBuild
@@ -15,7 +15,7 @@
 # limitations under the License.
 #
 
-FROM node:4
+FROM node:6
 
 RUN mkdir -p /opt/web-console-frontend
 
@@ -23,7 +23,7 @@ WORKDIR /opt/web-console-frontend
 
 COPY src .
 
-RUN npm update -g npm && npm install --no-optional
+RUN npm install --no-optional
 
 VOLUME /opt/web-console-frontend/build
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/bf330251/modules/web-console/docker/compose/frontend/build.sh
----------------------------------------------------------------------
diff --git a/modules/web-console/docker/compose/frontend/build.sh b/modules/web-console/docker/compose/frontend/build.sh
index 4dfa57a..6d52fb2 100755
--- a/modules/web-console/docker/compose/frontend/build.sh
+++ b/modules/web-console/docker/compose/frontend/build.sh
@@ -50,7 +50,7 @@ docker build -f=./DockerfileBuild -t $DOCKER_BUILD_IMAGE_NAME:latest .
 docker run -it -v $BUILD_DIR:/opt/web-console-frontend/build --name $DOCKER_BUILD_CONTAINER $DOCKER_BUILD_IMAGE_NAME
 
 echo "Step 2. Build NGINX container with SPA and proxy configuration"
-docker build -f=./Dockerfile -t $DOCKER_IMAGE_NAME:$RELEASE_VERSION .
+docker build -f=./Dockerfile -t $DOCKER_IMAGE_NAME:$RELEASE_VERSION -t $DOCKER_IMAGE_NAME:latest .
 
 echo "Step 3. Cleanup"
 docker rm -f $DOCKER_BUILD_CONTAINER

http://git-wip-us.apache.org/repos/asf/ignite/blob/bf330251/modules/web-console/docker/compose/frontend/nginx/web-console.conf
----------------------------------------------------------------------
diff --git a/modules/web-console/docker/compose/frontend/nginx/web-console.conf b/modules/web-console/docker/compose/frontend/nginx/web-console.conf
index d80a7f9..323826e 100644
--- a/modules/web-console/docker/compose/frontend/nginx/web-console.conf
+++ b/modules/web-console/docker/compose/frontend/nginx/web-console.conf
@@ -53,6 +53,15 @@ server {
     proxy_pass http://backend-api;
   }
 
+  location /agents {
+    proxy_set_header Upgrade $http_upgrade;
+    proxy_set_header Connection "upgrade";
+    proxy_http_version 1.1;
+    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+    proxy_set_header Host $host;
+    proxy_pass http://backend-api;
+  }
+
   location = /50x.html {
     root $ignite_console_dir/error_page;
   }

http://git-wip-us.apache.org/repos/asf/ignite/blob/bf330251/modules/web-console/docker/standalone/.dockerignore
----------------------------------------------------------------------
diff --git a/modules/web-console/docker/standalone/.dockerignore b/modules/web-console/docker/standalone/.dockerignore
index 35b7244..c59189e 100644
--- a/modules/web-console/docker/standalone/.dockerignore
+++ b/modules/web-console/docker/standalone/.dockerignore
@@ -1,2 +1,7 @@
+build/frontend/build
 build/frontend/node_modules
+build/frontend/ignite_modules_temp
+build/frontend/test
+build/backend/config/*.json
 build/backend/node_modules
+build/backend/test

http://git-wip-us.apache.org/repos/asf/ignite/blob/bf330251/modules/web-console/docker/standalone/Dockerfile
----------------------------------------------------------------------
diff --git a/modules/web-console/docker/standalone/Dockerfile b/modules/web-console/docker/standalone/Dockerfile
index 785f109..0bcd07d 100644
--- a/modules/web-console/docker/standalone/Dockerfile
+++ b/modules/web-console/docker/standalone/Dockerfile
@@ -18,7 +18,7 @@
 FROM ubuntu:14.04
 
 ENV NPM_CONFIG_LOGLEVEL info
-ENV NODE_VERSION 4.4.7
+ENV NODE_VERSION 6.6.0
 
 # Before package list update.
 RUN set -ex  && \
@@ -40,7 +40,7 @@ RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv EA312927 && \
 
 # Update package list & install.
 RUN apt-get update && \
-    apt-get install -y nginx-light mongodb-org-server curl xz-utils
+    apt-get install -y nginx-light mongodb-org-server curl xz-utils git
 
 # Install Node JS.
 RUN curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-linux-x64.tar.xz"  && \
@@ -51,7 +51,7 @@ RUN curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-linux-
   rm "node-v$NODE_VERSION-linux-x64.tar.xz" SHASUMS256.txt.asc SHASUMS256.txt
 
 # Install global node packages.
-RUN npm upgrade -g npm && npm install -g pm2
+RUN npm install -g pm2
 
 # Install frontend & backend apps.
 RUN mkdir -p /opt/web-console
@@ -62,7 +62,7 @@ COPY build .
 
 # Install node modules.
 RUN cd /opt/web-console/frontend && npm install --no-optional && npm run build
-RUN cd /opt/web-console/backend && npm install --no-optional
+RUN cd /opt/web-console/backend && npm install --only=production --no-optional
 
 # Returns to base path.
 WORKDIR /opt/web-console
@@ -82,6 +82,6 @@ VOLUME ["/etc/nginx"]
 VOLUME ["/var/lib/mongodb"]
 VOLUME ["/opt/web-console/serve/agent_dists"]
 
-EXPOSE 80 3001
+EXPOSE 80
 
 ENTRYPOINT ["/opt/web-console/entrypoint.sh"]

http://git-wip-us.apache.org/repos/asf/ignite/blob/bf330251/modules/web-console/docker/standalone/build.sh
----------------------------------------------------------------------
diff --git a/modules/web-console/docker/standalone/build.sh b/modules/web-console/docker/standalone/build.sh
index 4365dec..5482086 100755
--- a/modules/web-console/docker/standalone/build.sh
+++ b/modules/web-console/docker/standalone/build.sh
@@ -53,7 +53,7 @@ cp -r $IGNITE_WEB_CONSOLE_DIR/backend/. $BUILD_DIR/backend
 cp $IGNITE_HOME/modules/web-console/web-agent/target/ignite-web-agent*.zip $BUILD_DIR/backend/agent_dists/.
 
 echo "Step 4. Build docker image."
-docker build -f=./Dockerfile -t $DOCKER_IMAGE_NAME:$RELEASE_VERSION .
+docker build -f=./Dockerfile -t $DOCKER_IMAGE_NAME:$RELEASE_VERSION -t $DOCKER_IMAGE_NAME:latest .
 
 echo "Step 5. Cleanup."
 rm -Rf $BUILD_DIR

http://git-wip-us.apache.org/repos/asf/ignite/blob/bf330251/modules/web-console/docker/standalone/docker-compose.yml
----------------------------------------------------------------------
diff --git a/modules/web-console/docker/standalone/docker-compose.yml b/modules/web-console/docker/standalone/docker-compose.yml
index 561c88d..eb59e8a 100644
--- a/modules/web-console/docker/standalone/docker-compose.yml
+++ b/modules/web-console/docker/standalone/docker-compose.yml
@@ -18,10 +18,7 @@
 webconsole:
   image: ignite/web-console-standalone
   ports:
-    - 3080:80
-    - 3000:3000
-    - 3001:3001
-    - 27017:27017
+    - 80:80
   restart: always
   environment:
     # Port for serving frontend API
@@ -30,8 +27,6 @@ webconsole:
     - server_sessionSecret="CHANGE ME"
     # URL for mongodb connection
     - mongodb_url=mongodb://127.0.0.1/console
-    # Port for web-agent.
-    - agentServer_port=3001
     # Mail connection settings. Leave empty if no needed. See also settings, https://github.com/nodemailer/nodemailer
     - mail_service=""
     - mail_sign=""

http://git-wip-us.apache.org/repos/asf/ignite/blob/bf330251/modules/web-console/docker/standalone/nginx/web-console.conf
----------------------------------------------------------------------
diff --git a/modules/web-console/docker/standalone/nginx/web-console.conf b/modules/web-console/docker/standalone/nginx/web-console.conf
index 3de544f..3d83075 100644
--- a/modules/web-console/docker/standalone/nginx/web-console.conf
+++ b/modules/web-console/docker/standalone/nginx/web-console.conf
@@ -48,6 +48,15 @@ server {
     proxy_pass http://backend-api;
   }
 
+  location /agents {
+    proxy_set_header Upgrade $http_upgrade;
+    proxy_set_header Connection "upgrade";
+    proxy_http_version 1.1;
+    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+    proxy_set_header Host $host;
+    proxy_pass http://backend-api;
+  }
+
   location = /50x.html {
     root $ignite_console_dir/error_page;
   }

http://git-wip-us.apache.org/repos/asf/ignite/blob/bf330251/modules/web-console/frontend/app/data/pom-dependencies.json
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/data/pom-dependencies.json b/modules/web-console/frontend/app/data/pom-dependencies.json
index 7ab6c1b..acf2bc8 100644
--- a/modules/web-console/frontend/app/data/pom-dependencies.json
+++ b/modules/web-console/frontend/app/data/pom-dependencies.json
@@ -13,7 +13,7 @@
     "Generic": {"groupId": "com.mchange", "artifactId": "c3p0", "version": "0.9.5.1"},
     "MySQL": {"groupId": "mysql", "artifactId": "mysql-connector-java", "version": "5.1.37"},
     "PostgreSQL": {"groupId": "org.postgresql", "artifactId": "postgresql", "version": "9.4-1204-jdbc42"},
-    "H2": {"groupId": "com.h2database", "artifactId": "h2", "version": "1.3.175"},
+    "H2": {"groupId": "com.h2database", "artifactId": "h2", "version": "1.4.191"},
     "Oracle": {"groupId": "oracle", "artifactId": "jdbc", "version": "11.2", "jar": "ojdbc6.jar"},
     "DB2": {"groupId": "ibm", "artifactId": "jdbc", "version": "4.19.26", "jar": "db2jcc4.jar"},
     "SQLServer": {"groupId": "microsoft", "artifactId": "jdbc", "version": "4.1", "jar": "sqljdbc41.jar"}

http://git-wip-us.apache.org/repos/asf/ignite/blob/bf330251/modules/web-console/frontend/app/directives/ui-ace-pojos/ui-ace-pojos.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/directives/ui-ace-pojos/ui-ace-pojos.jade b/modules/web-console/frontend/app/directives/ui-ace-pojos/ui-ace-pojos.jade
index ed1432b..581b8c1 100644
--- a/modules/web-console/frontend/app/directives/ui-ace-pojos/ui-ace-pojos.jade
+++ b/modules/web-console/frontend/app/directives/ui-ace-pojos/ui-ace-pojos.jade
@@ -15,7 +15,7 @@
     limitations under the License.
 
 mixin check-tooltip(message)
-    i.tipLabel.fa.fa-question-circle(bs-tooltip='"#{message}"')
+    i.tipLabel.icon-help(bs-tooltip='"#{message}"')
 
 .panel-details-noborder
     .details-row

http://git-wip-us.apache.org/repos/asf/ignite/blob/bf330251/modules/web-console/frontend/app/filters/duration.filter.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/filters/duration.filter.js b/modules/web-console/frontend/app/filters/duration.filter.js
index deeedd7..0d7afe6 100644
--- a/modules/web-console/frontend/app/filters/duration.filter.js
+++ b/modules/web-console/frontend/app/filters/duration.filter.js
@@ -20,6 +20,9 @@ export default ['duration', [() => {
      * @param {Number} t Time in ms.
      */
     return (t) => {
+        if (t === 9223372036854775807)
+            return 'Infinite';
+
         const a = (i, suffix) => i && i !== '00' ? i + suffix + ' ' : '';
 
         const cd = 24 * 60 * 60 * 1000;

http://git-wip-us.apache.org/repos/asf/ignite/blob/bf330251/modules/web-console/frontend/app/helpers/jade/form/form-field-checkbox.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/helpers/jade/form/form-field-checkbox.jade b/modules/web-console/frontend/app/helpers/jade/form/form-field-checkbox.jade
index ef5cb37..222ecfe 100644
--- a/modules/web-console/frontend/app/helpers/jade/form/form-field-checkbox.jade
+++ b/modules/web-console/frontend/app/helpers/jade/form/form-field-checkbox.jade
@@ -35,4 +35,4 @@ mixin form-field-checkbox(label, model, name, disabled, required, tip)
                         data-ignite-form-panel-field=''
                     )
             span #{label}
-            i.tipLabel.fa.fa-question-circle(bs-tooltip='' data-title=tip)
+            i.tipLabel.icon-help(bs-tooltip='' data-title=tip)

http://git-wip-us.apache.org/repos/asf/ignite/blob/bf330251/modules/web-console/frontend/app/helpers/jade/form/form-field-datalist.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/helpers/jade/form/form-field-datalist.jade b/modules/web-console/frontend/app/helpers/jade/form/form-field-datalist.jade
index 25e5805..4c1970e 100644
--- a/modules/web-console/frontend/app/helpers/jade/form/form-field-datalist.jade
+++ b/modules/web-console/frontend/app/helpers/jade/form/form-field-datalist.jade
@@ -40,7 +40,7 @@ mixin form-field-datalist(label, model, name, disabled, required, placeholder, o
     .ignite-form-field
         +ignite-form-field__label(label, name, required)
         .ignite-form-field__control
-            i.tipField.fa.fa-question-circle(bs-tooltip='' data-title=tip)
+            i.tipField.fa.icon-help(bs-tooltip='' data-title=tip)
 
             +form-field-feedback(name, 'required', errLbl + ' could not be empty!')
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/bf330251/modules/web-console/frontend/app/helpers/jade/form/form-field-dropdown.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/helpers/jade/form/form-field-dropdown.jade b/modules/web-console/frontend/app/helpers/jade/form/form-field-dropdown.jade
index f5d035d..298db52 100644
--- a/modules/web-console/frontend/app/helpers/jade/form/form-field-dropdown.jade
+++ b/modules/web-console/frontend/app/helpers/jade/form/form-field-dropdown.jade
@@ -41,7 +41,7 @@ mixin ignite-form-field-dropdown(label, model, name, disabled, required, multipl
     .ignite-form-field
         +ignite-form-field__label(label, name, required)
         .ignite-form-field__control
-            i.tipField.fa.fa-question-circle(bs-tooltip='' data-title=tip)
+            i.tipField.icon-help(bs-tooltip='' data-title=tip)
 
             if block
                 block

http://git-wip-us.apache.org/repos/asf/ignite/blob/bf330251/modules/web-console/frontend/app/helpers/jade/form/form-field-number.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/helpers/jade/form/form-field-number.jade b/modules/web-console/frontend/app/helpers/jade/form/form-field-number.jade
index 62b3e09..d48343c 100644
--- a/modules/web-console/frontend/app/helpers/jade/form/form-field-number.jade
+++ b/modules/web-console/frontend/app/helpers/jade/form/form-field-number.jade
@@ -38,7 +38,7 @@ mixin ignite-form-field-number(label, model, name, disabled, required, placehold
     .ignite-form-field
         +ignite-form-field__label(label, name, required)
         .ignite-form-field__control
-            i.tipField.fa.fa-question-circle(bs-tooltip='' data-title=tip)
+            i.tipField.icon-help(bs-tooltip='' data-title=tip)
             
             +form-field-feedback(name, 'required', 'This field could not be empty')
             +form-field-feedback(name, 'min', 'Value is less than allowable minimum: '+ min || 0)

http://git-wip-us.apache.org/repos/asf/ignite/blob/bf330251/modules/web-console/frontend/app/helpers/jade/form/form-field-password.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/helpers/jade/form/form-field-password.jade b/modules/web-console/frontend/app/helpers/jade/form/form-field-password.jade
index 51cc109..e5e7bc8 100644
--- a/modules/web-console/frontend/app/helpers/jade/form/form-field-password.jade
+++ b/modules/web-console/frontend/app/helpers/jade/form/form-field-password.jade
@@ -36,7 +36,7 @@ mixin ignite-form-field-password(label, model, name, disabled, required, placeho
     .ignite-form-field
         +ignite-form-field__label(label, name, required)
         .ignite-form-field__control
-            i.tipField.fa.fa-question-circle(bs-tooltip='' data-title=tip)
+            i.tipField.icon-help(bs-tooltip='' data-title=tip)
             
             if block
                 block

http://git-wip-us.apache.org/repos/asf/ignite/blob/bf330251/modules/web-console/frontend/app/helpers/jade/form/form-field-text.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/helpers/jade/form/form-field-text.jade b/modules/web-console/frontend/app/helpers/jade/form/form-field-text.jade
index 55b850d..136d23b 100644
--- a/modules/web-console/frontend/app/helpers/jade/form/form-field-text.jade
+++ b/modules/web-console/frontend/app/helpers/jade/form/form-field-text.jade
@@ -36,7 +36,7 @@ mixin ignite-form-field-text(label, model, name, disabled, required, placeholder
     .ignite-form-field
         +ignite-form-field__label(label, name, required)
         .ignite-form-field__control
-            i.tipField.fa.fa-question-circle(bs-tooltip='' data-title=tip)
+            i.tipField.icon-help(bs-tooltip='' data-title=tip)
             
             if block
                 block

http://git-wip-us.apache.org/repos/asf/ignite/blob/bf330251/modules/web-console/frontend/app/helpers/jade/mixins.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/helpers/jade/mixins.jade b/modules/web-console/frontend/app/helpers/jade/mixins.jade
index 9d46883..92af1b0 100644
--- a/modules/web-console/frontend/app/helpers/jade/mixins.jade
+++ b/modules/web-console/frontend/app/helpers/jade/mixins.jade
@@ -433,10 +433,8 @@ mixin evictionPolicy(model, name, enabled, required, tip)
             {value: "SORTED", label: "Sorted"},\
             {value: undefined, label: "Not set"}\
         ]', tip)
-    span(ng-if=kind ng-init='__ = {};')
-        a.customize(ng-show='__.expanded' ng-click='__.expanded = false') Hide settings
-        a.customize(ng-hide='__.expanded' ng-click='__.expanded = true') Show settings
-        .panel-details(ng-if='__.expanded')
+    span(ng-show=kind)
+        +showHideLink('expanded', 'settings')
             .details-row
                 +number('Batch size', policy + '.batchSize', name + '+ "batchSize"', enabled, '1', '1',
                     'Number of entries to remove on shrink')
@@ -517,9 +515,9 @@ mixin table-pair-edit(tbl, prefix, keyPlaceholder, valPlaceholder, keyJavaBuiltI
         .fieldSep !{divider}
         .input-tip
             if keyJavaBuiltInTypes
-                input.form-control(id=keyFocusId ignite-on-enter-focus-move=valFocusId type='text' ng-model=keyModel placeholder=keyPlaceholder bs-typeahead container='body' ignite-retain-selection data-min-length='1' bs-options='javaClass for javaClass in javaBuiltInClasses' ignite-on-escape='tableReset()')
+                input.form-control(id=keyFocusId ignite-on-enter-focus-move=valFocusId type='text' ng-model=keyModel placeholder=keyPlaceholder bs-typeahead container='body' ignite-retain-selection data-min-length='1' bs-options='javaClass for javaClass in javaBuiltInClasses' ignite-on-escape='tableReset(false)')
             else
-                input.form-control(id=keyFocusId ignite-on-enter-focus-move=valFocusId type='text' ng-model=keyModel placeholder=keyPlaceholder ignite-on-escape='tableReset()')
+                input.form-control(id=keyFocusId ignite-on-enter-focus-move=valFocusId type='text' ng-model=keyModel placeholder=keyPlaceholder ignite-on-escape='tableReset(false)')
     .col-xs-6.col-sm-6.col-md-6
         -var btnVisible = 'tablePairSaveVisible(' + tbl + ', ' + index + ')'
         -var btnSave = 'tablePairSave(tablePairValid, backupItem, ' + tbl + ', ' + index + ')'
@@ -528,9 +526,9 @@ mixin table-pair-edit(tbl, prefix, keyPlaceholder, valPlaceholder, keyJavaBuiltI
         +btn-save(btnVisible, btnSave)
         .input-tip
             if valueJavaBuiltInTypes
-                input.form-control(id=valFocusId type='text' ng-model=valModel placeholder=valPlaceholder bs-typeahead container='body' ignite-retain-selection data-min-length='1' bs-options='javaClass for javaClass in javaBuiltInClasses' ignite-on-enter=btnVisibleAndSave ignite-on-escape='tableReset()')
+                input.form-control(id=valFocusId type='text' ng-model=valModel placeholder=valPlaceholder bs-typeahead container='body' ignite-retain-selection data-min-length='1' bs-options='javaClass for javaClass in javaBuiltInClasses' ignite-on-enter=btnVisibleAndSave ignite-on-escape='tableReset(false)')
             else
-                input.form-control(id=valFocusId type='text' ng-model=valModel placeholder=valPlaceholder ignite-on-enter=btnVisibleAndSave ignite-on-escape='tableReset()')
+                input.form-control(id=valFocusId type='text' ng-model=valModel placeholder=valPlaceholder ignite-on-enter=btnVisibleAndSave ignite-on-escape='tableReset(false)')
 
 //- Mixin for DB dialect.
 mixin dialect(lbl, model, name, required, tipTitle, genericDialectName, placeholder)
@@ -553,3 +551,13 @@ mixin dialect(lbl, model, name, required, tipTitle, genericDialectName, placehol
             <li>PostgreSQL</li>\
             <li>H2 database</li>\
         </ul>')
+
+//- Mixin for show/hide links.
+mixin showHideLink(name, text)
+    span(ng-init='__ = {};')
+        a.customize(ng-show='__.#{name}' ng-click='__.#{name} = false') Hide #{text}
+        a.customize(ng-hide='__.#{name}' ng-click='__.#{name} = true; ui.loadPanel("#{name}");') Show #{text}
+        div(ng-if='ui.isPanelLoaded("#{name}")')
+            .panel-details(ng-show='__.#{name}')
+                if block
+                    block

http://git-wip-us.apache.org/repos/asf/ignite/blob/bf330251/modules/web-console/frontend/app/modules/configuration/generator/Beans.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/configuration/generator/Beans.js b/modules/web-console/frontend/app/modules/configuration/generator/Beans.js
index 546f38b..2750626 100644
--- a/modules/web-console/frontend/app/modules/configuration/generator/Beans.js
+++ b/modules/web-console/frontend/app/modules/configuration/generator/Beans.js
@@ -221,6 +221,12 @@ export class Bean extends EmptyBean {
         return this;
     }
 
+    propertyInt(name, value, hint) {
+        this.properties.push({clsName: 'PROPERTY_INT', name, value, hint});
+
+        return this;
+    }
+
     stringProperty(model, name = model, mapper) {
         return this._property(this.properties, 'java.lang.String', model, name, _.nonEmpty, mapper);
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/bf330251/modules/web-console/frontend/app/modules/configuration/generator/ConfigurationGenerator.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/configuration/generator/ConfigurationGenerator.js b/modules/web-console/frontend/app/modules/configuration/generator/ConfigurationGenerator.js
index 869e3df..5887832 100644
--- a/modules/web-console/frontend/app/modules/configuration/generator/ConfigurationGenerator.js
+++ b/modules/web-console/frontend/app/modules/configuration/generator/ConfigurationGenerator.js
@@ -103,9 +103,9 @@ export default ['JavaTypes', 'igniteClusterDefaults', 'igniteCacheDefaults', 'ig
                 case 'DB2':
                     dsBean = new Bean('com.ibm.db2.jcc.DB2DataSource', id, {})
                         .property('serverName', `${id}.jdbc.server_name`, 'YOUR_DATABASE_SERVER_NAME')
-                        .property('portNumber', `${id}.jdbc.port_number`, 'YOUR_JDBC_PORT_NUMBER')
-                        .property('databaseName', `${id}.jdbc.database_name`, 'YOUR_JDBC_DRIVER_TYPE')
-                        .property('driverType', `${id}.jdbc.driver_type`, 'YOUR_DATABASE_NAME');
+                        .propertyInt('portNumber', `${id}.jdbc.port_number`, 'YOUR_JDBC_PORT_NUMBER')
+                        .property('databaseName', `${id}.jdbc.database_name`, 'YOUR_DATABASE_NAME')
+                        .propertyInt('driverType', `${id}.jdbc.driver_type`, 'YOUR_JDBC_DRIVER_TYPE');
 
                     break;
                 case 'SQLServer':
@@ -234,12 +234,14 @@ export default ['JavaTypes', 'igniteClusterDefaults', 'igniteCacheDefaults', 'ig
                     ipFinder.emptyBeanProperty('curator')
                         .stringProperty('zkConnectionString');
 
-                    if (_.get(src, 'retryPolicy.kind')) {
+                    const kind = _.get(src, 'retryPolicy.kind');
+
+                    if (kind) {
                         const policy = src.retryPolicy;
 
                         let retryPolicyBean;
 
-                        switch (policy.kind) {
+                        switch (kind) {
                             case 'ExponentialBackoff':
                                 retryPolicyBean = new Bean('org.apache.curator.retry.ExponentialBackoffRetry', null,
                                     policy.ExponentialBackoff, dflt.ExponentialBackoff)
@@ -289,6 +291,7 @@ export default ['JavaTypes', 'igniteClusterDefaults', 'igniteCacheDefaults', 'ig
 
                                 break;
                             default:
+                                // No-op.
                         }
 
                         if (retryPolicyBean)
@@ -301,6 +304,7 @@ export default ['JavaTypes', 'igniteClusterDefaults', 'igniteCacheDefaults', 'ig
 
                     break;
                 default:
+                    // No-op.
             }
 
             if (ipFinder)
@@ -425,10 +429,10 @@ export default ['JavaTypes', 'igniteClusterDefaults', 'igniteCacheDefaults', 'ig
         // Generate checkpoint configurations.
         static clusterCheckpoint(cluster, caches, cfg = this.igniteConfigurationBean()) {
             const cfgs = _.filter(_.map(cluster.checkpointSpi, (spi) => {
-                switch (spi.kind) {
+                switch (_.get(spi, 'kind')) {
                     case 'FS':
                         const fsBean = new Bean('org.apache.ignite.spi.checkpoint.sharedfs.SharedFsCheckpointSpi',
-                            'checkpointSpi', spi.FS);
+                            'checkpointSpiFs', spi.FS);
 
                         fsBean.collectionProperty('directoryPaths', 'directoryPaths', _.get(spi, 'FS.directoryPaths'))
                             .emptyBeanProperty('checkpointListener');
@@ -437,9 +441,11 @@ export default ['JavaTypes', 'igniteClusterDefaults', 'igniteCacheDefaults', 'ig
 
                     case 'Cache':
                         const cacheBean = new Bean('org.apache.ignite.spi.checkpoint.cache.CacheCheckpointSpi',
-                            'checkpointSpi', spi.Cache);
+                            'checkpointSpiCache', spi.Cache);
 
-                        const cache = _.find(caches, (c) => c._id === _.get(spi, 'Cache.cache') || c.cache._id === _.get(spi, 'Cache.cache'));
+                        const curCache = _.get(spi, 'Cache.cache');
+
+                        const cache = _.find(caches, (c) => curCache && (c._id === curCache || _.get(c, 'cache._id') === curCache));
 
                         if (cache)
                             cacheBean.prop('java.lang.String', 'cacheName', cache.name || cache.cache.name);
@@ -451,7 +457,7 @@ export default ['JavaTypes', 'igniteClusterDefaults', 'igniteCacheDefaults', 'ig
 
                     case 'S3':
                         const s3Bean = new Bean('org.apache.ignite.spi.checkpoint.s3.S3CheckpointSpi',
-                            'checkpointSpi', spi.S3, clusterDflts.checkpointSpi.S3);
+                            'checkpointSpiS3', spi.S3, clusterDflts.checkpointSpi.S3);
 
                         let credentialsBean = null;
 
@@ -459,8 +465,8 @@ export default ['JavaTypes', 'igniteClusterDefaults', 'igniteCacheDefaults', 'ig
                             case 'Basic':
                                 credentialsBean = new Bean('com.amazonaws.auth.BasicAWSCredentials', 'awsCredentials', {});
 
-                                credentialsBean.constructorArgument('PROPERTY', 'checkpoint.s3.credentials.accessKey')
-                                    .constructorArgument('PROPERTY', 'checkpoint.s3.credentials.secretKey');
+                                credentialsBean.propertyConstructorArgument('checkpoint.s3.credentials.accessKey', 'YOUR_S3_ACCESS_KEY')
+                                    .propertyConstructorArgument('checkpoint.s3.credentials.secretKey', 'YOUR_S3_SECRET_KEY');
 
                                 break;
 
@@ -645,7 +651,7 @@ export default ['JavaTypes', 'igniteClusterDefaults', 'igniteCacheDefaults', 'ig
 
                     case 'JDBC':
                         const jdbcBean = new Bean('org.apache.ignite.spi.checkpoint.jdbc.JdbcCheckpointSpi',
-                            'checkpointSpi', spi.JDBC, clusterDflts.checkpointSpi.JDBC);
+                            'checkpointSpiJdbc', spi.JDBC, clusterDflts.checkpointSpi.JDBC);
 
                         const id = jdbcBean.valueOf('dataSourceBean');
                         const dialect = _.get(spi.JDBC, 'dialect');
@@ -673,7 +679,7 @@ export default ['JavaTypes', 'igniteClusterDefaults', 'igniteCacheDefaults', 'ig
                         const clsName = _.get(spi, 'Custom.className');
 
                         if (clsName)
-                            return new Bean(clsName, 'checkpointSpi', spi.Cache);
+                            return new Bean(clsName, 'checkpointSpiCustom', spi.Cache);
 
                         return null;
 
@@ -691,7 +697,7 @@ export default ['JavaTypes', 'igniteClusterDefaults', 'igniteCacheDefaults', 'ig
         static clusterCollision(collision, cfg = this.igniteConfigurationBean()) {
             let colSpi;
 
-            switch (collision.kind) {
+            switch (_.get(collision, 'kind')) {
                 case 'JobStealing':
                     colSpi = new Bean('org.apache.ignite.spi.collision.jobstealing.JobStealingCollisionSpi',
                         'colSpi', collision.JobStealing, clusterDflts.collision.JobStealing);
@@ -727,18 +733,16 @@ export default ['JavaTypes', 'igniteClusterDefaults', 'igniteCacheDefaults', 'ig
 
                     break;
                 case 'Custom':
-                    colSpi = new Bean(collision.Custom.class,
-                        'colSpi', collision.PriorityQueue, clusterDflts.collision.PriorityQueue);
+                    if (_.nonNil(_.get(collision, 'Custom.class')))
+                        colSpi = new EmptyBean(collision.Custom.class);
 
                     break;
                 default:
                     return cfg;
             }
 
-            if (colSpi.isEmpty())
-                return cfg;
-
-            cfg.beanProperty('collisionSpi', colSpi);
+            if (_.nonNil(colSpi))
+                cfg.beanProperty('collisionSpi', colSpi);
 
             return cfg;
         }
@@ -907,7 +911,7 @@ export default ['JavaTypes', 'igniteClusterDefaults', 'igniteCacheDefaults', 'ig
             _.forEach(cluster.failoverSpi, (spi) => {
                 let failoverSpi;
 
-                switch (spi.kind) {
+                switch (_.get(spi, 'kind')) {
                     case 'JobStealing':
                         failoverSpi = new Bean('org.apache.ignite.spi.failover.jobstealing.JobStealingFailoverSpi',
                             'failoverSpi', spi.JobStealing, clusterDflts.failoverSpi.JobStealing);
@@ -955,26 +959,25 @@ export default ['JavaTypes', 'igniteClusterDefaults', 'igniteCacheDefaults', 'ig
             _.forEach(cluster.loadBalancingSpi, (spi) => {
                 let loadBalancingSpi;
 
-                switch (spi.kind) {
+                switch (_.get(spi, 'kind')) {
                     case 'RoundRobin':
-                        loadBalancingSpi = new Bean('org.apache.ignite.spi.loadbalancing.roundrobin.RoundRobinLoadBalancingSpi', 'loadBalancingSpi', spi.RoundRobin, clusterDflts.loadBalancingSpi.RoundRobin);
+                        loadBalancingSpi = new Bean('org.apache.ignite.spi.loadbalancing.roundrobin.RoundRobinLoadBalancingSpi', 'loadBalancingSpiRR', spi.RoundRobin, clusterDflts.loadBalancingSpi.RoundRobin);
 
                         loadBalancingSpi.boolProperty('perTask');
 
                         break;
                     case 'Adaptive':
-                        loadBalancingSpi = new Bean('org.apache.ignite.spi.loadbalancing.adaptive.AdaptiveLoadBalancingSpi', 'loadBalancingSpi', spi.Adaptive);
+                        loadBalancingSpi = new Bean('org.apache.ignite.spi.loadbalancing.adaptive.AdaptiveLoadBalancingSpi', 'loadBalancingSpiAdaptive', spi.Adaptive);
 
                         let probeBean;
 
-                        switch (spi.Adaptive.loadProbe.kind) {
+                        switch (_.get(spi, 'Adaptive.loadProbe.kind')) {
                             case 'Job':
                                 probeBean = new Bean('org.apache.ignite.spi.loadbalancing.adaptive.AdaptiveJobCountLoadProbe', 'jobProbe', spi.Adaptive.loadProbe.Job, clusterDflts.loadBalancingSpi.Adaptive.loadProbe.Job);
 
                                 probeBean.boolProperty('useAverage');
 
                                 break;
-
                             case 'CPU':
                                 probeBean = new Bean('org.apache.ignite.spi.loadbalancing.adaptive.AdaptiveCpuLoadProbe', 'cpuProbe', spi.Adaptive.loadProbe.CPU, clusterDflts.loadBalancingSpi.Adaptive.loadProbe.CPU);
 
@@ -983,14 +986,12 @@ export default ['JavaTypes', 'igniteClusterDefaults', 'igniteCacheDefaults', 'ig
                                     .intProperty('processorCoefficient');
 
                                 break;
-
                             case 'ProcessingTime':
                                 probeBean = new Bean('org.apache.ignite.spi.loadbalancing.adaptive.AdaptiveProcessingTimeLoadProbe', 'timeProbe', spi.Adaptive.loadProbe.ProcessingTime, clusterDflts.loadBalancingSpi.Adaptive.loadProbe.ProcessingTime);
 
                                 probeBean.boolProperty('useAverage');
 
                                 break;
-
                             case 'Custom':
                                 const className = _.get(spi, 'Adaptive.loadProbe.Custom.className');
 
@@ -998,7 +999,6 @@ export default ['JavaTypes', 'igniteClusterDefaults', 'igniteCacheDefaults', 'ig
                                     probeBean = new Bean(className, 'probe', spi.Adaptive.loadProbe.Job.Custom);
 
                                 break;
-
                             default:
                                 // No-op.
                         }
@@ -1008,7 +1008,7 @@ export default ['JavaTypes', 'igniteClusterDefaults', 'igniteCacheDefaults', 'ig
 
                         break;
                     case 'WeightedRandom':
-                        loadBalancingSpi = new Bean('org.apache.ignite.spi.loadbalancing.weightedrandom.WeightedRandomLoadBalancingSpi', 'loadBalancingSpi', spi.WeightedRandom, clusterDflts.loadBalancingSpi.WeightedRandom);
+                        loadBalancingSpi = new Bean('org.apache.ignite.spi.loadbalancing.weightedrandom.WeightedRandomLoadBalancingSpi', 'loadBalancingSpiRandom', spi.WeightedRandom, clusterDflts.loadBalancingSpi.WeightedRandom);
 
                         loadBalancingSpi.intProperty('nodeWeight')
                             .boolProperty('useWeights');
@@ -1018,7 +1018,7 @@ export default ['JavaTypes', 'igniteClusterDefaults', 'igniteCacheDefaults', 'ig
                         const className = _.get(spi, 'Custom.className');
 
                         if (className)
-                            loadBalancingSpi = new Bean(className, 'loadBalancingSpi', spi.Custom);
+                            loadBalancingSpi = new Bean(className, 'loadBalancingSpiCustom', spi.Custom);
 
                         break;
                     default:
@@ -1030,19 +1030,16 @@ export default ['JavaTypes', 'igniteClusterDefaults', 'igniteCacheDefaults', 'ig
             });
 
             if (spis.length)
-                cfg.arrayProperty('loadBalancingSpi', 'loadBalancingSpi', spis, 'org.apache.ignite.spi.loadbalancing.LoadBalancingSpi');
+                cfg.varArgProperty('loadBalancingSpi', 'loadBalancingSpi', spis, 'org.apache.ignite.spi.loadbalancing.LoadBalancingSpi');
 
             return cfg;
         }
 
         // Generate logger group.
         static clusterLogger(logger, cfg = this.igniteConfigurationBean()) {
-            if (_.isNil(logger))
-                return cfg;
-
             let loggerBean;
 
-            switch (logger.kind) {
+            switch (_.get(logger, 'kind')) {
                 case 'Log4j':
                     if (logger.Log4j && (logger.Log4j.mode === 'Default' || logger.Log4j.mode === 'Path' && _.nonEmpty(logger.Log4j.path))) {
                         loggerBean = new Bean('org.apache.ignite.logger.log4j.Log4JLogger',
@@ -1087,6 +1084,7 @@ export default ['JavaTypes', 'igniteClusterDefaults', 'igniteCacheDefaults', 'ig
 
                     break;
                 default:
+                    return cfg;
             }
 
             if (loggerBean)
@@ -1116,34 +1114,34 @@ export default ['JavaTypes', 'igniteClusterDefaults', 'igniteCacheDefaults', 'ig
 
         // Generate marshaller group.
         static clusterMarshaller(cluster, cfg = this.igniteConfigurationBean(cluster)) {
-            const marshaller = cluster.marshaller;
-
-            if (marshaller && marshaller.kind) {
-                let bean;
+            const kind = _.get(cluster.marshaller, 'kind');
+            const settings = _.get(cluster.marshaller, kind);
 
-                switch (marshaller.kind) {
-                    case 'OptimizedMarshaller':
-                        bean = new Bean('org.apache.ignite.marshaller.optimized.OptimizedMarshaller', 'marshaller',
-                            marshaller[marshaller.kind]);
+            if (_.isNil(settings))
+                return cfg;
 
-                        bean.intProperty('poolSize')
-                            .intProperty('requireSerializable');
+            let bean;
 
-                        break;
+            switch (kind) {
+                case 'OptimizedMarshaller':
+                    bean = new Bean('org.apache.ignite.marshaller.optimized.OptimizedMarshaller', 'marshaller', settings)
+                        .intProperty('poolSize')
+                        .intProperty('requireSerializable');
 
-                    case 'JdkMarshaller':
-                        bean = new Bean('org.apache.ignite.marshaller.jdk.JdkMarshaller', 'marshaller',
-                            marshaller[marshaller.kind]);
+                    break;
 
-                        break;
+                case 'JdkMarshaller':
+                    bean = new Bean('org.apache.ignite.marshaller.jdk.JdkMarshaller', 'marshaller', settings);
 
-                    default:
-                }
+                    break;
 
-                if (bean)
-                    cfg.beanProperty('marshaller', bean);
+                default:
+                    // No-op.
             }
 
+            if (bean)
+                cfg.beanProperty('marshaller', bean);
+
             cfg.intProperty('marshalLocalJobs')
                 .intProperty('marshallerCacheKeepAliveTime')
                 .intProperty('marshallerCacheThreadPoolSize', 'marshallerCachePoolSize');
@@ -1214,7 +1212,7 @@ export default ['JavaTypes', 'igniteClusterDefaults', 'igniteCacheDefaults', 'ig
 
         // Generate swap group.
         static clusterSwap(cluster, cfg = this.igniteConfigurationBean(cluster)) {
-            if (cluster.swapSpaceSpi && cluster.swapSpaceSpi.kind === 'FileSwapSpaceSpi') {
+            if (_.get(cluster.swapSpaceSpi, 'kind') === 'FileSwapSpaceSpi') {
                 const bean = new Bean('org.apache.ignite.spi.swapspace.file.FileSwapSpaceSpi', 'swapSpaceSpi',
                     cluster.swapSpaceSpi.FileSwapSpaceSpi);
 
@@ -1451,14 +1449,20 @@ export default ['JavaTypes', 'igniteClusterDefaults', 'igniteCacheDefaults', 'ig
                 switch (kind) {
                     case 'CacheJdbcPojoStoreFactory':
                         bean = new Bean('org.apache.ignite.cache.store.jdbc.CacheJdbcPojoStoreFactory', 'cacheStoreFactory',
-                            storeFactory);
+                            storeFactory, cacheDflts.cacheStoreFactory.CacheJdbcPojoStoreFactory);
 
                         const jdbcId = bean.valueOf('dataSourceBean');
 
                         bean.dataSource(jdbcId, 'dataSourceBean', this.dataSourceBean(jdbcId, storeFactory.dialect))
                             .beanProperty('dialect', new EmptyBean(this.dialectClsName(storeFactory.dialect)));
 
-                        bean.boolProperty('sqlEscapeAll');
+                        bean.intProperty('batchSize')
+                            .intProperty('maximumPoolSize')
+                            .intProperty('maximumWriteAttempts')
+                            .intProperty('parallelLoadCacheMinimumThreshold')
+                            .emptyBeanProperty('hasher')
+                            .emptyBeanProperty('transformer')
+                            .boolProperty('sqlEscapeAll');
 
                         const setType = (typeBean, propName) => {
                             if (JavaTypes.nonBuiltInClass(typeBean.valueOf(propName)))
@@ -1555,31 +1559,35 @@ export default ['JavaTypes', 'igniteClusterDefaults', 'igniteCacheDefaults', 'ig
         static cacheNodeFilter(cache, igfss, ccfg = this.cacheConfigurationBean(cache)) {
             const kind = _.get(cache, 'nodeFilter.kind');
 
-            if (kind && cache.nodeFilter[kind]) {
-                let bean = null;
+            const settings = _.get(cache.nodeFilter, kind);
 
-                switch (kind) {
-                    case 'IGFS':
-                        const foundIgfs = _.find(igfss, (igfs) => igfs._id === cache.nodeFilter.IGFS.igfs);
+            if (_.isNil(settings))
+                return ccfg;
 
-                        if (foundIgfs) {
-                            bean = new Bean('org.apache.ignite.internal.processors.igfs.IgfsNodePredicate', 'nodeFilter', foundIgfs)
-                                .stringConstructorArgument('name');
-                        }
+            let bean = null;
 
-                        break;
-                    case 'Custom':
-                        bean = new Bean(cache.nodeFilter.Custom.className, 'nodeFilter');
+            switch (kind) {
+                case 'IGFS':
+                    const foundIgfs = _.find(igfss, {_id: settings.igfs});
 
-                        break;
-                    default:
-                        return ccfg;
-                }
+                    if (foundIgfs) {
+                        bean = new Bean('org.apache.ignite.internal.processors.igfs.IgfsNodePredicate', 'nodeFilter', foundIgfs)
+                            .stringConstructorArgument('name');
+                    }
 
-                if (bean)
-                    ccfg.beanProperty('nodeFilter', bean);
+                    break;
+                case 'Custom':
+                    if (_.nonEmpty(settings.className))
+                        bean = new EmptyBean(settings.className);
+
+                    break;
+                default:
+                    // No-op.
             }
 
+            if (bean)
+                ccfg.beanProperty('nodeFilter', bean);
+
             return ccfg;
         }
 
@@ -1733,7 +1741,8 @@ export default ['JavaTypes', 'igniteClusterDefaults', 'igniteCacheDefaults', 'ig
                     .pathProperty('tokenDirectoryPath')
                     .intProperty('threadCount');
 
-                cfg.beanProperty('ipcEndpointConfiguration', bean);
+                if (bean.nonEmpty())
+                    cfg.beanProperty('ipcEndpointConfiguration', bean);
             }
 
             return cfg;

http://git-wip-us.apache.org/repos/asf/ignite/blob/bf330251/modules/web-console/frontend/app/modules/configuration/generator/JavaTransformer.service.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/configuration/generator/JavaTransformer.service.js b/modules/web-console/frontend/app/modules/configuration/generator/JavaTransformer.service.js
index 64d43d8..b123ab5 100644
--- a/modules/web-console/frontend/app/modules/configuration/generator/JavaTransformer.service.js
+++ b/modules/web-console/frontend/app/modules/configuration/generator/JavaTransformer.service.js
@@ -395,17 +395,19 @@ export default ['JavaTypes', 'igniteEventGroups', 'IgniteConfigurationGenerator'
                         return `${item}L`;
                     case 'java.io.Serializable':
                     case 'java.lang.String':
-                        return `"${item}"`;
+                        return `"${item.replace(/\\/g, '\\\\').replace(/"/g, '\\"')}"`;
                     case 'PATH':
                         return `"${item.replace(/\\/g, '\\\\')}"`;
                     case 'java.lang.Class':
                         return `${JavaTypes.shortClassName(item)}.class`;
                     case 'java.util.UUID':
                         return `UUID.fromString("${item}")`;
-                    case 'PROPERTY_CHAR':
-                        return `props.getProperty("${item}").toCharArray()`;
                     case 'PROPERTY':
                         return `props.getProperty("${item}")`;
+                    case 'PROPERTY_CHAR':
+                        return `props.getProperty("${item}").toCharArray()`;
+                    case 'PROPERTY_INT':
+                        return `Integer.parseInt(props.getProperty("${item}"))`;
                     default:
                         if (this._isBean(clsName)) {
                             if (item.isComplex())
@@ -744,6 +746,7 @@ export default ['JavaTypes', 'igniteEventGroups', 'IgniteConfigurationGenerator'
                         break;
                     case 'PROPERTY':
                     case 'PROPERTY_CHAR':
+                    case 'PROPERTY_INT':
                         imports.push('java.io.InputStream', 'java.util.Properties');
 
                         break;
@@ -1075,7 +1078,7 @@ export default ['JavaTypes', 'igniteEventGroups', 'IgniteConfigurationGenerator'
                 sb.startBlock(`public ${clsName}(${arg(_.head(fields))}${fields.length === 1 ? ') {' : ','}`);
 
                 _.forEach(_.tail(fields), (field, idx) => {
-                    sb.append(`${arg(field)}${idx !== fields.length - 1 ? ',' : ') {'}`);
+                    sb.append(`${arg(field)}${idx !== fields.length - 2 ? ',' : ') {'}`);
                 });
 
                 _.forEach(fields, (field) => sb.append(`this.${field.javaFieldName} = ${field.javaFieldName};`));
@@ -1262,8 +1265,8 @@ export default ['JavaTypes', 'igniteEventGroups', 'IgniteConfigurationGenerator'
                         const valueFields = _.clone(domain.valueFields);
 
                         if (includeKeyFields) {
-                            _.forEach(domain.keyFields, ({fld}) => {
-                                if (!_.find(valueFields, {name: fld.name}))
+                            _.forEach(domain.keyFields, (fld) => {
+                                if (!_.find(valueFields, {javaFieldName: fld.javaFieldName}))
                                     valueFields.push(fld);
                             });
                         }

http://git-wip-us.apache.org/repos/asf/ignite/blob/bf330251/modules/web-console/frontend/app/modules/configuration/generator/Properties.service.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/configuration/generator/Properties.service.js b/modules/web-console/frontend/app/modules/configuration/generator/Properties.service.js
index 07f8dff..49b4aa6 100644
--- a/modules/web-console/frontend/app/modules/configuration/generator/Properties.service.js
+++ b/modules/web-console/frontend/app/modules/configuration/generator/Properties.service.js
@@ -24,6 +24,23 @@ export default class PropertiesGenerator {
     _collectProperties(bean) {
         const props = [];
 
+        _.forEach(bean.arguments, (arg) => {
+            switch (arg.clsName) {
+                case 'BEAN':
+                    props.push(...this._collectProperties(arg.value));
+
+                    break;
+                case 'PROPERTY':
+                case 'PROPERTY_CHAR':
+                case 'PROPERTY_INT':
+                    props.push(`${arg.value}=${arg.hint}`);
+
+                    break;
+                default:
+                    // No-op.
+            }
+        });
+
         _.forEach(bean.properties, (prop) => {
             switch (prop.clsName) {
                 case 'DATA_SOURCE':
@@ -37,6 +54,7 @@ export default class PropertiesGenerator {
                     break;
                 case 'PROPERTY':
                 case 'PROPERTY_CHAR':
+                case 'PROPERTY_INT':
                     props.push(`${prop.value}=${prop.hint}`);
 
                     break;
@@ -51,6 +69,7 @@ export default class PropertiesGenerator {
 
                     break;
                 default:
+                    // No-op.
             }
         });
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/bf330251/modules/web-console/frontend/app/modules/configuration/generator/SpringTransformer.service.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/configuration/generator/SpringTransformer.service.js b/modules/web-console/frontend/app/modules/configuration/generator/SpringTransformer.service.js
index 91a85fa..73df25e 100644
--- a/modules/web-console/frontend/app/modules/configuration/generator/SpringTransformer.service.js
+++ b/modules/web-console/frontend/app/modules/configuration/generator/SpringTransformer.service.js
@@ -20,6 +20,14 @@ import _ from 'lodash';
 import AbstractTransformer from './AbstractTransformer';
 import StringBuilder from './StringBuilder';
 
+const escapeXml = (str) => {
+    return str.replace(/&/g, '&amp;')
+        .replace(/"/g, '&quot;')
+        .replace(/'/g, '&apos;')
+        .replace(/>/g, '&gt;')
+        .replace(/</g, '&lt;');
+};
+
 export default ['JavaTypes', 'igniteEventGroups', 'IgniteConfigurationGenerator', (JavaTypes, eventGroups, generator) => {
     return class SpringTransformer extends AbstractTransformer {
         static generator = generator;
@@ -84,11 +92,14 @@ export default ['JavaTypes', 'igniteEventGroups', 'IgniteConfigurationGenerator'
                 switch (clsName) {
                     case 'PROPERTY':
                     case 'PROPERTY_CHAR':
+                    case 'PROPERTY_INT':
                         return `\${${item}}`;
                     case 'java.lang.Class':
                         return JavaTypes.fullClassName(item);
                     case 'long':
                         return `${item}L`;
+                    case 'java.lang.String':
+                        return escapeXml(item);
                     default:
                         return item;
                 }
@@ -99,9 +110,9 @@ export default ['JavaTypes', 'igniteEventGroups', 'IgniteConfigurationGenerator'
             return JavaTypes.nonBuiltInClass(clsName) && JavaTypes.nonEnum(clsName) && _.includes(clsName, '.');
         }
 
-        static _setCollection(sb, prop, tag) {
+        static _setCollection(sb, prop) {
             sb.startBlock(`<property name="${prop.name}">`);
-            sb.startBlock(`<${tag}>`);
+            sb.startBlock('<list>');
 
             _.forEach(prop.items, (item, idx) => {
                 if (this._isBean(prop.typeClsName)) {
@@ -114,7 +125,7 @@ export default ['JavaTypes', 'igniteEventGroups', 'IgniteConfigurationGenerator'
                     sb.append(`<value>${item}</value>`);
             });
 
-            sb.endBlock(`</${tag}>`);
+            sb.endBlock('</list>');
             sb.endBlock('</property>');
         }
 
@@ -201,11 +212,8 @@ export default ['JavaTypes', 'igniteEventGroups', 'IgniteConfigurationGenerator'
 
                         break;
                     case 'ARRAY':
-                        this._setCollection(sb, prop, 'array');
-
-                        break;
                     case 'COLLECTION':
-                        this._setCollection(sb, prop, 'list');
+                        this._setCollection(sb, prop);
 
                         break;
                     case 'MAP':

http://git-wip-us.apache.org/repos/asf/ignite/blob/bf330251/modules/web-console/frontend/app/modules/configuration/generator/defaults/cache.provider.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/configuration/generator/defaults/cache.provider.js b/modules/web-console/frontend/app/modules/configuration/generator/defaults/cache.provider.js
index 5ff1e02..f50e493 100644
--- a/modules/web-console/frontend/app/modules/configuration/generator/defaults/cache.provider.js
+++ b/modules/web-console/frontend/app/modules/configuration/generator/defaults/cache.provider.js
@@ -37,6 +37,14 @@ const DFLT_CACHE = {
     sqlEscapeAll: false,
     storeKeepBinary: false,
     loadPreviousValue: false,
+    cacheStoreFactory: {
+        CacheJdbcPojoStoreFactory: {
+            batchSize: 512,
+            maximumWriteAttempts: 2,
+            parallelLoadCacheMinimumThreshold: 512,
+            sqlEscapeAll: false
+        }
+    },
     readThrough: false,
     writeThrough: false,
     writeBehindEnabled: false,

http://git-wip-us.apache.org/repos/asf/ignite/blob/bf330251/modules/web-console/frontend/app/modules/configuration/generator/defaults/cluster.provider.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/configuration/generator/defaults/cluster.provider.js b/modules/web-console/frontend/app/modules/configuration/generator/defaults/cluster.provider.js
index 1be4b70..726581d 100644
--- a/modules/web-console/frontend/app/modules/configuration/generator/defaults/cluster.provider.js
+++ b/modules/web-console/frontend/app/modules/configuration/generator/defaults/cluster.provider.js
@@ -167,7 +167,7 @@ const DFLT_CLUSTER = {
     logger: {
         Log4j: {
             level: {
-                clsName: 'org.apache.logging.log4j.Level'
+                clsName: 'org.apache.log4j.Level'
             }
         },
         Log4j2: {

http://git-wip-us.apache.org/repos/asf/ignite/blob/bf330251/modules/web-console/frontend/app/modules/form/field/tooltip.directive.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/form/field/tooltip.directive.js b/modules/web-console/frontend/app/modules/form/field/tooltip.directive.js
index 5005280..4f440a1 100644
--- a/modules/web-console/frontend/app/modules/form/field/tooltip.directive.js
+++ b/modules/web-console/frontend/app/modules/form/field/tooltip.directive.js
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-const template = '<i class="tipField fa fa-question-circle"></i>';
+const template = '<i class="tipField icon-help"></i>';
 
 export default ['igniteFormFieldTooltip', ['$tooltip', ($tooltip) => {
     const link = ($scope, $element, $attrs, [form, field], $transclude) => {

http://git-wip-us.apache.org/repos/asf/ignite/blob/bf330251/modules/web-console/frontend/app/modules/form/group/tooltip.directive.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/form/group/tooltip.directive.js b/modules/web-console/frontend/app/modules/form/group/tooltip.directive.js
index 3e470e1..6027765 100644
--- a/modules/web-console/frontend/app/modules/form/group/tooltip.directive.js
+++ b/modules/web-console/frontend/app/modules/form/group/tooltip.directive.js
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-const template = '<i class="group-legend-btn fa fa-question-circle"></i>';
+const template = '<i class="group-legend-btn icon-help"></i>';
 
 export default ['igniteFormGroupTooltip', ['$tooltip', ($tooltip) => {
     const link = ($scope, $element, $attrs, $ctrls, $transclude) => {

http://git-wip-us.apache.org/repos/asf/ignite/blob/bf330251/modules/web-console/frontend/app/modules/form/panel/field.directive.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/form/panel/field.directive.js b/modules/web-console/frontend/app/modules/form/panel/field.directive.js
index 5dc7b07..cf8101a 100644
--- a/modules/web-console/frontend/app/modules/form/panel/field.directive.js
+++ b/modules/web-console/frontend/app/modules/form/panel/field.directive.js
@@ -40,8 +40,8 @@ export default ['igniteFormPanelField', ['$parse', 'IgniteLegacyTable', ($parse,
         else
             saveDefault();
 
-        scope.tableReset = () => {
-            if (!LegacyTable.tableSaveAndReset())
+        scope.tableReset = (trySave) => {
+            if (trySave === false || !LegacyTable.tableSaveAndReset())
                 LegacyTable.tableReset();
         };
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/bf330251/modules/web-console/frontend/app/modules/sql/scan-filter-input.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/sql/scan-filter-input.jade b/modules/web-console/frontend/app/modules/sql/scan-filter-input.jade
index addc5f3..0396727 100644
--- a/modules/web-console/frontend/app/modules/sql/scan-filter-input.jade
+++ b/modules/web-console/frontend/app/modules/sql/scan-filter-input.jade
@@ -14,7 +14,7 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 
-include ../../helpers/jade/mixins.jade
+include /app/helpers/jade/mixins.jade
 
 .modal(tabindex='-1' role='dialog')
     .modal-dialog

http://git-wip-us.apache.org/repos/asf/ignite/blob/bf330251/modules/web-console/frontend/app/modules/sql/sql.controller.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/sql/sql.controller.js b/modules/web-console/frontend/app/modules/sql/sql.controller.js
index 0c2be01..4e6e372 100644
--- a/modules/web-console/frontend/app/modules/sql/sql.controller.js
+++ b/modules/web-console/frontend/app/modules/sql/sql.controller.js
@@ -1244,8 +1244,10 @@ export default ['$rootScope', '$scope', '$http', '$q', '$timeout', '$interval',
         };
 
         const _closeOldQuery = (paragraph) => {
-            if (paragraph.queryId)
-                return agentMonitor.queryClose(paragraph.resNodeId, paragraph.queryId);
+            const nid = paragraph.resNodeId;
+
+            if (paragraph.queryId && _.find($scope.caches, ({nodes}) => _.includes(nodes, nid)))
+                return agentMonitor.queryClose(nid, paragraph.queryId);
 
             return $q.when();
         };

http://git-wip-us.apache.org/repos/asf/ignite/blob/bf330251/modules/web-console/frontend/app/modules/states/configuration/caches/client-near-cache.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/states/configuration/caches/client-near-cache.jade b/modules/web-console/frontend/app/modules/states/configuration/caches/client-near-cache.jade
index 9d8ccbe..e3d1a81 100644
--- a/modules/web-console/frontend/app/modules/states/configuration/caches/client-near-cache.jade
+++ b/modules/web-console/frontend/app/modules/states/configuration/caches/client-near-cache.jade
@@ -14,7 +14,7 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 
-include ../../../../../app/helpers/jade/mixins.jade
+include /app/helpers/jade/mixins.jade
 
 -var form = 'clientNearCache'
 -var model = 'backupItem.clientNearConfiguration'

http://git-wip-us.apache.org/repos/asf/ignite/blob/bf330251/modules/web-console/frontend/app/modules/states/configuration/caches/concurrency.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/states/configuration/caches/concurrency.jade b/modules/web-console/frontend/app/modules/states/configuration/caches/concurrency.jade
index 37bd88d..ffcd568 100644
--- a/modules/web-console/frontend/app/modules/states/configuration/caches/concurrency.jade
+++ b/modules/web-console/frontend/app/modules/states/configuration/caches/concurrency.jade
@@ -14,7 +14,7 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 
-include ../../../../../app/helpers/jade/mixins.jade
+include /app/helpers/jade/mixins.jade
 
 -var form = 'concurrency'
 -var model = 'backupItem'

http://git-wip-us.apache.org/repos/asf/ignite/blob/bf330251/modules/web-console/frontend/app/modules/states/configuration/caches/general.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/states/configuration/caches/general.jade b/modules/web-console/frontend/app/modules/states/configuration/caches/general.jade
index e9ff143..14f3ab4 100644
--- a/modules/web-console/frontend/app/modules/states/configuration/caches/general.jade
+++ b/modules/web-console/frontend/app/modules/states/configuration/caches/general.jade
@@ -14,7 +14,7 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 
-include ../../../../../app/helpers/jade/mixins.jade
+include /app/helpers/jade/mixins.jade
 
 -var form = 'general'
 -var model = 'backupItem'

http://git-wip-us.apache.org/repos/asf/ignite/blob/bf330251/modules/web-console/frontend/app/modules/states/configuration/caches/memory.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/states/configuration/caches/memory.jade b/modules/web-console/frontend/app/modules/states/configuration/caches/memory.jade
index 724418f..f2d3e2b 100644
--- a/modules/web-console/frontend/app/modules/states/configuration/caches/memory.jade
+++ b/modules/web-console/frontend/app/modules/states/configuration/caches/memory.jade
@@ -14,7 +14,7 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 
-include ../../../../../app/helpers/jade/mixins.jade
+include /app/helpers/jade/mixins.jade
 
 -var form = 'memory'
 -var model = 'backupItem'

http://git-wip-us.apache.org/repos/asf/ignite/blob/bf330251/modules/web-console/frontend/app/modules/states/configuration/caches/near-cache-client.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/states/configuration/caches/near-cache-client.jade b/modules/web-console/frontend/app/modules/states/configuration/caches/near-cache-client.jade
index ba538c2..56f7e64 100644
--- a/modules/web-console/frontend/app/modules/states/configuration/caches/near-cache-client.jade
+++ b/modules/web-console/frontend/app/modules/states/configuration/caches/near-cache-client.jade
@@ -14,7 +14,7 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 
-include ../../../../../app/helpers/jade/mixins.jade
+include /app/helpers/jade/mixins.jade
 
 -var form = 'clientNearCache'
 -var model = 'backupItem'

http://git-wip-us.apache.org/repos/asf/ignite/blob/bf330251/modules/web-console/frontend/app/modules/states/configuration/caches/near-cache-server.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/states/configuration/caches/near-cache-server.jade b/modules/web-console/frontend/app/modules/states/configuration/caches/near-cache-server.jade
index a96b947..9895281 100644
--- a/modules/web-console/frontend/app/modules/states/configuration/caches/near-cache-server.jade
+++ b/modules/web-console/frontend/app/modules/states/configuration/caches/near-cache-server.jade
@@ -14,7 +14,7 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 
-include ../../../../../app/helpers/jade/mixins.jade
+include /app/helpers/jade/mixins.jade
 
 -var form = 'serverNearCache'
 -var model = 'backupItem'

http://git-wip-us.apache.org/repos/asf/ignite/blob/bf330251/modules/web-console/frontend/app/modules/states/configuration/caches/node-filter.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/states/configuration/caches/node-filter.jade b/modules/web-console/frontend/app/modules/states/configuration/caches/node-filter.jade
index eb74736..b34aba0 100644
--- a/modules/web-console/frontend/app/modules/states/configuration/caches/node-filter.jade
+++ b/modules/web-console/frontend/app/modules/states/configuration/caches/node-filter.jade
@@ -14,7 +14,7 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 
-include ../../../../../app/helpers/jade/mixins.jade
+include /app/helpers/jade/mixins.jade
 
 -var form = 'nodeFilter'
 -var model = 'backupItem'