Web console beta-5.

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

Branch: refs/heads/master
Commit: 087f6405d21ffe33181ced407ef67bd78583900d
Parents: b9d28ca
Author: Andrey Novikov <[email protected]>
Authored: Fri Oct 28 17:26:33 2016 +0700
Committer: Andrey Novikov <[email protected]>
Committed: Fri Oct 28 17:26:33 2016 +0700

----------------------------------------------------------------------
 modules/web-console/DEVNOTES.txt                |    2 +-
 modules/web-console/backend/app/agent.js        |   26 +-
 modules/web-console/backend/app/browser.js      |   14 +-
 modules/web-console/backend/app/mongo.js        |  207 +-
 .../backend/routes/demo/domains.json            |   15 +-
 modules/web-console/backend/services/agents.js  |    1 +
 modules/web-console/backend/services/auth.js    |    8 +-
 modules/web-console/backend/services/caches.js  |   14 +-
 .../web-console/backend/services/clusters.js    |   19 +-
 modules/web-console/backend/services/domains.js |   12 +-
 modules/web-console/backend/services/igfss.js   |   12 +-
 .../backend/test/unit/AuthService.test.js       |    4 +-
 .../backend/test/unit/CacheService.test.js      |  135 +-
 .../backend/test/unit/ClusterService.test.js    |  132 +-
 .../backend/test/unit/DomainService.test.js     |  144 +-
 .../backend/test/unit/IgfsService.test.js       |  122 +-
 modules/web-console/frontend/.eslintrc          |    6 +-
 modules/web-console/frontend/app/app.config.js  |   10 +
 modules/web-console/frontend/app/app.js         |   37 +-
 .../web-console/frontend/app/data/dialects.json |    9 +
 .../frontend/app/data/java-classes.json         |    4 +-
 .../frontend/app/decorator/tooltip.js           |   13 +-
 .../app/directives/on-focus-out.directive.js    |   37 +
 .../directives/restore-input-focus.directive.js |   24 +
 .../ui-ace-java/ui-ace-java.controller.js       |   78 +-
 .../ui-ace-java/ui-ace-java.directive.js        |  100 +-
 .../ui-ace-pojos/ui-ace-pojos.controller.js     |    2 +-
 .../ui-ace-pom/ui-ace-pom.controller.js         |    2 +-
 .../ui-ace-sharp/ui-ace-sharp.controller.js     |   32 +
 .../ui-ace-sharp/ui-ace-sharp.directive.js      |  133 +
 .../directives/ui-ace-sharp/ui-ace-sharp.jade   |   22 +
 .../ui-ace-spring/ui-ace-spring.controller.js   |   88 +
 .../ui-ace-spring/ui-ace-spring.directive.js    |   66 +
 .../directives/ui-ace-spring/ui-ace-spring.jade |   17 +
 .../ui-ace-xml/ui-ace-xml.controller.js         |   27 -
 .../ui-ace-xml/ui-ace-xml.directive.js          |  147 -
 .../app/directives/ui-ace-xml/ui-ace-xml.jade   |   17 -
 .../ui-grid-settings/ui-grid-settings.jade      |   33 +
 .../ui-grid-settings/ui-grid-settings.scss      |   38 +
 .../frontend/app/filters/default-name.filter.js |   21 +
 .../frontend/app/filters/hasPojo.filter.js      |    5 +-
 .../helpers/jade/form/form-field-feedback.jade  |    5 +-
 .../frontend/app/helpers/jade/mixins.jade       |  219 +-
 .../frontend/app/modules/agent/agent.module.js  |   10 +-
 .../modules/configuration/Version.service.js    |   82 +-
 .../configuration/configuration.module.js       |   30 +-
 .../generator/AbstractTransformer.js            |  341 ++
 .../modules/configuration/generator/Beans.js    |  379 ++
 .../generator/ConfigurationGenerator.js         | 1785 +++++++++
 .../configuration/generator/Java.service.js     |   21 -
 .../generator/JavaTransformer.service.js        | 1721 +++++++++
 .../generator/PlatformGenerator.js              |  522 +++
 .../configuration/generator/Pom.service.js      |  173 +-
 .../generator/Properties.service.js             |   74 +
 .../configuration/generator/Readme.service.js   |   79 +
 .../generator/SharpTransformer.service.js       |  243 ++
 .../generator/SpringTransformer.service.js      |  325 ++
 .../configuration/generator/StringBuilder.js    |   76 +
 .../configuration/generator/Xml.service.js      |   21 -
 .../defaults/cache.platform.provider.js         |   60 +
 .../generator/defaults/cache.provider.js        |  129 +
 .../defaults/cluster.platform.provider.js       |   49 +
 .../generator/defaults/cluster.provider.js      |  293 ++
 .../generator/defaults/igfs.provider.js         |   68 +
 .../configuration/generator/generator-common.js |  625 +++
 .../configuration/generator/generator-java.js   | 3617 ++++++++++++++++++
 .../generator/generator-optional.js             |   25 +
 .../configuration/generator/generator-spring.js | 2111 ++++++++++
 .../app/modules/form/field/input/select.scss    |   21 -
 .../app/modules/form/field/input/text.scss      |    1 -
 .../frontend/app/modules/form/form.module.js    |   10 +-
 .../app/modules/form/panel/revert.directive.js  |    4 +-
 .../modules/form/services/FormGUID.service.js   |   22 +
 .../validator/java-built-in-class.directive.js  |    6 +-
 .../form/validator/java-identifier.directive.js |    6 +-
 .../form/validator/java-keywords.directive.js   |   15 +-
 .../java-package-specified.directive.js         |    6 +-
 .../frontend/app/modules/nodes/Nodes.service.js |   69 +
 .../modules/nodes/nodes-dialog.controller.js    |   68 +
 .../app/modules/nodes/nodes-dialog.jade         |   35 +
 .../app/modules/nodes/nodes-dialog.scss         |   20 +
 .../frontend/app/modules/nodes/nodes.module.js  |   27 +
 .../frontend/app/modules/sql/sql.controller.js  |  269 +-
 .../app/modules/states/configuration.state.js   |    2 +-
 .../configuration/caches/client-near-cache.jade |   50 +
 .../states/configuration/caches/general.jade    |    3 +
 .../states/configuration/caches/memory.jade     |   14 +-
 .../configuration/caches/near-cache-client.jade |   51 +
 .../configuration/caches/near-cache-server.jade |   52 +
 .../configuration/caches/node-filter.jade       |   49 -
 .../states/configuration/caches/query.jade      |   30 +-
 .../states/configuration/caches/rebalance.jade  |    3 +-
 .../configuration/caches/server-near-cache.jade |   51 -
 .../states/configuration/caches/store.jade      |   84 +-
 .../states/configuration/clusters/atomic.jade   |    3 +-
 .../configuration/clusters/attributes.jade      |    4 +-
 .../states/configuration/clusters/binary.jade   |   28 +-
 .../configuration/clusters/cache-key-cfg.jade   |    9 +-
 .../configuration/clusters/checkpoint.jade      |   85 +
 .../configuration/clusters/checkpoint/fs.jade   |   66 +
 .../configuration/clusters/checkpoint/jdbc.jade |   45 +
 .../configuration/clusters/checkpoint/s3.jade   |  174 +
 .../configuration/clusters/collision.jade       |   13 +-
 .../clusters/collision/job-stealing.jade        |    2 +-
 .../configuration/clusters/communication.jade   |    3 +-
 .../configuration/clusters/connector.jade       |    3 +-
 .../configuration/clusters/deployment.jade      |    3 +-
 .../configuration/clusters/discovery.jade       |    3 +-
 .../states/configuration/clusters/events.jade   |   37 +-
 .../states/configuration/clusters/failover.jade |   19 +-
 .../states/configuration/clusters/general.jade  |    3 +
 .../clusters/general/discovery/zookeeper.jade   |    2 +
 .../states/configuration/clusters/igfs.jade     |    3 +-
 .../configuration/clusters/load-balancing.jade  |  104 +
 .../configuration/clusters/marshaller.jade      |    3 +-
 .../states/configuration/clusters/odbc.jade     |    3 +-
 .../states/configuration/clusters/ssl.jade      |    7 +-
 .../states/configuration/clusters/swap.jade     |    3 +-
 .../configuration/clusters/transactions.jade    |    6 +-
 .../states/configuration/domains/general.jade   |   12 +-
 .../states/configuration/domains/query.jade     |   40 +-
 .../states/configuration/domains/store.jade     |   15 +-
 .../states/configuration/igfs/general.jade      |    3 +
 .../modules/states/configuration/igfs/ipc.jade  |    2 +-
 .../modules/states/configuration/igfs/misc.jade |    4 +-
 .../states/configuration/igfs/secondary.jade    |    3 +-
 .../configuration/summary/summary.controller.js |  106 +-
 .../app/services/ErrorPopover.service.js        |    2 +-
 .../frontend/app/services/FormUtils.service.js  |    6 +-
 .../frontend/app/services/JavaTypes.service.js  |   70 +-
 .../app/services/LegacyTable.service.js         |   24 +-
 .../app/services/LegacyUtils.service.js         |  128 +-
 .../frontend/app/services/SqlTypes.service.js   |    6 +-
 modules/web-console/frontend/app/vendor.js      |    3 +-
 .../frontend/controllers/caches-controller.js   |  121 +-
 .../frontend/controllers/clusters-controller.js |  177 +-
 .../frontend/controllers/domains-controller.js  |  148 +-
 .../frontend/controllers/igfs-controller.js     |    6 +-
 .../frontend/generator/generator-common.js      |  625 ---
 .../frontend/generator/generator-java.js        | 3611 -----------------
 .../frontend/generator/generator-optional.js    |   25 -
 .../frontend/generator/generator-properties.js  |  175 -
 .../frontend/generator/generator-readme.js      |   85 -
 .../frontend/generator/generator-xml.js         | 2108 ----------
 .../frontend/gulpfile.babel.js/paths.js         |   31 +-
 .../frontend/gulpfile.babel.js/tasks/jade.js    |   21 +-
 .../frontend/gulpfile.babel.js/tasks/watch.js   |    6 +-
 .../gulpfile.babel.js/webpack/common.js         |    2 +-
 .../webpack/environments/development.js         |   17 +-
 .../webpack/environments/test.js                |   52 +
 .../frontend/gulpfile.babel.js/webpack/index.js |    4 +-
 modules/web-console/frontend/package.json       |   16 +-
 .../frontend/public/stylesheets/style.scss      |   75 +-
 .../frontend/test/karma.conf.babel.js           |   91 +
 modules/web-console/frontend/test/karma.conf.js |   98 +-
 .../frontend/test/unit/JavaTransformer.test.js  |   57 +
 .../frontend/test/unit/JavaTypes.test.js        |   23 +-
 .../frontend/test/unit/SharpTransformer.test.js |   55 +
 .../test/unit/SpringTransformer.test.js         |   57 +
 .../frontend/test/unit/SqlTypes.test.js         |   17 -
 .../frontend/test/unit/Version.test.js          |   82 +
 .../test/unit/defaultName.filter.test.js        |   38 +
 .../frontend/views/configuration/caches.jade    |    3 +-
 .../frontend/views/configuration/clusters.jade  |    3 +-
 .../views/configuration/domains-import.jade     |   14 +-
 .../summary-project-structure.jade              |    2 +-
 .../frontend/views/configuration/summary.jade   |   57 +-
 .../frontend/views/sql/cache-metadata.jade      |    2 +-
 .../frontend/views/sql/notebook-new.jade        |    4 +-
 modules/web-console/frontend/views/sql/sql.jade |   80 +-
 .../views/templates/agent-download.jade         |    6 +-
 .../frontend/views/templates/batch-confirm.jade |    4 +-
 .../frontend/views/templates/clone.jade         |    4 +-
 .../frontend/views/templates/confirm.jade       |    4 +-
 .../frontend/views/templates/demo-info.jade     |    4 +-
 .../views/templates/getting-started.jade        |    4 +-
 .../frontend/views/templates/message.jade       |    4 +-
 .../frontend/views/templates/select.jade        |    2 +-
 .../ignite/console/demo/AgentClusterDemo.java   |    2 +-
 179 files changed, 16544 insertions(+), 8419 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/087f6405/modules/web-console/DEVNOTES.txt
----------------------------------------------------------------------
diff --git a/modules/web-console/DEVNOTES.txt b/modules/web-console/DEVNOTES.txt
index cf2b650..85ec958 100644
--- a/modules/web-console/DEVNOTES.txt
+++ b/modules/web-console/DEVNOTES.txt
@@ -9,7 +9,7 @@ How to deploy locally:
  run "npm install --no-optional" for download backend dependencies.
 4. Change directory to '$IGNITE_HOME/modules/web-console/frontend' and
  run "npm install --no-optional" for download frontend dependencies.
-5. Build ignite-web-agent module follow instructions from 
'modules/web-agent/README.txt'.
+5. Build ignite-web-agent module follow instructions from 
'modules/web-console/web-agent/README.txt'.
 6. Copy ignite-web-agent-<version>.zip from 
'$IGNITE_HOME/modules/web-console/web-agent/target'
  to '$IGNITE_HOME/modules/web-console/backend/agent_dists' folder.
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/087f6405/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 aa06c84..6aa9a12 100644
--- a/modules/web-console/backend/app/agent.js
+++ b/modules/web-console/backend/app/agent.js
@@ -225,20 +225,32 @@ module.exports.factory = function(_, fs, path, JSZip, 
socketio, settings, mongo)
          * @param {String} nid Node id.
          * @param {String} cacheName Cache name.
          * @param {String} query Query.
+         * @param {Boolean} nonCollocatedJoins Flag whether to execute non 
collocated joins.
          * @param {Boolean} local Flag whether to execute query locally.
          * @param {int} pageSize Page size.
          * @returns {Promise}
          */
-        fieldsQuery(demo, nid, cacheName, query, local, pageSize) {
+        fieldsQuery(demo, nid, cacheName, query, nonCollocatedJoins, local, 
pageSize) {
             const cmd = new Command(demo, 'exe')
                 .addParam('name', 
'org.apache.ignite.internal.visor.compute.VisorGatewayTask')
                 .addParam('p1', nid)
-                .addParam('p2', 
'org.apache.ignite.internal.visor.query.VisorQueryTask')
-                .addParam('p3', 
'org.apache.ignite.internal.visor.query.VisorQueryArg')
-                .addParam('p4', cacheName)
-                .addParam('p5', query)
-                .addParam('p6', local)
-                .addParam('p7', pageSize);
+                .addParam('p2', 
'org.apache.ignite.internal.visor.query.VisorQueryTask');
+
+            if (nonCollocatedJoins) {
+                cmd.addParam('p3', 
'org.apache.ignite.internal.visor.query.VisorQueryArgV2')
+                    .addParam('p4', cacheName)
+                    .addParam('p5', query)
+                    .addParam('p6', true)
+                    .addParam('p7', local)
+                    .addParam('p8', pageSize);
+            }
+            else {
+                cmd.addParam('p3', 
'org.apache.ignite.internal.visor.query.VisorQueryArg')
+                    .addParam('p4', cacheName)
+                    .addParam('p5', query)
+                    .addParam('p6', local)
+                    .addParam('p7', pageSize);
+            }
 
             return this.executeRest(cmd);
         }

http://git-wip-us.apache.org/repos/asf/ignite/blob/087f6405/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 d3a673b..254851d 100644
--- a/modules/web-console/backend/app/browser.js
+++ b/modules/web-console/backend/app/browser.js
@@ -98,9 +98,9 @@ module.exports.factory = (_, socketio, agentMgr, configure) 
=> {
                 });
 
                 // Execute query on node and return first page to browser.
-                socket.on('node:query', (nid, cacheName, query, local, 
pageSize, cb) => {
+                socket.on('node:query', (nid, cacheName, query, 
distributedJoins, local, pageSize, cb) => {
                     agentMgr.findAgent(accountId())
-                        .then((agent) => agent.fieldsQuery(demo, nid, 
cacheName, query, local, pageSize))
+                        .then((agent) => agent.fieldsQuery(demo, nid, 
cacheName, query, distributedJoins, local, pageSize))
                         .then((res) => cb(null, res))
                         .catch((err) => cb(_errorToJson(err)));
                 });
@@ -114,13 +114,13 @@ module.exports.factory = (_, socketio, agentMgr, 
configure) => {
                 });
 
                 // Execute query on node and return full result to browser.
-                socket.on('node:query:getAll', (nid, cacheName, query, local, 
cb) => {
+                socket.on('node:query:getAll', (nid, cacheName, query, 
distributedJoins, local, cb) => {
                     // Set page size for query.
                     const pageSize = 1024;
 
                     agentMgr.findAgent(accountId())
                         .then((agent) => {
-                            const firstPage = agent.fieldsQuery(demo, nid, 
cacheName, query, local, pageSize)
+                            const firstPage = agent.fieldsQuery(demo, nid, 
cacheName, query, distributedJoins, local, pageSize)
                                 .then(({result}) => {
                                     if (result.key)
                                         return Promise.reject(result.key);
@@ -133,10 +133,10 @@ module.exports.factory = (_, socketio, agentMgr, 
configure) => {
                                     return acc;
 
                                 return agent.queryFetch(demo, 
acc.responseNodeId, acc.queryId, pageSize)
-                                    .then((res) => {
-                                        acc.rows = acc.rows.concat(res.rows);
+                                    .then(({result}) => {
+                                        acc.rows = 
acc.rows.concat(result.rows);
 
-                                        acc.hasMore = res.hasMore;
+                                        acc.hasMore = result.hasMore;
 
                                         return fetchResult(acc);
                                     });

http://git-wip-us.apache.org/repos/asf/ignite/blob/087f6405/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 ba7ed09..e12af2a 100644
--- a/modules/web-console/backend/app/mongo.js
+++ b/modules/web-console/backend/app/mongo.js
@@ -123,7 +123,7 @@ module.exports.factory = function(passportMongo, settings, 
pluginMongo, mongoose
             indexType: {type: String, enum: ['SORTED', 'FULLTEXT', 
'GEOSPATIAL']},
             fields: [{name: String, direction: Boolean}]
         }],
-        demo: Boolean
+        generatePojo: Boolean
     });
 
     DomainModelSchema.index({valueType: 1, space: 1}, {unique: true});
@@ -148,9 +148,6 @@ module.exports.factory = function(passportMongo, settings, 
pluginMongo, mongoose
             IGFS: {
                 igfs: {type: ObjectId, ref: 'Igfs'}
             },
-            OnNodes: {
-                nodeIds: [String]
-            },
             Custom: {
                 className: String
             }
@@ -199,7 +196,8 @@ module.exports.factory = function(passportMongo, settings, 
pluginMongo, mongoose
                 dialect: {
                     type: String,
                     enum: ['Generic', 'Oracle', 'DB2', 'SQLServer', 'MySQL', 
'PostgreSQL', 'H2']
-                }
+                },
+                sqlEscapeAll: Boolean
             },
             CacheJdbcBlobStoreFactory: {
                 connectVia: {type: String, enum: ['URL', 'DataSource']},
@@ -218,7 +216,7 @@ module.exports.factory = function(passportMongo, settings, 
pluginMongo, mongoose
                 deleteQuery: String
             },
             CacheHibernateBlobStoreFactory: {
-                hibernateProperties: [String]
+                hibernateProperties: [{name: String, value: String}]
             }
         },
         storeKeepBinary: Boolean,
@@ -248,8 +246,8 @@ module.exports.factory = function(passportMongo, settings, 
pluginMongo, mongoose
         readFromBackup: Boolean,
         copyOnRead: Boolean,
         maxConcurrentAsyncOperations: Number,
-        nearCacheEnabled: Boolean,
         nearConfiguration: {
+            enabled: Boolean,
             nearStartSize: Number,
             nearEvictionPolicy: {
                 kind: {type: String, enum: ['LRU', 'FIFO', 'SORTED']},
@@ -270,7 +268,28 @@ module.exports.factory = function(passportMongo, settings, 
pluginMongo, mongoose
                 }
             }
         },
-        demo: Boolean
+        clientNearConfiguration: {
+            enabled: Boolean,
+            nearStartSize: Number,
+            nearEvictionPolicy: {
+                kind: {type: String, enum: ['LRU', 'FIFO', 'SORTED']},
+                LRU: {
+                    batchSize: Number,
+                    maxMemorySize: Number,
+                    maxSize: Number
+                },
+                FIFO: {
+                    batchSize: Number,
+                    maxMemorySize: Number,
+                    maxSize: Number
+                },
+                SORTED: {
+                    batchSize: Number,
+                    maxMemorySize: Number,
+                    maxSize: Number
+                }
+            }
+        }
     });
 
     CacheSchema.index({name: 1, space: 1}, {unique: true});
@@ -370,7 +389,50 @@ module.exports.factory = function(passportMongo, settings, 
pluginMongo, mongoose
                 addresses: [String]
             },
             S3: {
-                bucketName: String
+                bucketName: String,
+                clientConfiguration: {
+                    protocol: {type: String, enum: ['HTTP', 'HTTPS']},
+                    maxConnections: Number,
+                    userAgent: String,
+                    localAddress: String,
+                    proxyHost: String,
+                    proxyPort: Number,
+                    proxyUsername: String,
+                    proxyDomain: String,
+                    proxyWorkstation: String,
+                    retryPolicy: {
+                        kind: {type: String, enum: ['Default', 
'DefaultMaxRetries', 'DynamoDB', 'DynamoDBMaxRetries', 'Custom', 
'CustomClass']},
+                        DefaultMaxRetries: {
+                            maxErrorRetry: Number
+                        },
+                        DynamoDBMaxRetries: {
+                            maxErrorRetry: Number
+                        },
+                        Custom: {
+                            retryCondition: String,
+                            backoffStrategy: String,
+                            maxErrorRetry: Number,
+                            honorMaxErrorRetryInClientConfig: Boolean
+                        },
+                        CustomClass: {
+                            className: String
+                        }
+                    },
+                    maxErrorRetry: Number,
+                    socketTimeout: Number,
+                    connectionTimeout: Number,
+                    requestTimeout: Number,
+                    useReaper: Boolean,
+                    useGzip: Boolean,
+                    signerOverride: String,
+                    preemptiveBasicProxyAuth: Boolean,
+                    connectionTTL: Number,
+                    connectionMaxIdleMillis: Number,
+                    useTcpKeepAlive: Boolean,
+                    dnsResolver: String,
+                    responseMetadataCacheSize: Number,
+                    secureRandom: String
+                }
             },
             Cloud: {
                 credential: String,
@@ -463,6 +525,17 @@ module.exports.factory = function(passportMongo, settings, 
pluginMongo, mongoose
         igfsThreadPoolSize: Number,
         igfss: [{type: ObjectId, ref: 'Igfs'}],
         includeEventTypes: [String],
+        eventStorage: {
+            kind: {type: String, enum: ['Memory', 'Custom']},
+            Memory: {
+                expireAgeMs: Number,
+                expireCount: Number,
+                filter: String
+            },
+            Custom: {
+                className: String
+            }
+        },
         managementThreadPoolSize: Number,
         marshaller: {
             kind: {type: String, enum: ['OptimizedMarshaller', 
'JdkMarshaller']},
@@ -628,6 +701,122 @@ module.exports.factory = function(passportMongo, 
settings, pluginMongo, mongoose
         cacheKeyConfiguration: [{
             typeName: String,
             affinityKeyFieldName: String
+        }],
+        checkpointSpi: [{
+            kind: {type: String, enum: ['FS', 'Cache', 'S3', 'JDBC', 
'Custom']},
+            FS: {
+                directoryPaths: [String],
+                checkpointListener: String
+            },
+            Cache: {
+                cache: {type: ObjectId, ref: 'Cache'},
+                checkpointListener: String
+            },
+            S3: {
+                awsCredentials: {
+                    kind: {type: String, enum: ['Basic', 'Properties', 
'Anonymous', 'BasicSession', 'Custom']},
+                    Properties: {
+                        path: String
+                    },
+                    Custom: {
+                        className: String
+                    }
+                },
+                bucketNameSuffix: String,
+                clientConfiguration: {
+                    protocol: {type: String, enum: ['HTTP', 'HTTPS']},
+                    maxConnections: Number,
+                    userAgent: String,
+                    localAddress: String,
+                    proxyHost: String,
+                    proxyPort: Number,
+                    proxyUsername: String,
+                    proxyDomain: String,
+                    proxyWorkstation: String,
+                    retryPolicy: {
+                        kind: {type: String, enum: ['Default', 
'DefaultMaxRetries', 'DynamoDB', 'DynamoDBMaxRetries', 'Custom']},
+                        DefaultMaxRetries: {
+                            maxErrorRetry: Number
+                        },
+                        DynamoDBMaxRetries: {
+                            maxErrorRetry: Number
+                        },
+                        Custom: {
+                            retryCondition: String,
+                            backoffStrategy: String,
+                            maxErrorRetry: Number,
+                            honorMaxErrorRetryInClientConfig: Boolean
+                        }
+                    },
+                    maxErrorRetry: Number,
+                    socketTimeout: Number,
+                    connectionTimeout: Number,
+                    requestTimeout: Number,
+                    useReaper: Boolean,
+                    useGzip: Boolean,
+                    signerOverride: String,
+                    preemptiveBasicProxyAuth: Boolean,
+                    connectionTTL: Number,
+                    connectionMaxIdleMillis: Number,
+                    useTcpKeepAlive: Boolean,
+                    dnsResolver: String,
+                    responseMetadataCacheSize: Number,
+                    secureRandom: String
+                },
+                checkpointListener: String
+            },
+            JDBC: {
+                dataSourceBean: String,
+                dialect: {
+                    type: String,
+                    enum: ['Generic', 'Oracle', 'DB2', 'SQLServer', 'MySQL', 
'PostgreSQL', 'H2']
+                },
+                user: String,
+                checkpointTableName: String,
+                keyFieldName: String,
+                keyFieldType: String,
+                valueFieldName: String,
+                valueFieldType: String,
+                expireDateFieldName: String,
+                expireDateFieldType: String,
+                numberOfRetries: Number,
+                checkpointListener: String
+            },
+            Custom: {
+                className: String
+            }
+        }],
+        loadBalancingSpi: [{
+            kind: {type: String, enum: ['RoundRobin', 'Adaptive', 
'WeightedRandom', 'Custom']},
+            RoundRobin: {
+                perTask: Boolean
+            },
+            Adaptive: {
+                loadProbe: {
+                    kind: {type: String, enum: ['Job', 'CPU', 
'ProcessingTime', 'Custom']},
+                    Job: {
+                        useAverage: Boolean
+                    },
+                    CPU: {
+                        useAverage: Boolean,
+                        useProcessors: Boolean,
+                        processorCoefficient: Number
+                    },
+                    ProcessingTime: {
+                        useAverage: Boolean
+                    },
+                    Custom: {
+                        className: String
+                    }
+                }
+            },
+            WeightedRandom: {
+                nodeWeight: Number,
+                useWeights: Boolean
+            },
+            Custom: {
+                className: String
+            }
         }]
     });
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/087f6405/modules/web-console/backend/routes/demo/domains.json
----------------------------------------------------------------------
diff --git a/modules/web-console/backend/routes/demo/domains.json 
b/modules/web-console/backend/routes/demo/domains.json
index 980d8d1..ae46758 100644
--- a/modules/web-console/backend/routes/demo/domains.json
+++ b/modules/web-console/backend/routes/demo/domains.json
@@ -39,7 +39,8 @@
         "javaFieldType": "int"
       }
     ],
-    "caches": []
+    "caches": [],
+    "generatePojo": true
   },
   {
     "keyType": "Integer",
@@ -81,7 +82,8 @@
         "javaFieldType": "int"
       }
     ],
-    "caches": []
+    "caches": [],
+    "generatePojo": true
   },
   {
     "keyType": "Integer",
@@ -218,7 +220,8 @@
         "javaFieldType": "int"
       }
     ],
-    "caches": []
+    "caches": [],
+    "generatePojo": true
   },
   {
     "keyType": "Integer",
@@ -260,7 +263,8 @@
         "javaFieldType": "int"
       }
     ],
-    "caches": []
+    "caches": [],
+    "generatePojo": true
   },
   {
     "keyType": "Integer",
@@ -302,6 +306,7 @@
         "javaFieldType": "int"
       }
     ],
-    "caches": []
+    "caches": [],
+    "generatePojo": true
   }
 ]

http://git-wip-us.apache.org/repos/asf/ignite/blob/087f6405/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 8a65739..5c0b6a7 100644
--- a/modules/web-console/backend/services/agents.js
+++ b/modules/web-console/backend/services/agents.js
@@ -38,6 +38,7 @@ module.exports.factory = (_, fs, path, JSZip, settings, 
agentMgr, errors) => {
     class AgentsService {
         /**
          * Get agent archive with user agent configuration.
+         *
          * @returns {*} - readable stream for further piping. 
(http://stuk.github.io/jszip/documentation/api_jszip/generate_node_stream.html)
          */
         static getArchive(host, token) {

http://git-wip-us.apache.org/repos/asf/ignite/blob/087f6405/modules/web-console/backend/services/auth.js
----------------------------------------------------------------------
diff --git a/modules/web-console/backend/services/auth.js 
b/modules/web-console/backend/services/auth.js
index 67a3f2f..c3423da 100644
--- a/modules/web-console/backend/services/auth.js
+++ b/modules/web-console/backend/services/auth.js
@@ -36,6 +36,7 @@ module.exports.factory = (_, mongo, settings, errors) => {
     class AuthService {
         /**
          * Generate token string.
+         *
          * @param length - length of string
          * @returns {string} - generated token
          */
@@ -53,7 +54,8 @@ module.exports.factory = (_, mongo, settings, errors) => {
         }
 
         /**
-         * Reset password reset token for user
+         * Reset password reset token for user.
+         *
          * @param email - user email
          * @returns {Promise.<mongo.Account>} - that resolves account found by 
email with new reset password token.
          */
@@ -71,6 +73,7 @@ module.exports.factory = (_, mongo, settings, errors) => {
 
         /**
          * Reset password by reset token.
+         *
          * @param {string} token - reset token
          * @param {string} newPassword - new password
          * @returns {Promise.<mongo.Account>} - that resolves account with new 
password
@@ -95,7 +98,8 @@ module.exports.factory = (_, mongo, settings, errors) => {
         }
 
         /**
-         * Find account by token
+         * Find account by token.
+         *
          * @param {string} token - reset token
          * @returns {Promise.<{token, email}>} - that resolves token and user 
email
          */

http://git-wip-us.apache.org/repos/asf/ignite/blob/087f6405/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 f8cc2ed..e59d51d 100644
--- a/modules/web-console/backend/services/caches.js
+++ b/modules/web-console/backend/services/caches.js
@@ -34,14 +34,16 @@ module.exports = {
 module.exports.factory = (_, mongo, spaceService, errors) => {
     /**
      * Convert remove status operation to own presentation.
+     *
      * @param {RemoveResult} result - The results of remove operation.
      */
     const convertRemoveStatus = ({result}) => ({rowsAffected: result.n});
 
     /**
-     * Update existing cache
-     * @param {Object} cache - The cache for updating
-     * @returns {Promise.<mongo.ObjectId>} that resolves cache id
+     * Update existing cache.
+     *
+     * @param {Object} cache - The cache for updating.
+     * @returns {Promise.<mongo.ObjectId>} that resolves cache id.
      */
     const update = (cache) => {
         const cacheId = cache._id;
@@ -60,6 +62,7 @@ module.exports.factory = (_, mongo, spaceService, errors) => {
 
     /**
      * Create new cache.
+     *
      * @param {Object} cache - The cache for creation.
      * @returns {Promise.<mongo.ObjectId>} that resolves cache id.
      */
@@ -78,6 +81,7 @@ module.exports.factory = (_, mongo, spaceService, errors) => {
 
     /**
      * Remove all caches by space ids.
+     *
      * @param {Number[]} spaceIds - The space ids for cache deletion.
      * @returns {Promise.<RemoveResult>} - that resolves results of remove 
operation.
      */
@@ -93,6 +97,7 @@ module.exports.factory = (_, mongo, spaceService, errors) => {
     class CachesService {
         /**
          * Create or update cache.
+         *
          * @param {Object} cache - The cache.
          * @returns {Promise.<mongo.ObjectId>} that resolves cache id of merge 
operation.
          */
@@ -105,6 +110,7 @@ module.exports.factory = (_, mongo, spaceService, errors) 
=> {
 
         /**
          * Get caches by spaces.
+         *
          * @param {mongo.ObjectId|String} spaceIds - The spaces ids that own 
caches.
          * @returns {Promise.<mongo.Cache[]>} - contains requested caches.
          */
@@ -114,6 +120,7 @@ module.exports.factory = (_, mongo, spaceService, errors) 
=> {
 
         /**
          * Remove cache.
+         *
          * @param {mongo.ObjectId|String} cacheId - The cache id for remove.
          * @returns {Promise.<{rowsAffected}>} - The number of affected rows.
          */
@@ -129,6 +136,7 @@ module.exports.factory = (_, mongo, spaceService, errors) 
=> {
 
         /**
          * Remove all caches by user.
+         *
          * @param {mongo.ObjectId|String} userId - The user id that own caches.
          * @param {Boolean} demo - The flag indicates that need lookup in demo 
space.
          * @returns {Promise.<{rowsAffected}>} - The number of affected rows.

http://git-wip-us.apache.org/repos/asf/ignite/blob/087f6405/modules/web-console/backend/services/clusters.js
----------------------------------------------------------------------
diff --git a/modules/web-console/backend/services/clusters.js 
b/modules/web-console/backend/services/clusters.js
index 6c2722b..06e413a 100644
--- a/modules/web-console/backend/services/clusters.js
+++ b/modules/web-console/backend/services/clusters.js
@@ -34,14 +34,16 @@ module.exports = {
 module.exports.factory = (_, mongo, spacesService, errors) => {
     /**
      * Convert remove status operation to own presentation.
+     *
      * @param {RemoveResult} result - The results of remove operation.
      */
     const convertRemoveStatus = ({result}) => ({rowsAffected: result.n});
 
     /**
-     * Update existing cluster
-     * @param {Object} cluster - The cluster for updating
-     * @returns {Promise.<mongo.ObjectId>} that resolves cluster id
+     * Update existing cluster.
+     *
+     * @param {Object} cluster - The cluster for updating.
+     * @returns {Promise.<mongo.ObjectId>} that resolves cluster id.
      */
     const update = (cluster) => {
         const clusterId = cluster._id;
@@ -60,6 +62,7 @@ module.exports.factory = (_, mongo, spacesService, errors) => 
{
 
     /**
      * Create new cluster.
+     *
      * @param {Object} cluster - The cluster for creation.
      * @returns {Promise.<mongo.ObjectId>} that resolves cluster id.
      */
@@ -78,6 +81,7 @@ module.exports.factory = (_, mongo, spacesService, errors) => 
{
 
     /**
      * Remove all caches by space ids.
+     *
      * @param {Number[]} spaceIds - The space ids for cache deletion.
      * @returns {Promise.<RemoveResult>} - that resolves results of remove 
operation.
      */
@@ -90,7 +94,8 @@ module.exports.factory = (_, mongo, spacesService, errors) => 
{
     class ClustersService {
         /**
          * Create or update cluster.
-         * @param {Object} cluster - The cluster
+         *
+         * @param {Object} cluster - The cluster.
          * @returns {Promise.<mongo.ObjectId>} that resolves cluster id of 
merge operation.
          */
         static merge(cluster) {
@@ -102,8 +107,9 @@ module.exports.factory = (_, mongo, spacesService, errors) 
=> {
 
         /**
          * Get clusters and linked objects by space.
-         * @param {mongo.ObjectId|String} spaceIds - The spaces id that own 
cluster.
-         * @returns {Promise.<[mongo.Cache[], mongo.Cluster[], 
mongo.DomainModel[], mongo.Space[]]>} - contains requested caches and array of 
linked objects: clusters, domains, spaces.
+         *
+         * @param {mongo.ObjectId|String} spaceIds The spaces ids that own 
clusters.
+         * @returns {Promise.<Array<mongo.Cluster>>} Requested clusters.
          */
         static listBySpaces(spaceIds) {
             return mongo.Cluster.find({space: {$in: 
spaceIds}}).sort('name').lean().exec();
@@ -111,6 +117,7 @@ module.exports.factory = (_, mongo, spacesService, errors) 
=> {
 
         /**
          * Remove cluster.
+         *
          * @param {mongo.ObjectId|String} clusterId - The cluster id for 
remove.
          * @returns {Promise.<{rowsAffected}>} - The number of affected rows.
          */

http://git-wip-us.apache.org/repos/asf/ignite/blob/087f6405/modules/web-console/backend/services/domains.js
----------------------------------------------------------------------
diff --git a/modules/web-console/backend/services/domains.js 
b/modules/web-console/backend/services/domains.js
index 791e229..22582c1 100644
--- a/modules/web-console/backend/services/domains.js
+++ b/modules/web-console/backend/services/domains.js
@@ -35,6 +35,7 @@ module.exports = {
 module.exports.factory = (_, mongo, spacesService, cachesService, errors) => {
     /**
      * Convert remove status operation to own presentation.
+     *
      * @param {RemoveResult} result - The results of remove operation.
      */
     const convertRemoveStatus = ({result}) => ({rowsAffected: result.n});
@@ -43,7 +44,8 @@ module.exports.factory = (_, mongo, spacesService, 
cachesService, errors) => {
         Promise.all(_.map(cacheStoreChanges, (change) => 
mongo.Cache.update({_id: {$eq: change.cacheId}}, change.change, {}).exec()));
 
     /**
-     * Update existing domain
+     * Update existing domain.
+     *
      * @param {Object} domain - The domain for updating
      * @param savedDomains List of saved domains.
      * @returns {Promise.<mongo.ObjectId>} that resolves domain id
@@ -67,6 +69,7 @@ module.exports.factory = (_, mongo, spacesService, 
cachesService, errors) => {
 
     /**
      * Create new domain.
+     *
      * @param {Object} domain - The domain for creation.
      * @param savedDomains List of saved domains.
      * @returns {Promise.<mongo.ObjectId>} that resolves cluster id.
@@ -131,6 +134,7 @@ module.exports.factory = (_, mongo, spacesService, 
cachesService, errors) => {
 
     /**
      * Remove all caches by space ids.
+     *
      * @param {Array.<Number>} spaceIds - The space ids for cache deletion.
      * @returns {Promise.<RemoveResult>} - that resolves results of remove 
operation.
      */
@@ -142,6 +146,7 @@ module.exports.factory = (_, mongo, spacesService, 
cachesService, errors) => {
     class DomainsService {
         /**
          * Batch merging domains.
+         *
          * @param {Array.<mongo.DomainModel>} domains
          */
         static batchMerge(domains) {
@@ -150,9 +155,9 @@ module.exports.factory = (_, mongo, spacesService, 
cachesService, errors) => {
 
         /**
          * Get domain and linked objects by space.
+         *
          * @param {mongo.ObjectId|String} spaceIds - The space id that own 
domain.
-         * @returns {Promise.<[mongo.Cache[], mongo.Cluster[], 
mongo.DomainModel[], mongo.Space[]]>}
-         *      contains requested domains and array of linked objects: 
caches, spaces.
+         * @returns {Promise.<Array.<mongo.DomainModel>>} contains requested 
domains.
          */
         static listBySpaces(spaceIds) {
             return mongo.DomainModel.find({space: {$in: 
spaceIds}}).sort('valueType').lean().exec();
@@ -160,6 +165,7 @@ module.exports.factory = (_, mongo, spacesService, 
cachesService, errors) => {
 
         /**
          * Remove domain.
+         *
          * @param {mongo.ObjectId|String} domainId - The domain id for remove.
          * @returns {Promise.<{rowsAffected}>} - The number of affected rows.
          */

http://git-wip-us.apache.org/repos/asf/ignite/blob/087f6405/modules/web-console/backend/services/igfss.js
----------------------------------------------------------------------
diff --git a/modules/web-console/backend/services/igfss.js 
b/modules/web-console/backend/services/igfss.js
index 20f0121..578c642 100644
--- a/modules/web-console/backend/services/igfss.js
+++ b/modules/web-console/backend/services/igfss.js
@@ -34,12 +34,14 @@ module.exports = {
 module.exports.factory = (_, mongo, spacesService, errors) => {
     /**
      * Convert remove status operation to own presentation.
+     *
      * @param {RemoveResult} result - The results of remove operation.
      */
     const convertRemoveStatus = ({result}) => ({rowsAffected: result.n});
 
     /**
-     * Update existing IGFS
+     * Update existing IGFS.
+     *
      * @param {Object} igfs - The IGFS for updating
      * @returns {Promise.<mongo.ObjectId>} that resolves IGFS id
      */
@@ -58,6 +60,7 @@ module.exports.factory = (_, mongo, spacesService, errors) => 
{
 
     /**
      * Create new IGFS.
+     *
      * @param {Object} igfs - The IGFS for creation.
      * @returns {Promise.<mongo.ObjectId>} that resolves IGFS id.
      */
@@ -75,6 +78,7 @@ module.exports.factory = (_, mongo, spacesService, errors) => 
{
 
     /**
      * Remove all IGFSs by space ids.
+     *
      * @param {Number[]} spaceIds - The space ids for IGFS deletion.
      * @returns {Promise.<RemoveResult>} - that resolves results of remove 
operation.
      */
@@ -86,6 +90,7 @@ module.exports.factory = (_, mongo, spacesService, errors) => 
{
     class IgfssService {
         /**
          * Create or update IGFS.
+         *
          * @param {Object} igfs - The IGFS
          * @returns {Promise.<mongo.ObjectId>} that resolves IGFS id of merge 
operation.
          */
@@ -98,8 +103,9 @@ module.exports.factory = (_, mongo, spacesService, errors) 
=> {
 
         /**
          * Get IGFS by spaces.
+         *
          * @param {mongo.ObjectId|String} spacesIds - The spaces ids that own 
IGFSs.
-         * @returns {Promise.<mongo.IGFS[]>} - contains requested IGFSs.
+         * @returns {Promise.<Array<mongo.IGFS>>} - contains requested IGFSs.
          */
         static listBySpaces(spacesIds) {
             return mongo.Igfs.find({space: {$in: 
spacesIds}}).sort('name').lean().exec();
@@ -107,6 +113,7 @@ module.exports.factory = (_, mongo, spacesService, errors) 
=> {
 
         /**
          * Remove IGFS.
+         *
          * @param {mongo.ObjectId|String} igfsId - The IGFS id for remove.
          * @returns {Promise.<{rowsAffected}>} - The number of affected rows.
          */
@@ -121,6 +128,7 @@ module.exports.factory = (_, mongo, spacesService, errors) 
=> {
 
         /**
          * Remove all IGFSes by user.
+         *
          * @param {mongo.ObjectId|String} userId - The user id that own IGFS.
          * @param {Boolean} demo - The flag indicates that need lookup in demo 
space.
          * @returns {Promise.<{rowsAffected}>} - The number of affected rows.

http://git-wip-us.apache.org/repos/asf/ignite/blob/087f6405/modules/web-console/backend/test/unit/AuthService.test.js
----------------------------------------------------------------------
diff --git a/modules/web-console/backend/test/unit/AuthService.test.js 
b/modules/web-console/backend/test/unit/AuthService.test.js
index eec60c4..5ce473d 100644
--- a/modules/web-console/backend/test/unit/AuthService.test.js
+++ b/modules/web-console/backend/test/unit/AuthService.test.js
@@ -35,9 +35,7 @@ suite('AuthServiceTestsSuite', () => {
             });
     });
 
-    setup(() => {
-        return db.init();
-    });
+    setup(() => db.init());
 
     test('Check token generator', () => {
         const tokenLength = 16;

http://git-wip-us.apache.org/repos/asf/ignite/blob/087f6405/modules/web-console/backend/test/unit/CacheService.test.js
----------------------------------------------------------------------
diff --git a/modules/web-console/backend/test/unit/CacheService.test.js 
b/modules/web-console/backend/test/unit/CacheService.test.js
index 980f47a..304f62c 100644
--- a/modules/web-console/backend/test/unit/CacheService.test.js
+++ b/modules/web-console/backend/test/unit/CacheService.test.js
@@ -19,56 +19,37 @@ const assert = require('chai').assert;
 const injector = require('../injector');
 const testCaches = require('../data/caches.json');
 const testAccounts = require('../data/accounts.json');
+const testSpaces = require('../data/spaces.json');
 
 let cacheService;
 let mongo;
 let errors;
+let db;
 
 suite('CacheServiceTestsSuite', () => {
-    const prepareUserSpaces = () => {
-        return mongo.Account.create(testAccounts)
-            .then((accounts) => {
-                return Promise.all(
-                    accounts.map((account) => mongo.Space.create(
-                        [
-                            {name: 'Personal space', owner: account._id, demo: 
false},
-                            {name: 'Demo space', owner: account._id, demo: 
true}
-                        ]
-                    )))
-                    .then((spaces) => [accounts, spaces]);
-            });
-    };
-
     suiteSetup(() => {
         return Promise.all([injector('services/caches'),
             injector('mongo'),
-            injector('errors')])
-            .then(([_cacheService, _mongo, _errors]) => {
+            injector('errors'),
+            injector('dbHelper')])
+            .then(([_cacheService, _mongo, _errors, _db]) => {
                 mongo = _mongo;
                 cacheService = _cacheService;
                 errors = _errors;
+                db = _db;
             });
     });
 
-    setup(() => {
-        return Promise.all([
-            mongo.Cache.remove().exec(),
-            mongo.Account.remove().exec(),
-            mongo.Space.remove().exec()
-        ]);
-    });
+    setup(() => db.init());
 
     test('Create new cache', (done) => {
-        cacheService.merge(testCaches[0])
-            .then((cache) => {
-                assert.isNotNull(cache._id);
-
-                return cache._id;
-            })
-            .then((cacheId) => mongo.Cache.findById(cacheId))
-            .then((cache) => {
-                assert.isNotNull(cache);
-            })
+        const dupleCache = Object.assign({}, testCaches[0], {name: 'Other 
name'});
+
+        delete dupleCache._id;
+
+        cacheService.merge(dupleCache)
+            .then((cache) => mongo.Cache.findById(cache._id))
+            .then((cache) => assert.isNotNull(cache))
             .then(done)
             .catch(done);
     });
@@ -76,52 +57,43 @@ suite('CacheServiceTestsSuite', () => {
     test('Update existed cache', (done) => {
         const newName = 'NewUniqueName';
 
-        cacheService.merge(testCaches[0])
-            .then((cache) => {
-                const cacheBeforeMerge = Object.assign({}, testCaches[0], 
{_id: cache._id, name: newName});
+        const cacheBeforeMerge = Object.assign({}, testCaches[0], {name: 
newName});
 
-                return cacheService.merge(cacheBeforeMerge);
-            })
+        cacheService.merge(cacheBeforeMerge)
             .then((cache) => mongo.Cache.findById(cache._id))
-            .then((cacheAfterMerge) => {
-                assert.equal(cacheAfterMerge.name, newName);
-            })
+            .then((cacheAfterMerge) => assert.equal(cacheAfterMerge.name, 
newName))
             .then(done)
             .catch(done);
     });
 
     test('Create duplicated cache', (done) => {
-        const dupleCache = Object.assign({}, testCaches[0], {_id: null});
+        const dupleCache = Object.assign({}, testCaches[0]);
 
-        cacheService.merge(testCaches[0])
-            .then(() => cacheService.merge(dupleCache))
+        delete dupleCache._id;
+
+        cacheService.merge(dupleCache)
             .catch((err) => {
                 assert.instanceOf(err, errors.DuplicateKeyException);
+
                 done();
             });
     });
 
     test('Remove existed cache', (done) => {
-        cacheService.merge(testCaches[0])
-            .then((createdCache) => {
-                return mongo.Cache.findById(createdCache._id)
-                    .then((foundCache) => foundCache._id)
-                    .then(cacheService.remove)
-                    .then(({rowsAffected}) => {
-                        assert.equal(rowsAffected, 1);
-                    })
-                    .then(() => mongo.Cache.findById(createdCache._id))
-                    .then((notFoundCache) => {
-                        assert.isNull(notFoundCache);
-                    });
-            })
+        cacheService.remove(testCaches[0]._id)
+            .then(({rowsAffected}) =>
+                assert.equal(rowsAffected, 1)
+            )
+            .then(() => mongo.Cache.findById(testCaches[0]._id))
+            .then((notFoundCache) =>
+                assert.isNull(notFoundCache)
+            )
             .then(done)
             .catch(done);
     });
 
     test('Remove cache without identifier', (done) => {
-        cacheService.merge(testCaches[0])
-            .then(() => cacheService.remove())
+        cacheService.remove()
             .catch((err) => {
                 assert.instanceOf(err, errors.IllegalArgumentException);
 
@@ -132,45 +104,28 @@ suite('CacheServiceTestsSuite', () => {
     test('Remove missed cache', (done) => {
         const validNoExistingId = 'FFFFFFFFFFFFFFFFFFFFFFFF';
 
-        cacheService.merge(testCaches[0])
-            .then(() => cacheService.remove(validNoExistingId))
-            .then(({rowsAffected}) => {
-                assert.equal(rowsAffected, 0);
-            })
+        cacheService.remove(validNoExistingId)
+            .then(({rowsAffected}) =>
+                assert.equal(rowsAffected, 0)
+            )
             .then(done)
             .catch(done);
     });
 
-    test('Remove all caches in space', (done) => {
-        prepareUserSpaces()
-            .then(([accounts, spaces]) => {
-                const currentUser = accounts[0];
-                const userCache = Object.assign({}, testCaches[0], {space: 
spaces[0][0]._id});
-
-                return cacheService.merge(userCache)
-                    .then(() => cacheService.removeAll(currentUser._id, 
false));
-            })
-            .then(({rowsAffected}) => {
-                assert.equal(rowsAffected, 1);
-            })
+    test('Get all caches by space', (done) => {
+        cacheService.listBySpaces(testSpaces[0]._id)
+            .then((caches) =>
+                assert.equal(caches.length, 5)
+            )
             .then(done)
             .catch(done);
     });
 
-    test('Get all caches by space', (done) => {
-        prepareUserSpaces()
-            .then(([accounts, spaces]) => {
-                const userCache = Object.assign({}, testCaches[0], {space: 
spaces[0][0]._id});
-
-                return cacheService.merge(userCache)
-                    .then((cache) => {
-                        return cacheService.listBySpaces(spaces[0][0]._id)
-                            .then((caches) => {
-                                assert.equal(caches.length, 1);
-                                assert.equal(caches[0]._id.toString(), 
cache._id.toString());
-                            });
-                    });
-            })
+    test('Remove all caches in space', (done) => {
+        cacheService.removeAll(testAccounts[0]._id, false)
+            .then(({rowsAffected}) =>
+                assert.equal(rowsAffected, 5)
+            )
             .then(done)
             .catch(done);
     });

http://git-wip-us.apache.org/repos/asf/ignite/blob/087f6405/modules/web-console/backend/test/unit/ClusterService.test.js
----------------------------------------------------------------------
diff --git a/modules/web-console/backend/test/unit/ClusterService.test.js 
b/modules/web-console/backend/test/unit/ClusterService.test.js
index aff54f7..ed04c45 100644
--- a/modules/web-console/backend/test/unit/ClusterService.test.js
+++ b/modules/web-console/backend/test/unit/ClusterService.test.js
@@ -19,55 +19,37 @@ const assert = require('chai').assert;
 const injector = require('../injector');
 const testClusters = require('../data/clusters.json');
 const testAccounts = require('../data/accounts.json');
+const testSpaces = require('../data/spaces.json');
 
 let clusterService;
 let mongo;
 let errors;
+let db;
 
 suite('ClusterServiceTestsSuite', () => {
-    const prepareUserSpaces = () => {
-        return mongo.Account.create(testAccounts)
-            .then((accounts) => {
-                return Promise.all(accounts.map((account) => 
mongo.Space.create(
-                    [
-                        {name: 'Personal space', owner: account._id, demo: 
false},
-                        {name: 'Demo space', owner: account._id, demo: true}
-                    ]
-                )))
-                    .then((spaces) => [accounts, spaces]);
-            });
-    };
-
     suiteSetup(() => {
         return Promise.all([injector('services/clusters'),
             injector('mongo'),
-            injector('errors')])
-            .then(([_clusterService, _mongo, _errors]) => {
+            injector('errors'),
+            injector('dbHelper')])
+            .then(([_clusterService, _mongo, _errors, _db]) => {
                 mongo = _mongo;
                 clusterService = _clusterService;
                 errors = _errors;
+                db = _db;
             });
     });
 
-    setup(() => {
-        return Promise.all([
-            mongo.Cluster.remove().exec(),
-            mongo.Account.remove().exec(),
-            mongo.Space.remove().exec()
-        ]);
-    });
+    setup(() => db.init());
 
     test('Create new cluster', (done) => {
-        clusterService.merge(testClusters[0])
-            .then((cluster) => {
-                assert.isNotNull(cluster._id);
-
-                return cluster._id;
-            })
-            .then((clusterId) => mongo.Cluster.findById(clusterId))
-            .then((cluster) => {
-                assert.isNotNull(cluster);
-            })
+        const dupleCluster = Object.assign({}, testClusters[0], {name: 'Other 
name'});
+
+        delete dupleCluster._id;
+
+        clusterService.merge(dupleCluster)
+            .then((cluster) => mongo.Cluster.findById(cluster._id))
+            .then((cluster) => assert.isNotNull(cluster))
             .then(done)
             .catch(done);
     });
@@ -75,25 +57,21 @@ suite('ClusterServiceTestsSuite', () => {
     test('Update existed cluster', (done) => {
         const newName = 'NewUniqueName';
 
-        clusterService.merge(testClusters[0])
-            .then((cluster) => {
-                const clusterBeforeMerge = Object.assign({}, testClusters[0], 
{_id: cluster._id, name: newName});
+        const clusterBeforeMerge = Object.assign({}, testClusters[0], {name: 
newName});
 
-                return clusterService.merge(clusterBeforeMerge);
-            })
+        clusterService.merge(clusterBeforeMerge)
             .then((cluster) => mongo.Cluster.findById(cluster._id))
-            .then((clusterAfterMerge) => {
-                assert.equal(clusterAfterMerge.name, newName);
-            })
+            .then((clusterAfterMerge) => assert.equal(clusterAfterMerge.name, 
newName))
             .then(done)
             .catch(done);
     });
 
     test('Create duplicated cluster', (done) => {
-        const dupleCluster = Object.assign({}, testClusters[0], {_id: null});
+        const dupleCluster = Object.assign({}, testClusters[0]);
 
-        clusterService.merge(testClusters[0])
-            .then(() => clusterService.merge(dupleCluster))
+        delete dupleCluster._id;
+
+        clusterService.merge(dupleCluster)
             .catch((err) => {
                 assert.instanceOf(err, errors.DuplicateKeyException);
 
@@ -102,25 +80,20 @@ suite('ClusterServiceTestsSuite', () => {
     });
 
     test('Remove existed cluster', (done) => {
-        clusterService.merge(testClusters[0])
-            .then((existCluster) => {
-                return mongo.Cluster.findById(existCluster._id)
-                    .then((foundCluster) => 
clusterService.remove(foundCluster._id))
-                    .then(({rowsAffected}) => {
-                        assert.equal(rowsAffected, 1);
-                    })
-                    .then(() => mongo.Cluster.findById(existCluster._id))
-                    .then((notFoundCluster) => {
-                        assert.isNull(notFoundCluster);
-                    });
-            })
+        clusterService.remove(testClusters[0]._id)
+            .then(({rowsAffected}) =>
+                assert.equal(rowsAffected, 1)
+            )
+            .then(() => mongo.Cluster.findById(testClusters[0]._id))
+            .then((notFoundCluster) =>
+                assert.isNull(notFoundCluster)
+            )
             .then(done)
             .catch(done);
     });
 
     test('Remove cluster without identifier', (done) => {
-        clusterService.merge(testClusters[0])
-            .then(() => clusterService.remove())
+        clusterService.remove()
             .catch((err) => {
                 assert.instanceOf(err, errors.IllegalArgumentException);
 
@@ -131,45 +104,28 @@ suite('ClusterServiceTestsSuite', () => {
     test('Remove missed cluster', (done) => {
         const validNoExistingId = 'FFFFFFFFFFFFFFFFFFFFFFFF';
 
-        clusterService.merge(testClusters[0])
-            .then(() => clusterService.remove(validNoExistingId))
-            .then(({rowsAffected}) => {
-                assert.equal(rowsAffected, 0);
-            })
+        clusterService.remove(validNoExistingId)
+            .then(({rowsAffected}) =>
+                assert.equal(rowsAffected, 0)
+            )
             .then(done)
             .catch(done);
     });
 
-    test('Remove all clusters in space', (done) => {
-        prepareUserSpaces()
-            .then(([accounts, spaces]) => {
-                const currentUser = accounts[0];
-                const userCluster = Object.assign({}, testClusters[0], {space: 
spaces[0][0]._id});
-
-                return clusterService.merge(userCluster)
-                    .then(() => clusterService.removeAll(currentUser._id, 
false));
-            })
-            .then(({rowsAffected}) => {
-                assert.equal(rowsAffected, 1);
-            })
+    test('Get all clusters by space', (done) => {
+        clusterService.listBySpaces(testSpaces[0]._id)
+            .then((clusters) =>
+                assert.equal(clusters.length, 2)
+            )
             .then(done)
             .catch(done);
     });
 
-    test('Get all clusters by space', (done) => {
-        prepareUserSpaces()
-            .then(([accounts, spaces]) => {
-                const userCluster = Object.assign({}, testClusters[0], {space: 
spaces[0][0]._id});
-
-                return clusterService.merge(userCluster)
-                    .then((existCluster) => {
-                        return clusterService.listBySpaces(spaces[0][0]._id)
-                            .then((clusters) => {
-                                assert.equal(clusters.length, 1);
-                                assert.equal(clusters[0]._id.toString(), 
existCluster._id.toString());
-                            });
-                    });
-            })
+    test('Remove all clusters in space', (done) => {
+        clusterService.removeAll(testAccounts[0]._id, false)
+            .then(({rowsAffected}) =>
+                assert.equal(rowsAffected, 2)
+            )
             .then(done)
             .catch(done);
     });

http://git-wip-us.apache.org/repos/asf/ignite/blob/087f6405/modules/web-console/backend/test/unit/DomainService.test.js
----------------------------------------------------------------------
diff --git a/modules/web-console/backend/test/unit/DomainService.test.js 
b/modules/web-console/backend/test/unit/DomainService.test.js
index 8ce3fef..c7cf149 100644
--- a/modules/web-console/backend/test/unit/DomainService.test.js
+++ b/modules/web-console/backend/test/unit/DomainService.test.js
@@ -19,56 +19,46 @@ const assert = require('chai').assert;
 const injector = require('../injector');
 const testDomains = require('../data/domains.json');
 const testAccounts = require('../data/accounts.json');
+const testSpaces = require('../data/spaces.json');
 
 let domainService;
 let mongo;
 let errors;
+let db;
 
 suite('DomainsServiceTestsSuite', () => {
-    const prepareUserSpaces = () => {
-        return mongo.Account.create(testAccounts)
-            .then((accounts) => {
-                return Promise.all(accounts.map((account) => 
mongo.Space.create(
-                    [
-                        {name: 'Personal space', owner: account._id, demo: 
false},
-                        {name: 'Demo space', owner: account._id, demo: true}
-                    ]
-                )))
-                    .then((spaces) => [accounts, spaces]);
-            });
-    };
-
     suiteSetup(() => {
         return Promise.all([injector('services/domains'),
             injector('mongo'),
-            injector('errors')])
-            .then(([_domainService, _mongo, _errors]) => {
+            injector('errors'),
+            injector('dbHelper')])
+            .then(([_domainService, _mongo, _errors, _db]) => {
                 mongo = _mongo;
                 domainService = _domainService;
                 errors = _errors;
+                db = _db;
             });
     });
 
-    setup(() => {
-        return Promise.all([
-            mongo.DomainModel.remove().exec(),
-            mongo.Account.remove().exec(),
-            mongo.Space.remove().exec()
-        ]);
-    });
+    setup(() => db.init());
 
     test('Create new domain', (done) => {
-        domainService.batchMerge([testDomains[0]])
+        const dupleDomain = Object.assign({}, testDomains[0], {valueType: 
'other.Type'});
+
+        delete dupleDomain._id;
+
+        domainService.batchMerge([dupleDomain])
             .then((results) => {
                 const domain = results.savedDomains[0];
 
-                assert.isNotNull(domain._id);
+                assert.isObject(domain);
+                assert.isDefined(domain._id);
 
-                return domain._id;
+                return mongo.DomainModel.findById(domain._id);
             })
-            .then((domainId) => mongo.DomainModel.findById(domainId))
             .then((domain) => {
-                assert.isNotNull(domain);
+                assert.isObject(domain);
+                assert.isDefined(domain._id);
             })
             .then(done)
             .catch(done);
@@ -77,27 +67,31 @@ suite('DomainsServiceTestsSuite', () => {
     test('Update existed domain', (done) => {
         const newValType = 'value.Type';
 
-        domainService.batchMerge([testDomains[0]])
-            .then((results) => {
-                const domain = results.savedDomains[0];
+        const domainBeforeMerge = Object.assign({}, testDomains[0], 
{valueType: newValType});
 
-                const domainBeforeMerge = Object.assign({}, testDomains[0], 
{_id: domain._id, valueType: newValType});
+        domainService.batchMerge([domainBeforeMerge])
+            .then(({savedDomains, generatedCaches}) => {
+                assert.isArray(savedDomains);
+                assert.isArray(generatedCaches);
 
-                return domainService.batchMerge([domainBeforeMerge]);
-            })
-            .then((results) => 
mongo.DomainModel.findById(results.savedDomains[0]._id))
-            .then((domainAfterMerge) => {
-                assert.equal(domainAfterMerge.valueType, newValType);
+                assert.equal(1, savedDomains.length);
+                assert.equal(0, generatedCaches.length);
+
+                return mongo.DomainModel.findById(savedDomains[0]._id);
             })
+            .then((domainAfterMerge) =>
+                assert.equal(domainAfterMerge.valueType, newValType)
+            )
             .then(done)
             .catch(done);
     });
 
     test('Create duplicated domain', (done) => {
-        const dupleDomain = Object.assign({}, testDomains[0], {_id: null});
+        const dupleDomain = Object.assign({}, testDomains[0]);
 
-        domainService.batchMerge([testDomains[0]])
-            .then(() => domainService.batchMerge([dupleDomain]))
+        delete dupleDomain._id;
+
+        domainService.batchMerge([dupleDomain])
             .catch((err) => {
                 assert.instanceOf(err, errors.DuplicateKeyException);
 
@@ -106,27 +100,20 @@ suite('DomainsServiceTestsSuite', () => {
     });
 
     test('Remove existed domain', (done) => {
-        domainService.batchMerge([testDomains[0]])
-            .then((results) => {
-                const domain = results.savedDomains[0];
-
-                return mongo.DomainModel.findById(domain._id)
-                    .then((foundDomain) => 
domainService.remove(foundDomain._id))
-                    .then(({rowsAffected}) => {
-                        assert.equal(rowsAffected, 1);
-                    })
-                    .then(() => mongo.DomainModel.findById(domain._id))
-                    .then((notFoundDomain) => {
-                        assert.isNull(notFoundDomain);
-                    });
-            })
+        domainService.remove(testDomains[0]._id)
+            .then(({rowsAffected}) =>
+                assert.equal(rowsAffected, 1)
+            )
+            .then(() => mongo.DomainModel.findById(testDomains[0]._id))
+            .then((notFoundDomain) =>
+                assert.isNull(notFoundDomain)
+            )
             .then(done)
             .catch(done);
     });
 
     test('Remove domain without identifier', (done) => {
-        domainService.batchMerge([testDomains[0]])
-            .then(() => domainService.remove())
+        domainService.remove()
             .catch((err) => {
                 assert.instanceOf(err, errors.IllegalArgumentException);
 
@@ -137,47 +124,28 @@ suite('DomainsServiceTestsSuite', () => {
     test('Remove missed domain', (done) => {
         const validNoExistingId = 'FFFFFFFFFFFFFFFFFFFFFFFF';
 
-        domainService.batchMerge([testDomains[0]])
-            .then(() => domainService.remove(validNoExistingId))
-            .then(({rowsAffected}) => {
-                assert.equal(rowsAffected, 0);
-            })
+        domainService.remove(validNoExistingId)
+            .then(({rowsAffected}) =>
+                assert.equal(rowsAffected, 0)
+            )
             .then(done)
             .catch(done);
     });
 
-    test('Remove all domains in space', (done) => {
-        prepareUserSpaces()
-            .then(([accounts, spaces]) => {
-                const currentUser = accounts[0];
-                const userDomain = Object.assign({}, testDomains[0], {space: 
spaces[0][0]._id});
-
-                return domainService.batchMerge([userDomain])
-                    .then(() => domainService.removeAll(currentUser._id, 
false));
-            })
-            .then(({rowsAffected}) => {
-                assert.equal(rowsAffected, 1);
-            })
+    test('Get all domains by space', (done) => {
+        domainService.listBySpaces(testSpaces[0]._id)
+            .then((domains) =>
+                assert.equal(domains.length, 5)
+            )
             .then(done)
             .catch(done);
     });
 
-    test('Get all domains by space', (done) => {
-        prepareUserSpaces()
-            .then(([accounts, spaces]) => {
-                const userDomain = Object.assign({}, testDomains[0], {space: 
spaces[0][0]._id});
-
-                return domainService.batchMerge([userDomain])
-                    .then((results) => {
-                        const domain = results.savedDomains[0];
-
-                        return domainService.listBySpaces(spaces[0][0]._id)
-                            .then((domains) => {
-                                assert.equal(domains.length, 1);
-                                assert.equal(domains[0]._id.toString(), 
domain._id.toString());
-                            });
-                    });
-            })
+    test('Remove all domains in space', (done) => {
+        domainService.removeAll(testAccounts[0]._id, false)
+            .then(({rowsAffected}) =>
+                assert.equal(rowsAffected, 5)
+            )
             .then(done)
             .catch(done);
     });

http://git-wip-us.apache.org/repos/asf/ignite/blob/087f6405/modules/web-console/backend/test/unit/IgfsService.test.js
----------------------------------------------------------------------
diff --git a/modules/web-console/backend/test/unit/IgfsService.test.js 
b/modules/web-console/backend/test/unit/IgfsService.test.js
index 4fab279..67d9e08 100644
--- a/modules/web-console/backend/test/unit/IgfsService.test.js
+++ b/modules/web-console/backend/test/unit/IgfsService.test.js
@@ -19,55 +19,43 @@ const assert = require('chai').assert;
 const injector = require('../injector');
 const testIgfss = require('../data/igfss.json');
 const testAccounts = require('../data/accounts.json');
+const testSpaces = require('../data/spaces.json');
 
 let igfsService;
 let mongo;
 let errors;
+let db;
 
 suite('IgfsServiceTestsSuite', () => {
-    const prepareUserSpaces = () => {
-        return mongo.Account.create(testAccounts)
-            .then((accounts) => {
-                return Promise.all(accounts.map((account) => 
mongo.Space.create(
-                    [
-                        {name: 'Personal space', owner: account._id, demo: 
false},
-                        {name: 'Demo space', owner: account._id, demo: true}
-                    ]
-                )))
-                    .then((spaces) => [accounts, spaces]);
-            });
-    };
-
     suiteSetup(() => {
         return Promise.all([injector('services/igfss'),
             injector('mongo'),
-            injector('errors')])
-            .then(([_igfsService, _mongo, _errors]) => {
+            injector('errors'),
+            injector('dbHelper')])
+            .then(([_igfsService, _mongo, _errors, _db]) => {
                 mongo = _mongo;
                 igfsService = _igfsService;
                 errors = _errors;
+                db = _db;
             });
     });
 
-    setup(() => {
-        return Promise.all([
-            mongo.Igfs.remove().exec(),
-            mongo.Account.remove().exec(),
-            mongo.Space.remove().exec()
-        ]);
-    });
+    setup(() => db.init());
 
     test('Create new igfs', (done) => {
-        igfsService.merge(testIgfss[0])
+        const dupleIgfs = Object.assign({}, testIgfss[0], {name: 'Other 
name'});
+
+        delete dupleIgfs._id;
+
+        igfsService.merge(dupleIgfs)
             .then((igfs) => {
                 assert.isNotNull(igfs._id);
 
-                return igfs._id;
-            })
-            .then((igfsId) => mongo.Igfs.findById(igfsId))
-            .then((igfs) => {
-                assert.isNotNull(igfs);
+                return mongo.Igfs.findById(igfs._id);
             })
+            .then((igfs) =>
+                assert.isNotNull(igfs)
+            )
             .then(done)
             .catch(done);
     });
@@ -75,25 +63,21 @@ suite('IgfsServiceTestsSuite', () => {
     test('Update existed igfs', (done) => {
         const newName = 'NewUniqueName';
 
-        igfsService.merge(testIgfss[0])
-            .then((existIgfs) => {
-                const igfsBeforeMerge = Object.assign({}, testIgfss[0], {_id: 
existIgfs._id, name: newName});
+        const igfsBeforeMerge = Object.assign({}, testIgfss[0], {name: 
newName});
 
-                return igfsService.merge(igfsBeforeMerge);
-            })
+        igfsService.merge(igfsBeforeMerge)
             .then((igfs) => mongo.Igfs.findById(igfs._id))
-            .then((igfsAfterMerge) => {
-                assert.equal(igfsAfterMerge.name, newName);
-            })
+            .then((igfsAfterMerge) => assert.equal(igfsAfterMerge.name, 
newName))
             .then(done)
             .catch(done);
     });
 
     test('Create duplicated igfs', (done) => {
-        const dupleIfgs = Object.assign({}, testIgfss[0], {_id: null});
+        const dupleIfgs = Object.assign({}, testIgfss[0]);
+
+        delete dupleIfgs._id;
 
-        igfsService.merge(testIgfss[0])
-            .then(() => igfsService.merge(dupleIfgs))
+        igfsService.merge(dupleIfgs)
             .catch((err) => {
                 assert.instanceOf(err, errors.DuplicateKeyException);
 
@@ -102,25 +86,18 @@ suite('IgfsServiceTestsSuite', () => {
     });
 
     test('Remove existed igfs', (done) => {
-        igfsService.merge(testIgfss[0])
-            .then((existIgfs) => {
-                return mongo.Igfs.findById(existIgfs._id)
-                    .then((foundIgfs) => igfsService.remove(foundIgfs._id))
-                    .then(({rowsAffected}) => {
-                        assert.equal(rowsAffected, 1);
-                    })
-                    .then(() => mongo.Igfs.findById(existIgfs._id))
-                    .then((notFoundIgfs) => {
-                        assert.isNull(notFoundIgfs);
-                    });
-            })
+        igfsService.remove(testIgfss[0]._id)
+            .then(({rowsAffected}) => assert.equal(rowsAffected, 1))
+            .then(() => mongo.Igfs.findById(testIgfss[0]._id))
+            .then((notFoundIgfs) =>
+                assert.isNull(notFoundIgfs)
+            )
             .then(done)
             .catch(done);
     });
 
     test('Remove igfs without identifier', (done) => {
-        igfsService.merge(testIgfss[0])
-            .then(() => igfsService.remove())
+        igfsService.remove()
             .catch((err) => {
                 assert.instanceOf(err, errors.IllegalArgumentException);
 
@@ -131,45 +108,22 @@ suite('IgfsServiceTestsSuite', () => {
     test('Remove missed igfs', (done) => {
         const validNoExistingId = 'FFFFFFFFFFFFFFFFFFFFFFFF';
 
-        igfsService.merge(testIgfss[0])
-            .then(() => igfsService.remove(validNoExistingId))
-            .then(({rowsAffected}) => {
-                assert.equal(rowsAffected, 0);
-            })
+        igfsService.remove(validNoExistingId)
+            .then(({rowsAffected}) => assert.equal(rowsAffected, 0))
             .then(done)
             .catch(done);
     });
 
-    test('Remove all igfss in space', (done) => {
-        prepareUserSpaces()
-            .then(([accounts, spaces]) => {
-                const currentUser = accounts[0];
-                const userIgfs = Object.assign({}, testIgfss[0], {space: 
spaces[0][0]._id});
-
-                return igfsService.merge(userIgfs)
-                    .then(() => igfsService.removeAll(currentUser._id, false));
-            })
-            .then(({rowsAffected}) => {
-                assert.equal(rowsAffected, 1);
-            })
+    test('Get all igfss by space', (done) => {
+        igfsService.listBySpaces(testSpaces[0]._id)
+            .then((igfss) => assert.equal(igfss.length, 1))
             .then(done)
             .catch(done);
     });
 
-    test('Get all igfss by space', (done) => {
-        prepareUserSpaces()
-            .then(([accounts, spaces]) => {
-                const userIgfs = Object.assign({}, testIgfss[0], {space: 
spaces[0][0]._id});
-
-                return igfsService.merge(userIgfs)
-                    .then((existIgfs) => {
-                        return igfsService.listBySpaces(spaces[0][0]._id)
-                            .then((igfss) => {
-                                assert.equal(igfss.length, 1);
-                                assert.equal(igfss[0]._id.toString(), 
existIgfs._id.toString());
-                            });
-                    });
-            })
+    test('Remove all igfss in space', (done) => {
+        igfsService.removeAll(testAccounts[0]._id, false)
+            .then(({rowsAffected}) => assert.equal(rowsAffected, 1))
             .then(done)
             .catch(done);
     });

http://git-wip-us.apache.org/repos/asf/ignite/blob/087f6405/modules/web-console/frontend/.eslintrc
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/.eslintrc 
b/modules/web-console/frontend/.eslintrc
index a8a3bb8..988cfa0 100644
--- a/modules/web-console/frontend/.eslintrc
+++ b/modules/web-console/frontend/.eslintrc
@@ -27,12 +27,8 @@ globals:
     global: true
     angular: true
     $generatorCommon: true
-    $generatorProperties: true
-    $generatorXml: true
+    $generatorSpring: true
     $generatorJava: true
-    $generatorPom: true
-    $generatorReadme: true
-    $generatorDocker: true
     $generatorOptional: true
     saveAs: true
     process: true

http://git-wip-us.apache.org/repos/asf/ignite/blob/087f6405/modules/web-console/frontend/app/app.config.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/app.config.js 
b/modules/web-console/frontend/app/app.config.js
index 7adfc94..7416ce9 100644
--- a/modules/web-console/frontend/app/app.config.js
+++ b/modules/web-console/frontend/app/app.config.js
@@ -15,6 +15,16 @@
  * limitations under the License.
  */
 
+import _ from 'lodash';
+
+const nonNil = _.negate(_.isNil);
+const nonEmpty = _.negate(_.isEmpty);
+
+_.mixin({
+    nonNil,
+    nonEmpty
+});
+
 import alertTemplateUrl from '../views/templates/alert.jade';
 
 const igniteConsoleCfg = angular.module('ignite-console.config', ['ngAnimate', 
'mgcrea.ngStrap']);

http://git-wip-us.apache.org/repos/asf/ignite/blob/087f6405/modules/web-console/frontend/app/app.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/app.js 
b/modules/web-console/frontend/app/app.js
index 830d067..3510743 100644
--- a/modules/web-console/frontend/app/app.js
+++ b/modules/web-console/frontend/app/app.js
@@ -16,6 +16,7 @@
  */
 
 import '../public/stylesheets/style.scss';
+import '../app/directives/ui-grid-settings/ui-grid-settings.scss';
 import './helpers/jade/mixins.jade';
 
 import './app.config';
@@ -26,6 +27,7 @@ import './decorator/tooltip';
 import './modules/form/form.module';
 import './modules/agent/agent.module.js';
 import './modules/sql/sql.module';
+import './modules/nodes/nodes.module';
 import './modules/Demo/Demo.module.js';
 
 import './modules/states/signin.state';
@@ -60,12 +62,15 @@ import igniteOnClickFocus from 
'./directives/on-click-focus.directive.js';
 import igniteOnEnter from './directives/on-enter.directive.js';
 import igniteOnEnterFocusMove from 
'./directives/on-enter-focus-move.directive.js';
 import igniteOnEscape from './directives/on-escape.directive.js';
-import igniteUiAceDocker from 
'./directives/ui-ace-docker/ui-ace-docker.directive';
+import igniteOnFocusOut from './directives/on-focus-out.directive.js';
+import igniteRestoreInputFocus from 
'./directives/restore-input-focus.directive.js';
 import igniteUiAceJava from './directives/ui-ace-java/ui-ace-java.directive';
+import igniteUiAceSpring from 
'./directives/ui-ace-spring/ui-ace-spring.directive';
+import igniteUiAceCSharp from 
'./directives/ui-ace-sharp/ui-ace-sharp.directive';
 import igniteUiAcePojos from 
'./directives/ui-ace-pojos/ui-ace-pojos.directive';
 import igniteUiAcePom from './directives/ui-ace-pom/ui-ace-pom.directive';
+import igniteUiAceDocker from 
'./directives/ui-ace-docker/ui-ace-docker.directive';
 import igniteUiAceTabs from './directives/ui-ace-tabs.directive';
-import igniteUiAceXml from './directives/ui-ace-xml/ui-ace-xml.directive';
 import igniteRetainSelection from './directives/retain-selection.directive';
 
 // Services.
@@ -89,24 +94,15 @@ import UnsavedChangesGuard from 
'./services/UnsavedChangesGuard.service';
 
 // Filters.
 import byName from './filters/byName.filter';
+import defaultName from './filters/default-name.filter';
 import domainsValidation from './filters/domainsValidation.filter';
-import hasPojo from './filters/hasPojo.filter';
 import duration from './filters/duration.filter';
+import hasPojo from './filters/hasPojo.filter';
 
 // Generators
-import $generatorCommon from 'generator/generator-common';
-import $generatorJava from 'generator/generator-java';
-import $generatorOptional from 'generator/generator-optional';
-import $generatorProperties from 'generator/generator-properties';
-import $generatorReadme from 'generator/generator-readme';
-import $generatorXml from 'generator/generator-xml';
+import $generatorOptional from 
'./modules/configuration/generator/generator-optional';
 
-window.$generatorCommon = $generatorCommon;
-window.$generatorJava = $generatorJava;
 window.$generatorOptional = $generatorOptional;
-window.$generatorProperties = $generatorProperties;
-window.$generatorReadme = $generatorReadme;
-window.$generatorXml = $generatorXml;
 
 // Controllers
 import admin from 'controllers/admin-controller';
@@ -152,6 +148,7 @@ angular
     'ignite-console.socket',
     'ignite-console.agent',
     'ignite-console.sql',
+    'ignite-console.nodes',
     'ignite-console.demo',
     // States.
     'ignite-console.states.login',
@@ -184,13 +181,16 @@ angular
 .directive(...igniteOnEnter)
 .directive(...igniteOnEnterFocusMove)
 .directive(...igniteOnEscape)
-.directive(...igniteUiAceDocker)
+.directive(...igniteUiAceSpring)
 .directive(...igniteUiAceJava)
+.directive(...igniteUiAceCSharp)
 .directive(...igniteUiAcePojos)
 .directive(...igniteUiAcePom)
+.directive(...igniteUiAceDocker)
 .directive(...igniteUiAceTabs)
-.directive(...igniteUiAceXml)
 .directive(...igniteRetainSelection)
+.directive('igniteOnFocusOut', igniteOnFocusOut)
+.directive('igniteRestoreInputFocus', igniteRestoreInputFocus)
 // Services.
 .service('IgniteErrorPopover', ErrorPopover)
 .service('JavaTypes', JavaTypes)
@@ -219,10 +219,11 @@ angular
 .controller(...igfs)
 .controller(...profile)
 // Filters.
-.filter(...hasPojo)
-.filter(...domainsValidation)
 .filter(...byName)
+.filter('defaultName', defaultName)
+.filter(...domainsValidation)
 .filter(...duration)
+.filter(...hasPojo)
 .config(['$stateProvider', '$locationProvider', '$urlRouterProvider', 
($stateProvider, $locationProvider, $urlRouterProvider) => {
     // Set up the states.
     $stateProvider

http://git-wip-us.apache.org/repos/asf/ignite/blob/087f6405/modules/web-console/frontend/app/data/dialects.json
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/data/dialects.json 
b/modules/web-console/frontend/app/data/dialects.json
new file mode 100644
index 0000000..007fbc6
--- /dev/null
+++ b/modules/web-console/frontend/app/data/dialects.json
@@ -0,0 +1,9 @@
+{
+  "Generic": "org.apache.ignite.cache.store.jdbc.dialect.BasicJdbcDialect",
+  "Oracle": "org.apache.ignite.cache.store.jdbc.dialect.OracleDialect",
+  "DB2": "org.apache.ignite.cache.store.jdbc.dialect.DB2Dialect",
+  "SQLServer": "org.apache.ignite.cache.store.jdbc.dialect.SQLServerDialect",
+  "MySQL": "org.apache.ignite.cache.store.jdbc.dialect.MySQLDialect",
+  "PostgreSQL": "org.apache.ignite.cache.store.jdbc.dialect.BasicJdbcDialect",
+  "H2": "org.apache.ignite.cache.store.jdbc.dialect.H2Dialect"
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/087f6405/modules/web-console/frontend/app/data/java-classes.json
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/data/java-classes.json 
b/modules/web-console/frontend/app/data/java-classes.json
index b0ec9fb..6704457 100644
--- a/modules/web-console/frontend/app/data/java-classes.json
+++ b/modules/web-console/frontend/app/data/java-classes.json
@@ -15,5 +15,7 @@
   {"short": "String", "full": "java.lang.String"},
   {"short": "Time", "full": "java.sql.Time"},
   {"short": "Timestamp", "full": "java.sql.Timestamp"},
-  {"short": "UUID", "full": "java.util.UUID"}
+  {"short": "UUID", "full": "java.util.UUID"},
+  {"short": "Serializable", "full": "java.io.Serializable"},
+  {"short": "Class", "full": "java.lang.Class"}
 ]

http://git-wip-us.apache.org/repos/asf/ignite/blob/087f6405/modules/web-console/frontend/app/decorator/tooltip.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/decorator/tooltip.js 
b/modules/web-console/frontend/app/decorator/tooltip.js
index 221cf7c..71ea694 100644
--- a/modules/web-console/frontend/app/decorator/tooltip.js
+++ b/modules/web-console/frontend/app/decorator/tooltip.js
@@ -28,12 +28,15 @@ angular.module('mgcrea.ngStrap.tooltip')
             let tipElementEntered = false;
 
             config.onShow = ($tooltip) => {
-                $tooltip.$element.on('mouseenter', () => tipElementEntered = 
true);
-                $tooltip.$element.on('mouseleave', () => {
-                    tipElementEntered = false;
+                // Workaround for tooltip detection.
+                if ($tooltip.$element && $tooltip.$options.trigger === 'click 
hover') {
+                    $tooltip.$element.on('mouseenter', () => tipElementEntered 
= true);
+                    $tooltip.$element.on('mouseleave', () => {
+                        tipElementEntered = false;
 
-                    $tooltip.leave();
-                });
+                        $tooltip.leave();
+                    });
+                }
             };
 
             const $tooltip = $delegate(element, config);

Reply via email to