You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by an...@apache.org on 2015/07/31 04:28:14 UTC

[01/41] incubator-ignite git commit: # ignite-1121 merge with ignite-843

Repository: incubator-ignite
Updated Branches:
  refs/heads/ignite-1121 1ff248cfd -> e24f3b74b


# ignite-1121 merge with ignite-843


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

Branch: refs/heads/ignite-1121
Commit: 9f901032577e2b4ba50f55454ad10b11750c9538
Parents: ea15083 95f54db
Author: Andrey <an...@gridgain.com>
Authored: Fri Jul 24 10:04:56 2015 +0700
Committer: Andrey <an...@gridgain.com>
Committed: Fri Jul 24 10:04:56 2015 +0700

----------------------------------------------------------------------
 .../main/js/controllers/metadata-controller.js  | 67 +++++++++----
 .../src/main/js/controllers/models/caches.json  |  8 +-
 .../main/js/controllers/models/clusters.json    |  8 +-
 .../main/js/controllers/models/metadata.json    | 36 ++++---
 .../src/main/js/controllers/models/summary.json |  2 +-
 .../web-control-center/src/main/js/package.json |  2 -
 .../src/main/js/public/stylesheets/style.less   |  2 +-
 .../main/js/views/configuration/metadata.jade   |  2 +-
 .../src/main/js/views/includes/controls.jade    | 98 ++++++++++----------
 .../src/main/js/views/sql/sql.jade              |  6 +-
 10 files changed, 138 insertions(+), 93 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/9f901032/modules/web-control-center/src/main/js/package.json
----------------------------------------------------------------------
diff --cc modules/web-control-center/src/main/js/package.json
index 477266a,7295755..bfbf034
--- a/modules/web-control-center/src/main/js/package.json
+++ b/modules/web-control-center/src/main/js/package.json
@@@ -37,10 -37,7 +37,8 @@@
      "passport": "^0.2.1",
      "passport-local": "^1.0.0",
      "passport-local-mongoose": "^1.0.0",
-     "pg": "^4.4.0",
 -    "serve-favicon": "~2.2.0"
 +    "serve-favicon": "~2.2.0",
-     "util": "^0.10.3",
 +    "ws": "~0.7.2"
    },
    "devDependencies": {
      "morgan": "~1.5.1",


[14/41] incubator-ignite git commit: #ignite-961: merge

Posted by an...@apache.org.
#ignite-961:  merge


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

Branch: refs/heads/ignite-1121
Commit: 216d4ff39be130015267fcf79abd2433644e0b3f
Parents: 63e6427
Author: ivasilinets <iv...@gridgain.com>
Authored: Mon Jul 27 18:07:02 2015 +0300
Committer: ivasilinets <iv...@gridgain.com>
Committed: Mon Jul 27 18:07:02 2015 +0300

----------------------------------------------------------------------
 .../processors/rest/handlers/query/QueryCommandHandler.java      | 4 ----
 1 file changed, 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/216d4ff3/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/query/QueryCommandHandler.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/query/QueryCommandHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/query/QueryCommandHandler.java
index d4e101a..35fbcef 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/query/QueryCommandHandler.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/query/QueryCommandHandler.java
@@ -152,10 +152,6 @@ public class QueryCommandHandler extends GridRestCommandHandlerAdapter {
 
                 res.setFieldsMetadata(convertMetadata(fieldsMeta));
 
-                List<GridQueryFieldMetadata> fieldsMeta = ((QueryCursorImpl<?>) qryCur).fieldsMeta();
-
-                res.setFieldsMetadata(convertMetadata(fieldsMeta));
-
                 return new GridRestResponse(res);
             }
             catch (Exception e) {


[29/41] incubator-ignite git commit: # ignite-843 Rename

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/web-control-center/src/main/js/controllers/summary-controller.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/controllers/summary-controller.js b/modules/web-control-center/src/main/js/controllers/summary-controller.js
deleted file mode 100644
index 531dc83..0000000
--- a/modules/web-control-center/src/main/js/controllers/summary-controller.js
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-controlCenterModule.controller('summaryController', ['$scope', '$http', '$common', function ($scope, $http, $common) {
-    $scope.joinTip = $common.joinTip;
-    $scope.getModel = $common.getModel;
-
-    $scope.javaClassItems = [
-        {label: 'snippet', value: false},
-        {label: 'factory class', value: true}
-    ];
-
-    $scope.evictionPolicies = [
-        {value: 'LRU', label: 'LRU'},
-        {value: 'RND', label: 'Random'},
-        {value: 'FIFO', label: 'FIFO'},
-        {value: 'SORTED', label: 'Sorted'},
-        {value: undefined, label: 'Not set'}
-    ];
-
-    $scope.oss = ['debian:8', 'ubuntu:14.10'];
-
-    $scope.configServer = {javaClassServer: false, os: undefined};
-    $scope.backupItem = {javaClassClient: false};
-
-    $http.get('/models/summary.json')
-        .success(function (data) {
-            $scope.screenTip = data.screenTip;
-            $scope.clientFields = data.clientFields;
-        })
-        .error(function (errMsg) {
-            $common.showError(errMsg);
-        });
-
-    $scope.clusters = [];
-
-    $scope.aceInit = function (editor) {
-        editor.setReadOnly(true);
-        editor.setOption("highlightActiveLine", false);
-
-        var renderer = editor.renderer;
-
-        renderer.setHighlightGutterLine(false);
-        renderer.setShowPrintMargin(false);
-        renderer.setOption('fontSize', '14px');
-
-        editor.setTheme('ace/theme/chrome');
-    };
-
-    $scope.reloadServer = function () {
-        $scope.javaServer = $scope.configServer.javaClassServer ? $scope.configServer.javaClass : $scope.configServer.javaSnippet;
-
-        if ($scope.configServer.docker) {
-            var os = $scope.configServer.os ? $scope.configServer.os : $scope.oss[0];
-
-            $scope.dockerServer = $scope.configServer.docker.replace(new RegExp('\%OS\%', 'g'), os);
-        }
-    };
-
-    $scope.selectItem = function (cluster) {
-        if (!cluster)
-            return;
-
-        $scope.selectedItem = cluster;
-
-        $scope.$watch('javaClassServer', $scope.reloadServer);
-        $scope.$watch('os', $scope.reloadServer);
-
-        $scope.generateServer(cluster);
-
-        $scope.reloadServer();
-
-        $scope.$watch('configServer', function () {
-            $scope.reloadServer();
-        }, true);
-
-        $scope.$watch('backupItem', function () {
-            $scope.generateClient();
-        }, true);
-    };
-
-    $scope.generateServer = function (cluster) {
-        $http.post('summary/generator', {_id: cluster._id})
-            .success(function (data) {
-                $scope.xmlServer = data.xmlServer;
-
-                $scope.configServer.javaClass = data.javaClassServer;
-                $scope.configServer.javaSnippet = data.javaSnippetServer;
-                $scope.configServer.docker = data.docker;
-            }).error(function (errMsg) {
-                $common.showError('Failed to generate config: ' + errMsg);
-            });
-    };
-
-    $scope.generateClient = function () {
-        $http.post('summary/generator', {
-            _id: $scope.selectedItem._id, javaClass: $scope.backupItem.javaClassClient,
-            clientNearConfiguration: $scope.backupItem.nearConfiguration
-        })
-            .success(function (data) {
-                $scope.xmlClient = data.xmlClient;
-                $scope.javaClient = data.javaClient;
-            }).error(function (errMsg) {
-                $common.showError('Failed to generate config: ' + errMsg);
-            });
-    };
-
-    $scope.download = function () {
-        $http.post('summary/download', {_id: $scope.selectedItem._id, javaClass: $scope.javaClass, os: $scope.os})
-            .success(function (data) {
-                var file = document.createElement('a');
-
-                file.setAttribute('href', 'data:application/octet-stream;charset=utf-8,' + data);
-                file.setAttribute('download', $scope.selectedItem.name + '-configuration.zip');
-
-                file.style.display = 'none';
-
-                document.body.appendChild(file);
-
-                file.click();
-
-                document.body.removeChild(file);
-            })
-            .error(function (errMsg) {
-                $common.showError('Failed to generate zip: ' + errMsg);
-            });
-    };
-
-    $http.post('clusters/list').success(function (data) {
-        $scope.clusters = data.clusters;
-
-        if ($scope.clusters.length > 0) {
-            var restoredId = sessionStorage.summarySelectedId;
-
-            var selectIdx = 0;
-
-            if (restoredId) {
-                var idx = _.findIndex($scope.clusters, function (cluster) {
-                    return cluster._id == restoredId;
-                });
-
-                if (idx >= 0)
-                    selectIdx = idx;
-                else
-                    delete sessionStorage.summarySelectedId;
-            }
-
-            $scope.selectItem($scope.clusters[selectIdx]);
-
-            $scope.$watch('selectedItem', function (val) {
-                if (val)
-                    sessionStorage.summarySelectedId = val._id;
-            }, true);
-        }
-    });
-}]);

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/web-control-center/src/main/js/db.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/db.js b/modules/web-control-center/src/main/js/db.js
deleted file mode 100644
index 5232e24..0000000
--- a/modules/web-control-center/src/main/js/db.js
+++ /dev/null
@@ -1,370 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-var config = require('./helpers/configuration-loader.js');
-
-// Mongoose for mongodb.
-var mongoose = require('mongoose'),
-    Schema = mongoose.Schema,
-    ObjectId = mongoose.Schema.Types.ObjectId,
-    passportLocalMongoose = require('passport-local-mongoose');
-
-var deepPopulate = require('mongoose-deep-populate');
-
-// Connect to mongoDB database.
-mongoose.connect(config.get('mongoDB:url'), {server: {poolSize: 4}});
-
-// Define account model.
-var AccountSchema = new Schema({
-    username: String,
-    email: String,
-    lastLogin: Date,
-    admin: Boolean
-});
-
-AccountSchema.plugin(passportLocalMongoose, {usernameField: 'email', limitAttempts: true, lastLoginField: 'lastLogin',
-    usernameLowerCase: true});
-
-AccountSchema.set('toJSON', {
-    transform: function(doc, ret) {
-        return {
-            _id: ret._id,
-            email: ret.email,
-            username: ret.username,
-            admin: ret.admin,
-            lastLogin: ret.lastLogin
-        };
-    }
-});
-
-exports.Account = mongoose.model('Account', AccountSchema);
-
-// Define space model.
-exports.Space = mongoose.model('Space', new Schema({
-    name: String,
-    owner: {type: ObjectId, ref: 'Account'},
-    usedBy: [{
-        permission: {type: String, enum: ['VIEW', 'FULL']},
-        account: {type: ObjectId, ref: 'Account'}
-    }]
-}));
-
-// Define cache type metadata model.
-var CacheTypeMetadataSchema = new Schema({
-    space: {type: ObjectId, ref: 'Space'},
-    name: String,
-    kind: {type: String, enum: ['query', 'store', 'both']},
-    databaseSchema: String,
-    databaseTable: String,
-    keyType: String,
-    valueType: String,
-    keyFields: [{databaseName: String, databaseType: String, javaName: String, javaType: String}],
-    valueFields: [{databaseName: String, databaseType: String, javaName: String, javaType: String}],
-    queryFields: [{name: String, className: String}],
-    ascendingFields: [{name: String, className: String}],
-    descendingFields:  [{name: String, className: String}],
-    textFields: [String],
-    groups: [{name: String, fields: [{name: String, className: String, direction: Boolean}]}]
-});
-
-exports.CacheTypeMetadata = mongoose.model('CacheTypeMetadata', CacheTypeMetadataSchema);
-
-// Define cache model.
-var CacheSchema = new Schema({
-    space: {type: ObjectId, ref: 'Space'},
-    name: String,
-    mode: {type: String, enum: ['PARTITIONED', 'REPLICATED', 'LOCAL']},
-    atomicityMode: {type: String, enum: ['ATOMIC', 'TRANSACTIONAL']},
-
-    backups: Number,
-    memoryMode: {type: String, enum: ['ONHEAP_TIERED', 'OFFHEAP_TIERED', 'OFFHEAP_VALUES']},
-    offHeapMaxMemory: Number,
-    startSize: Number,
-    swapEnabled: Boolean,
-
-    evictionPolicy: {
-        kind: {type: String, enum: ['LRU', 'RND', 'FIFO', 'Sorted']},
-        LRU: {
-            batchSize: Number,
-            maxMemorySize: Number,
-            maxSize: Number
-        },
-        RND: {
-            maxSize: Number
-        },
-        FIFO: {
-            batchSize: Number,
-            maxMemorySize: Number,
-            maxSize: Number
-        },
-        SORTED: {
-            batchSize: Number,
-            maxMemorySize: Number,
-            maxSize: Number
-        }
-    },
-
-    rebalanceMode: {type: String, enum: ['SYNC', 'ASYNC', 'NONE']},
-    rebalanceThreadPoolSize: Number,
-    rebalanceBatchSize: Number,
-    rebalanceOrder: Number,
-    rebalanceDelay: Number,
-    rebalanceTimeout: Number,
-    rebalanceThrottle: Number,
-
-    storeMetadata: [{type: ObjectId, ref: 'CacheTypeMetadata'}],
-    cacheStoreFactory: {
-        kind: {
-            type: String,
-            enum: ['CacheJdbcPojoStoreFactory', 'CacheJdbcBlobStoreFactory', 'CacheHibernateBlobStoreFactory']
-        },
-        CacheJdbcPojoStoreFactory: {
-            dataSourceBean: String,
-            dialect: {
-                type: String,
-                enum: ['Oracle', 'DB2', 'SQLServer', 'MySQL', 'PosgreSQL', 'H2']
-            }
-        },
-        CacheJdbcBlobStoreFactory: {
-            user: String,
-            dataSourceBean: String,
-            initSchema: Boolean,
-            createTableQuery: String,
-            loadQuery: String,
-            insertQuery: String,
-            updateQuery: String,
-            deleteQuery: String
-        },
-        CacheHibernateBlobStoreFactory: {
-            hibernateProperties: [String]
-        }
-    },
-    loadPreviousValue: Boolean,
-    readThrough: Boolean,
-    writeThrough: Boolean,
-
-    writeBehindEnabled: Boolean,
-    writeBehindBatchSize: Number,
-    writeBehindFlushSize: Number,
-    writeBehindFlushFrequency: Number,
-    writeBehindFlushThreadCount: Number,
-
-    invalidate: Boolean,
-    defaultLockTimeout: Number,
-    transactionManagerLookupClassName: String,
-
-    sqlEscapeAll: Boolean,
-    sqlOnheapRowCacheSize: Number,
-    longQueryWarningTimeout: Number,
-    queryMetadata: [{type: ObjectId, ref: 'CacheTypeMetadata'}],
-    indexedTypes: [{keyClass: String, valueClass: String}],
-    sqlFunctionClasses: [String],
-    statisticsEnabled: Boolean,
-    managementEnabled: Boolean,
-    readFromBackup: Boolean,
-    copyOnRead: Boolean,
-    maxConcurrentAsyncOperations: Number,
-    nearConfiguration: {
-        nearStartSize: Number,
-        nearEvictionPolicy: {
-            kind: {type: String, enum: ['LRU', 'RND', 'FIFO', 'Sorted']},
-            LRU: {
-                batchSize: Number,
-                maxMemorySize: Number,
-                maxSize: Number
-            },
-            RND: {
-                maxSize: Number
-            },
-            FIFO: {
-                batchSize: Number,
-                maxMemorySize: Number,
-                maxSize: Number
-            },
-            SORTED: {
-                batchSize: Number,
-                maxMemorySize: Number,
-                maxSize: Number
-            }
-        }
-    }
-});
-
-exports.Cache = mongoose.model('Cache', CacheSchema);
-
-// Define cluster schema.
-var ClusterSchema = new Schema({
-    space: {type: ObjectId, ref: 'Space'},
-    name: String,
-    discovery: {
-        kind: {type: String, enum: ['Vm', 'Multicast', 'S3', 'Cloud', 'GoogleStorage', 'Jdbc', 'SharedFs']},
-        Vm: {
-            addresses: [String]
-        },
-        Multicast: {
-            multicastGroup: String,
-            multicastPort: Number,
-            responseWaitTime: Number,
-            addressRequestAttempts: Number,
-            localAddress: String
-        },
-        S3: {
-            bucketName: String
-        },
-        Cloud: {
-            credential: String,
-            credentialPath: String,
-            identity: String,
-            provider: String,
-            regions: [String],
-            zones:  [String]
-        },
-        GoogleStorage: {
-            projectName: String,
-            bucketName: String,
-            serviceAccountP12FilePath: String,
-            addrReqAttempts: String
-        },
-        Jdbc: {
-            initSchema: Boolean
-        },
-        SharedFs: {
-            path: String
-        }
-    },
-    atomicConfiguration: {
-        backups: Number,
-        cacheMode: {type: String, enum: ['LOCAL', 'REPLICATED', 'PARTITIONED']},
-        atomicSequenceReserveSize: Number
-    },
-    caches: [{type: ObjectId, ref: 'Cache'}],
-    cacheSanityCheckEnabled: Boolean,
-    clockSyncSamples: Number,
-    clockSyncFrequency: Number,
-    deploymentMode: {type: String, enum: ['PRIVATE', 'ISOLATED', 'SHARED', 'CONTINUOUS']},
-    discoveryStartupDelay: Number,
-    igfsThreadPoolSize: Number,
-    includeEventTypes: [{
-        type: String, enum: ['EVTS_CHECKPOINT', 'EVTS_DEPLOYMENT', 'EVTS_ERROR', 'EVTS_DISCOVERY',
-            'EVTS_JOB_EXECUTION', 'EVTS_TASK_EXECUTION', 'EVTS_CACHE', 'EVTS_CACHE_REBALANCE', 'EVTS_CACHE_LIFECYCLE',
-            'EVTS_CACHE_QUERY', 'EVTS_SWAPSPACE', 'EVTS_IGFS']
-    }],
-    managementThreadPoolSize: Number,
-    marshaller: {
-        kind: {type: String, enum: ['OptimizedMarshaller', 'JdkMarshaller']},
-        OptimizedMarshaller: {
-            poolSize: Number,
-            requireSerializable: Boolean
-        }
-    },
-    marshalLocalJobs: Boolean,
-    marshallerCacheKeepAliveTime: Number,
-    marshallerCacheThreadPoolSize: Number,
-    metricsExpireTime: Number,
-    metricsHistorySize: Number,
-    metricsLogFrequency: Number,
-    metricsUpdateFrequency: Number,
-    networkTimeout: Number,
-    networkSendRetryDelay: Number,
-    networkSendRetryCount: Number,
-    peerClassLoadingEnabled: Boolean,
-    peerClassLoadingLocalClassPathExclude: [String],
-    peerClassLoadingMissedResourcesCacheSize: Number,
-    peerClassLoadingThreadPoolSize: Number,
-    publicThreadPoolSize: Number,
-    segmentCheckFrequency: Number,
-    segmentationPolicy: {type: String, enum: ['RESTART_JVM', 'STOP', 'NOOP']},
-    allSegmentationResolversPassRequired: Boolean,
-    segmentationResolveAttempts: Number,
-    swapSpaceSpi: {
-        kind: {type: String, enum: ['FileSwapSpaceSpi']},
-        FileSwapSpaceSpi: {
-            baseDirectory: String,
-            readStripesNumber: Number,
-            maximumSparsity: Number,
-            maxWriteQueueSize: Number,
-            writeBufferSize: Number
-        }
-    },
-    systemThreadPoolSize: Number,
-    timeServerPortBase: Number,
-    timeServerPortRange: Number,
-    transactionConfiguration: {
-        defaultTxConcurrency: {type: String, enum: ['OPTIMISTIC', 'PESSIMISTIC']},
-        transactionIsolation: {type: String, enum: ['READ_COMMITTED', 'REPEATABLE_READ', 'SERIALIZABLE']},
-        defaultTxTimeout: Number,
-        pessimisticTxLogLinger: Number,
-        pessimisticTxLogSize: Number,
-        txSerializableEnabled: Boolean
-    },
-    waitForSegmentOnStart: Boolean
-});
-
-ClusterSchema.plugin(deepPopulate, {
-    whitelist: [
-        'caches',
-        'caches.queryMetadata',
-        'caches.storeMetadata'
-    ]
-});
-
-// Define cluster model.
-exports.Cluster = mongoose.model('Cluster', ClusterSchema);
-
-// Define persistence schema.
-var PersistenceSchema = new Schema({
-    space: {type: ObjectId, ref: 'Space'},
-    name: String,
-    rdbms: {type: String, enum: ['oracle', 'db2', 'mssql', 'postgre', 'mysql', 'h2']},
-    dbName: String,
-    host: String,
-    user: String,
-    tables: [{
-        use: Boolean,
-        schemaName: String,
-        tableName: String,
-        keyClass: String,
-        valueClass: String,
-        columns: [{
-            use: Boolean,
-            pk: Boolean,
-            ak: Boolean,
-            notNull: Boolean,
-            databaseName: String,
-            databaseType: Number,
-            javaName: String,
-            javaType: String
-        }]
-    }]
-});
-
-// Define persistence model.
-exports.Persistence = mongoose.model('Persistence', PersistenceSchema);
-
-exports.upsert = function (model, data, cb) {
-    if (data._id) {
-        var id = data._id;
-
-        delete data._id;
-
-        model.findOneAndUpdate({_id: id}, data, cb);
-    }
-    else
-        new model(data).save(cb);
-};
-
-exports.mongoose = mongoose;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/web-control-center/src/main/js/helpers/configuration-loader.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/helpers/configuration-loader.js b/modules/web-control-center/src/main/js/helpers/configuration-loader.js
deleted file mode 100644
index 6dbb577..0000000
--- a/modules/web-control-center/src/main/js/helpers/configuration-loader.js
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-var config = require('nconf');
-
-config.file({'file': 'config/default.json'});
-
-module.exports = config;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/web-control-center/src/main/js/helpers/data-structures.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/helpers/data-structures.js b/modules/web-control-center/src/main/js/helpers/data-structures.js
deleted file mode 100644
index 2462708..0000000
--- a/modules/web-control-center/src/main/js/helpers/data-structures.js
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-eventGroups = {
-    EVTS_CHECKPOINT: ['EVT_CHECKPOINT_SAVED', 'EVT_CHECKPOINT_LOADED', 'EVT_CHECKPOINT_REMOVED'],
-    EVTS_DEPLOYMENT: ['EVT_CLASS_DEPLOYED', 'EVT_CLASS_UNDEPLOYED', 'EVT_CLASS_DEPLOY_FAILED', 'EVT_TASK_DEPLOYED',
-        'EVT_TASK_UNDEPLOYED', 'EVT_TASK_DEPLOY_FAILED'],
-    EVTS_ERROR: ['EVT_JOB_TIMEDOUT', 'EVT_JOB_FAILED', 'EVT_JOB_FAILED_OVER', 'EVT_JOB_REJECTED', 'EVT_JOB_CANCELLED',
-        'EVT_TASK_TIMEDOUT', 'EVT_TASK_FAILED', 'EVT_CLASS_DEPLOY_FAILED', 'EVT_TASK_DEPLOY_FAILED',
-        'EVT_TASK_DEPLOYED', 'EVT_TASK_UNDEPLOYED', 'EVT_CACHE_REBALANCE_STARTED', 'EVT_CACHE_REBALANCE_STOPPED'],
-    EVTS_DISCOVERY: ['EVT_NODE_JOINED', 'EVT_NODE_LEFT', 'EVT_NODE_FAILED', 'EVT_NODE_SEGMENTED',
-        'EVT_CLIENT_NODE_DISCONNECTED', 'EVT_CLIENT_NODE_RECONNECTED'],
-    EVTS_JOB_EXECUTION: ['EVT_JOB_MAPPED', 'EVT_JOB_RESULTED', 'EVT_JOB_FAILED_OVER', 'EVT_JOB_STARTED',
-        'EVT_JOB_FINISHED', 'EVT_JOB_TIMEDOUT', 'EVT_JOB_REJECTED', 'EVT_JOB_FAILED', 'EVT_JOB_QUEUED',
-        'EVT_JOB_CANCELLED'],
-    EVTS_TASK_EXECUTION: ['EVT_TASK_STARTED', 'EVT_TASK_FINISHED', 'EVT_TASK_FAILED', 'EVT_TASK_TIMEDOUT',
-        'EVT_TASK_SESSION_ATTR_SET', 'EVT_TASK_REDUCED'],
-    EVTS_CACHE: ['EVT_CACHE_ENTRY_CREATED', 'EVT_CACHE_ENTRY_DESTROYED', 'EVT_CACHE_OBJECT_PUT',
-        'EVT_CACHE_OBJECT_READ', 'EVT_CACHE_OBJECT_REMOVED', 'EVT_CACHE_OBJECT_LOCKED', 'EVT_CACHE_OBJECT_UNLOCKED',
-        'EVT_CACHE_OBJECT_SWAPPED', 'EVT_CACHE_OBJECT_UNSWAPPED', 'EVT_CACHE_OBJECT_EXPIRED'],
-    EVTS_CACHE_REBALANCE: ['EVT_CACHE_REBALANCE_STARTED', 'EVT_CACHE_REBALANCE_STOPPED',
-        'EVT_CACHE_REBALANCE_PART_LOADED', 'EVT_CACHE_REBALANCE_PART_UNLOADED', 'EVT_CACHE_REBALANCE_OBJECT_LOADED',
-        'EVT_CACHE_REBALANCE_OBJECT_UNLOADED', 'EVT_CACHE_REBALANCE_PART_DATA_LOST'],
-    EVTS_CACHE_LIFECYCLE: ['EVT_CACHE_STARTED', 'EVT_CACHE_STOPPED', 'EVT_CACHE_NODES_LEFT'],
-    EVTS_CACHE_QUERY: ['EVT_CACHE_QUERY_EXECUTED', 'EVT_CACHE_QUERY_OBJECT_READ'],
-    EVTS_SWAPSPACE: ['EVT_SWAP_SPACE_CLEARED', 'EVT_SWAP_SPACE_DATA_REMOVED', 'EVT_SWAP_SPACE_DATA_READ',
-        'EVT_SWAP_SPACE_DATA_STORED', 'EVT_SWAP_SPACE_DATA_EVICTED'],
-    EVTS_IGFS: ['EVT_IGFS_FILE_CREATED', 'EVT_IGFS_FILE_RENAMED', 'EVT_IGFS_FILE_DELETED', 'EVT_IGFS_FILE_OPENED_READ',
-        'EVT_IGFS_FILE_OPENED_WRITE', 'EVT_IGFS_FILE_CLOSED_WRITE', 'EVT_IGFS_FILE_CLOSED_READ', 'EVT_IGFS_FILE_PURGED',
-        'EVT_IGFS_META_UPDATED', 'EVT_IGFS_DIR_CREATED', 'EVT_IGFS_DIR_RENAMED', 'EVT_IGFS_DIR_DELETED']
-};
-
-jdbcTypes = {
-    BIT: {value: "BIT", code: -7, label: "BIT"},
-    TINYINT: {value: "TINYINT", code: -6, label: "TINYINT"},
-    SMALLINT: {value: "SMALLINT", code: 5, label: "SMALLINT"},
-    INTEGER: {value: "INTEGER", code: 4, label: "INTEGER"},
-    BIGINT: {value: "BIGINT", code: -5, label: "BIGINT"},
-    FLOAT: {value: "FLOAT", code: 6, label: "FLOAT"},
-    REAL: {value: "REAL", code: 7, label: "REAL"},
-    DOUBLE: {value: "DOUBLE", code: 8, label: "DOUBLE"},
-    NUMERIC: {value: "NUMERIC", code: 2, label: "NUMERIC"},
-    DECIMAL: {value: "DECIMAL", code: 3, label: "DECIMAL"},
-    CHAR: {value: "CHAR", code: 1, label: "CHAR"},
-    VARCHAR: {value: "VARCHAR", code: 12, label: "VARCHAR"},
-    DATE: {value: "DATE", code: 91, label: "DATE"},
-    TIME: {value: "TIME", code: 92, label: "TIME"},
-    TIMESTAMP: {value: "TIMESTAMP", code: 93, label: "TIMESTAMP"},
-    BINARY: {value: "BINARY", code: -2, label: "BINARY"}
-};
-
-javaTypes = {
-    INTEGER: {value: "java.lang.Integer", label: "Integer"},
-    LONG: {value: "java.lang.Long", label: "Long"},
-    BIGDECIMAL: {value: "java.math.BigDecimal", label: "BigDecimal"},
-    FLOAT: {value: "java.lang.Float", label: "Float"},
-    DOUBLE: {value: "java.lang.Double", label: "Double"},
-    STRING: {value: "java.lang.String", label: "String"},
-    BOOLEAN: {value: "java.lang.Boolean", label: "Boolean"},
-    BYTE_ARRAY: {value: "byte[]", label: "byte[]"},
-    DATE: {value: "java.sql.Date", label: "Date"},
-    TIME: {value: "java.sql.Time", label: "Time"},
-    TIMESTAMP: {value: "java.sql.Timestamp", label: "Timestamp"}
-};
-
-if (typeof window === 'undefined') {
-    exports.eventGroups = eventGroups;
-    exports.jdbcTypes = jdbcTypes;
-    exports.javaTypes = javaTypes;
-}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/web-control-center/src/main/js/package.json
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/package.json b/modules/web-control-center/src/main/js/package.json
deleted file mode 100644
index fd82196..0000000
--- a/modules/web-control-center/src/main/js/package.json
+++ /dev/null
@@ -1,49 +0,0 @@
-{
-  "name": "ignite-web-control-center",
-  "version": "1.0.0",
-  "description": "Web application for configuration, monitoring Ignite Cluster",
-  "private": true,
-  "scripts": {
-    "start": "node ./bin/www"
-  },
-  "author": "",
-  "contributors": [
-    {
-      "name": "",
-      "email": ""
-    }
-  ],
-  "license": "Apache-2.0",
-  "keywords": "grid",
-  "homepage": "https://ignite.incubator.apache.org/",
-  "engines": {
-    "node": ">=0.12.4"
-  },
-  "dependencies": {
-    "angular-ui-ace": "^0.2.3",
-    "archiver": "^0.14.4",
-    "body-parser": "~1.12.0",
-    "connect-flash": "^0.1.1",
-    "connect-mongo": "^0.8.1",
-    "cookie-parser": "~1.3.4",
-    "debug": "~2.1.1",
-    "express": "~4.12.2",
-    "express-session": "^1.11.1",
-    "jade": "~1.9.2",
-    "lodash": "3.10.0",
-    "mongoose": "^4.0.2",
-    "mongoose-deep-populate": "1.1.0",
-    "nconf": "^0.7.1",
-    "node-sass-middleware": "^0.9.0",
-    "passport": "^0.2.1",
-    "passport-local": "^1.0.0",
-    "passport-local-mongoose": "^1.0.0",
-    "serve-favicon": "~2.2.0"
-  },
-  "devDependencies": {
-    "morgan": "~1.5.1",
-    "supertest": "^1.0.1",
-    "mocha": "~2.0.1",
-    "should": "~3.1.3"
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/web-control-center/src/main/js/public/favicon.ico
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/public/favicon.ico b/modules/web-control-center/src/main/js/public/favicon.ico
deleted file mode 100644
index 74ec626..0000000
Binary files a/modules/web-control-center/src/main/js/public/favicon.ico and /dev/null differ

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/web-control-center/src/main/js/public/images/docker.png
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/public/images/docker.png b/modules/web-control-center/src/main/js/public/images/docker.png
deleted file mode 100644
index 7ec3aef..0000000
Binary files a/modules/web-control-center/src/main/js/public/images/docker.png and /dev/null differ

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/web-control-center/src/main/js/public/images/java.png
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/public/images/java.png b/modules/web-control-center/src/main/js/public/images/java.png
deleted file mode 100644
index ddb3b8e..0000000
Binary files a/modules/web-control-center/src/main/js/public/images/java.png and /dev/null differ

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/web-control-center/src/main/js/public/images/logo.png
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/public/images/logo.png b/modules/web-control-center/src/main/js/public/images/logo.png
deleted file mode 100644
index c3577c5..0000000
Binary files a/modules/web-control-center/src/main/js/public/images/logo.png and /dev/null differ

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/web-control-center/src/main/js/public/images/xml.png
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/public/images/xml.png b/modules/web-control-center/src/main/js/public/images/xml.png
deleted file mode 100644
index 029065e..0000000
Binary files a/modules/web-control-center/src/main/js/public/images/xml.png and /dev/null differ

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/web-control-center/src/main/js/public/stylesheets/style.scss
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/public/stylesheets/style.scss b/modules/web-control-center/src/main/js/public/stylesheets/style.scss
deleted file mode 100644
index e2542ce..0000000
--- a/modules/web-control-center/src/main/js/public/stylesheets/style.scss
+++ /dev/null
@@ -1,1270 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-$logo-path: "https://www.filepicker.io/api/file/QagunjDGRFul2JgNCAli";
-$input-height: 28px;
-$ignite-red: #ec1c24;
-$ignite-block-callout-background: #f3f8f3;
-$ignite-block-callout: #50af51;
-
-hr {
-    margin: 20px 0;
-}
-
-.main-header .logo {
-    height: auto;
-}
-
-.main-sidebar {
-    padding-top: 60px;
-}
-
-.navbar-default .navbar-brand, .navbar-default .navbar-brand:hover {
-    position: absolute;
-    width: 100%;
-    left: 0;
-    text-align: center;
-}
-
-.modal-backdrop.am-fade {
-    opacity: .5;
-    transition: opacity .15s linear;
-    &.ng-enter {
-        opacity: 0;
-        &.ng-enter-active {
-            opacity: .5;
-        }
-    }
-    &.ng-leave {
-        opacity: .5;
-        &.ng-leave-active {
-            opacity: 0;
-        }
-    }
-}
-
-.modal.center .modal-dialog {
-    position: fixed;
-    top: 50%;
-    left: 50%;
-    -webkit-transform: translateX(-50%) translateY(-50%);
-    transform: translateX(-50%) translateY(-50%);
-}
-
-.border-left {
-    box-shadow: 1px 0 0 0 #eee inset;
-}
-
-.border-right {
-    box-shadow: 1px 0 0 0 #eee;
-}
-
-.theme-line {
-    background-color: #f9f9f9;
-}
-
-.theme-line header {
-    background-color: #fff;
-}
-
-.theme-line header a.btn {
-    border: 0 none;
-    padding: 10px 25px;
-    background-color: rgba(0, 0, 0, 0.15);
-}
-
-.theme-line header a.btn:hover {
-    background-color: rgba(0, 0, 0, 0.25);
-}
-
-.theme-line header a.btn.btn-link {
-    background: transparent;
-    color: rgba(255, 255, 255, 0.8);
-}
-
-.theme-line header a.btn.btn-link:hover {
-    color: #fff;
-    text-decoration: none;
-}
-
-.theme-line .navbar-nav a {
-    background-color: transparent;
-}
-
-.theme-line .navbar-nav a:hover,
-.theme-line .navbar-nav a:active,
-.theme-line .navbar-nav a:focus {
-    background-color: transparent;
-}
-
-.theme-line .main-links {
-    padding-top: 50px;
-}
-
-.theme-line .main-links h3 {
-    margin-top: 0;
-    font-size: 17px;
-}
-
-.theme-line .main-links .links a {
-    color: #888;
-}
-
-.theme-line .main-links .links a:hover {
-    text-decoration: none;
-}
-
-.theme-line #category-columns,
-.theme-solid #category-columns {
-    margin: 50px 30px 0;
-}
-
-.theme-line #category-columns h4 {
-    text-transform: uppercase;
-    font-weight: 300;
-    color: #999;
-    font-size: 14px;
-}
-
-.theme-line #category-columns ul {
-    list-style: none;
-    padding: 0;
-    margin-bottom: 15px;
-}
-
-.theme-line #category-columns ul li a {
-    padding: 5px 0;
-    display: block;
-    font-size: 16px;
-}
-
-.theme-line #category-columns ul .view-all {
-    font-size: 0.85em;
-}
-
-.theme-line .docs-header {
-    color: #999;
-    overflow: hidden;
-}
-
-.theme-line .docs-header h1 {
-    color: #444;
-    margin-top: 0;
-    font-size: 22px;
-}
-
-.theme-line .btn-primary {
-    border: 0 none;
-    background-color: $ignite-red;
-}
-
-.theme-line .btn-primary:hover {
-    background-color: #950d12;
-}
-
-.theme-line .main-content .nav-horizontal a {
-    box-shadow: 0 0;
-    border: 0 none;
-    background-color: #fff;
-    border-radius: 0;
-    color: #aaa;
-    padding: 6px;
-    margin: 0 14px;
-}
-
-.theme-line .main-content .nav-horizontal a:hover {
-    color: #999;
-    border-bottom: 5px solid #ddd;
-}
-
-.theme-line .main-content .nav-horizontal a.active {
-    border-bottom: 5px solid #888;
-}
-
-.theme-line .navbar-nav, .theme-line .sidebar-nav {
-    ul li > a.active {
-        cursor: default;
-        pointer-events: none;
-    }
-}
-
-.theme-line .sidebar-nav {
-    color: #474a54;
-    padding-bottom: 30px;
-
-    ul {
-        padding: 0;
-        list-style: none;
-        font-size: 14px;
-        margin: 3px 0 0;
-        li {
-            color: #666;
-            line-height: $input-height;
-
-            span.fa-stack {
-                margin-right: 5px;
-                font-size: 12px;
-                height: 26px;
-            }
-
-            a {
-                font-size: 18px;
-                color: #666;
-                position: relative;
-                white-space: nowrap;
-                overflow: hidden;
-                -o-text-overflow: ellipsis;
-                text-overflow: ellipsis;
-            }
-        }
-    }
-}
-
-.theme-line .sidebar-nav ul li a:hover {
-    text-decoration: none;
-}
-
-.theme-line .select,
-.theme-line .typeahead {
-    li a {
-        color: #666;
-        background-color: transparent;
-    }
-
-    li a:hover {
-        color: $ignite-red;
-    }
-
-    .active {
-        background-color: #eee;
-    }
-}
-
-.theme-line .sidebar-nav ul li .subcategory {
-    padding-left: 15px;
-}
-
-.theme-line .sidebar-nav h4 {
-    margin-top: 2em;
-    font-weight: normal;
-    text-transform: uppercase;
-    font-size: 11px;
-    margin-bottom: 10px;
-    color: #bbb;
-}
-
-.theme-line .sidebar-nav h4:first-child {
-    margin-top: 0;
-}
-
-.theme-line .sidebar-nav .ask {
-    width: 100%;
-    text-align: center;
-    padding: 10px;
-}
-
-.theme-line .border-left .sidebar-nav {
-    padding-left: 15px;
-}
-
-.theme-line .suggest {
-    padding: 5px;
-    display: inline-block;
-    font-size: 12px;
-}
-
-.header {
-    padding: 15px;
-}
-
-.header .has-github {
-    padding-right: 136px;
-}
-
-.header h1.navbar-brand {
-    height: 40px;
-    width: 200px;
-    padding: 0;
-    margin: 5px 15px 0 0;
-}
-
-.header h1.navbar-brand a {
-    text-indent: -99999px;
-    background: no-repeat center center;
-    display: block;
-    width: 100%;
-    height: 100%;
-    background-size: contain;
-}
-
-.header .nav.navbar-nav.pull-right {
-    position: relative;
-    right: -30px;
-}
-
-.header .nav.navbar-nav .not-link {
-    padding: 15px;
-    display: inline-block;
-}
-
-.header .nav.navbar-nav .stable,
-.header .nav.navbar-nav .beta,
-.header .nav.navbar-nav .private {
-    font-size: 9px;
-    padding: 3px 5px;
-    display: inline-block;
-    line-height: 8px;
-    border-radius: 3px;
-    margin-left: 6px;
-    color: #fff;
-    top: -2px;
-    position: relative;
-    opacity: 0.6;
-    -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=60)";
-    filter: alpha(opacity=60);
-}
-
-.header .nav.navbar-nav a:hover > .stable,
-.header .nav.navbar-nav a:hover > .beta,
-.header .nav.navbar-nav a:hover > .private {
-    opacity: 1;
-    -ms-filter: none;
-    filter: none;
-}
-
-.header .nav.navbar-nav .beta {
-    background-color: #59c3d1;
-}
-
-.header .nav.navbar-nav .stable {
-    background-color: #41b841;
-}
-
-.header .nav.navbar-nav .private {
-    background-color: #333;
-}
-
-.theme-line header {
-    border-bottom: 8px solid;
-}
-
-.theme-line header h2 {
-    color: #aaa;
-}
-
-.theme-line header p {
-    color: #666;
-}
-
-.theme-line header {
-    border-bottom-color: $ignite-red;
-}
-
-.theme-line .navbar-nav {
-    color: #888;
-}
-
-.theme-line .navbar-nav a {
-    color: #bbb;
-}
-
-.theme-line header a.btn {
-    background-color: $ignite-red;
-}
-
-.theme-line header a.btn:hover {
-    background-color: #950d12;
-}
-
-.theme-line header .navbar-nav .tt-cursor {
-    background-color: $ignite-red;
-}
-
-.theme-line header .navbar-nav a:hover, .theme-line header .navbar-nav .open > a {
-    color: $ignite-red;
-}
-
-.theme-line .navbar-nav .active a {
-    //font-weight: bold;
-    color: $ignite-red;
-}
-
-.theme-line .navbar-nav .active a:hover {
-    color: #950d12;
-}
-
-.theme-line .main-links .links a:hover {
-    color: $ignite-red;
-}
-
-.theme-line .main-content a {
-    color: #666;
-}
-
-.theme-line .main-content a:hover {
-    color: #950d12;
-}
-
-.theme-line .sidebar-nav ul li a.active:before {
-    background-color: $ignite-red;
-}
-
-.theme-line .sidebar-nav ul li a.active {
-    color: $ignite-red;
-}
-
-.theme-line .sidebar-nav ul li a:hover, .theme-line .sidebar-nav ul li a.active:hover {
-    color: #950d12;
-}
-
-.theme-line .main-content .nav-horizontal a.active {
-    border-color: $ignite-red;
-    color: $ignite-red;
-}
-
-.theme-line .main-content .nav-horizontal a:hover {
-    color: #950d12;
-}
-
-.theme-line .main-content .nav-horizontal a.active:hover {
-    border-color: #950d12;
-}
-
-.theme-line header .navbar-nav a.active, .theme-line #versions-list li a:hover strong, .theme-line #versions-list li a.active .current, .theme-line #versions-list li a:active .current {
-    color: $ignite-red;
-}
-
-.theme-line header .navbar-nav a {
-    font-size: 18px;
-}
-
-.theme-line.body-threes .section-right .threes-nav .btn-default:hover, .theme-line.page-docs.body-threes .section-right .threes-nav .pull-right a:hover {
-    color: $ignite-red;
-    border-color: $ignite-red;
-}
-
-.theme-line .section-right {
-    padding-left: 30px;
-}
-
-.body-overlap .main-content {
-    margin-top: 30px;
-}
-
-.body-box .main-content,
-.body-overlap .main-content {
-    padding: 30px;
-    box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.1);
-    background-color: #fff;
-}
-
-body {
-    font-weight: 400;
-    font-family: Roboto Slab, serif;;
-}
-
-h1, h2, h3, h4, h5, h6 {
-    font-weight: 700;
-    font-family: Roboto Slab, serif;
-    margin-bottom: 10px;
-}
-
-.submit-vote.submit-vote-parent.voted a.submit-vote-button, .submit-vote.submit-vote-parent a.submit-vote-button:hover {
-    background-color: $ignite-red;
-}
-
-div.submit-vote.submit-vote-parent.voted a.submit-vote-button:hover {
-    background-color: #950d12;
-}
-
-a, .link .title {
-    color: $ignite-red;
-}
-
-a:hover, .link:hover .title {
-    color: #950d12;
-}
-
-.header h1.navbar-brand a {
-    background-image: url("#{$logo-path}");
-}
-
-.header h1.navbar-brand {
-    width: 96px;
-}
-
-.block-edit-parameters {
-    text-align: right;
-    padding-bottom: 5px;
-}
-
-.container-footer {
-    margin-top: 20px;
-}
-
-/* Modal */
-.modal {
-    display: block;
-    overflow: hidden;
-}
-
-.modal .close {
-    position: absolute;
-    top: 10px;
-    right: 10px;
-    float: none;
-}
-
-// Close icon
-.modal-header .close {
-    margin-right: -2px;
-}
-
-.modal .modal-dialog {
-    width: 610px;
-}
-
-.modal .modal-content {
-    border-radius: 0;
-    background-color: #f7f7f7;
-}
-
-.modal .modal-content .modal-header {
-    background-color: #fff;
-    text-align: center;
-    color: #555;
-    padding: 15px;
-    font-family: "myriad-pro", sans-serif;
-}
-
-.modal .modal-content .modal-header h4 {
-    font-family: "myriad-pro", sans-serif;
-    font-size: 22px;
-}
-
-.modal .modal-content .modal-header h4 .fa {
-    display: block;
-    font-size: 41px;
-    color: #ddd;
-    margin-bottom: 5px;
-}
-
-.modal .modal-content .modal-header p {
-    color: #aaa;
-    font-size: 1em;
-    margin: 3px 0 0;
-}
-
-.modal .modal-content .modal-spacer {
-    padding: 10px 10px 0 10px;
-}
-
-.modal .modal-content .modal-footer {
-    margin-top: 0;
-}
-
-.modal-body {
-    padding-top: 15px;
-}
-
-h1.ignite-logo {
-    background-image: url("#{$logo-path}");
-}
-
-.block-display-image img {
-    max-width: 100%;
-    max-height: 450px;
-    margin: auto;
-    display: block;
-}
-
-.greedy {
-    min-height: 100%;
-    height: #{"calc(100vh - 290px)"};
-}
-
-@media (min-width: 768px) {
-    .navbar-nav > li > a {
-        padding-top: 18px;
-        padding-bottom: 10px;
-    }
-}
-
-.details-row {
-    padding: 0 10px;
-}
-
-.details-row, .settings-row {
-    display: block;
-    margin: 10px 0;
-
-    label.table-header {
-        line-height: $input-height;
-    }
-
-    [class*="col-"] {
-        display: inline-block;
-        vertical-align: middle;
-        float: none;
-
-        padding-left: 0 !important;
-        padding-right: 0 !important;
-    }
-
-    input[type="checkbox"] {
-        line-height: 20px;
-        margin-right: 5px;
-    }
-
-    .checkbox label {
-        line-height: 20px;
-        vertical-align: middle;
-    }
-}
-
-button {
-    margin-right: 5px;
-}
-
-h1,
-h2,
-h3 {
-    user-select: none;
-    font-weight: normal;
-    /* Makes the vertical size of the text the same for all fonts. */
-    line-height: 1;
-}
-
-h3 {
-    color: black;
-    font-size: 1.2em;
-    margin-top: 0;
-    margin-bottom: 1.5em;
-}
-
-table tr:hover {
-    cursor: pointer;
-}
-
-.btn {
-    padding: 3px 6px;
-}
-
-button .caret, .btn .caret {
-    float: right;
-    margin-left: 5px;
-    margin-top: 7px;
-}
-
-.base-control {
-    text-align: left;
-    padding: 3px 3px;
-    height: $input-height;
-}
-
-.form-control {
-    @extend .base-control;
-
-    display: inline-block;
-
-    button {
-        text-align: left;
-    }
-}
-
-.theme-line .panel-heading {
-    padding: 10px 10px;
-    margin: 0;
-
-    h3 {
-        margin-bottom: 0;
-    }
-
-    h3 > a {
-        color: black;
-    }
-}
-
-.theme-line .panel-title {
-    a {
-        color: $ignite-red;
-    }
-
-    h3 {
-        margin-bottom: 20px;
-    }
-}
-
-.theme-line .panel-body {
-    padding: 10px 20px;
-}
-
-.theme-line .main-content a.customize {
-    margin-left: 5px;
-    color: $ignite-red;
-}
-
-.theme-line .panel-collapse {
-    margin: 0;
-}
-
-.theme-line table.links {
-    display: table;
-    table-layout: fixed;
-
-    td {
-        padding-left: 18px;
-    }
-
-    .active a {
-        color: $ignite-red;
-        font-weight: bold;
-    }
-
-    a:hover {
-        color: #950d12;
-    }
-
-    a {
-        color: #666;
-    }
-}
-
-.theme-line table.links-edit {
-    @extend table.links;
-
-    margin-top: 5px;
-    margin-bottom: 5px;
-
-    label {
-        line-height: $input-height;
-        color: #666;
-    }
-}
-
-.theme-line table.links-edit-details {
-    @extend table.links;
-
-    margin-bottom: 10px;
-
-    label {
-        line-height: $input-height;
-        color: #666;
-    }
-
-    td {
-        padding: 0;
-
-        .input-tip {
-            padding: 0;
-        }
-    }
-}
-
-.theme-line table.admin {
-    tr:hover {
-        cursor: default;
-    }
-
-    thead > tr th.header {
-        padding: 0 0 10px;
-
-        div {
-            padding: 0
-        }
-    }
-
-    margin-bottom: 10px;
-
-    label {
-        line-height: $input-height;
-        color: #666;
-    }
-
-    thead > tr th, td {
-        padding: 10px 10px;
-
-        .input-tip {
-            padding: 0;
-        }
-    }
-
-    tfoot > tr > td {
-        padding: 0;
-
-        .pagination {
-            margin: 10px 0;
-
-            > .active > a {
-                color: $ignite-red;
-                font-weight: bold;
-                border-color: #ddd;
-                background-color: #eee;
-            }
-        }
-    }
-}
-
-.theme-line table.sql-results {
-    [class*="col-"] {
-        padding-left: 0 !important;
-        padding-right: 0 !important;
-    }
-
-    td {
-        padding: 3px 6px;
-    }
-
-    > thead > tr > td {
-        padding: 3px 0;
-    }
-
-    thead > tr > th {
-        padding: 3px 6px;
-
-        line-height: $input-height;
-    }
-}
-
-.panel-title a {
-    font-size: 14px;
-}
-
-.panel-details {
-    margin-top: 10px;
-
-    padding: 0;
-
-    border-radius: 5px;
-    border: thin dotted lightgrey;
-}
-
-.table-details {
-    border-radius: 5px;
-    border: thin dotted lightgrey;
-
-    margin-top: 10px;
-
-    padding-left: 10px;
-    padding-right: 5px;
-}
-
-.tooltip.right .tooltip-arrow {
-    border-right-color: $ignite-red;
-}
-
-.tooltip > .tooltip-inner {
-    max-width: 400px;
-    text-align: left;
-    background-color: $ignite-red;
-}
-
-label {
-    font-weight: normal;
-    margin-bottom: 0;
-}
-
-.form-horizontal .checkbox {
-    padding-top: 0;
-}
-
-.input-tip {
-    display: block;
-    overflow: hidden;
-}
-
-.labelField {
-    float: left;
-    margin-right: 5px;
-}
-
-.labelFormField {
-    float: left;
-    line-height: $input-height;
-}
-
-.form-horizontal .form-group {
-    margin: 0;
-}
-
-.form-horizontal .has-feedback .form-control-feedback {
-    right: 0;
-}
-
-.tipField {
-    float: right;
-    line-height: $input-height;
-    margin-left: 5px;
-}
-
-.tipLabel {
-    font-size: 14px;
-    margin-left: 5px;
-}
-
-.fieldSep {
-    float: right;
-    line-height: $input-height;
-    margin: 0 5px;
-}
-
-.fieldButton {
-    float: right;
-    margin-left: 5px;
-    margin-right: 0;
-}
-
-.fa-plus {
-    cursor: pointer;
-}
-
-.fa-remove {
-    color: $ignite-red;
-    cursor: pointer;
-}
-
-.fa-floppy-o {
-    cursor: pointer;
-}
-
-.fa-arrow-up {
-    cursor: pointer;
-}
-
-.fa-arrow-down {
-    cursor: pointer;
-}
-
-label.required:after {
-    color: $ignite-red;
-    content: ' *';
-    display: inline;
-}
-
-.blank {
-    visibility: hidden;
-}
-
-.alert {
-    outline: 0
-}
-
-.alert.bottom, .alert.bottom-left, .alert.bottom-right, .alert.top,
-.alert.top-left, .alert.top-right {
-    position: fixed;
-    z-index: 1050;
-    margin: 20px
-}
-
-.alert.top, .alert.top-left, .alert.top-right {
-    top: 50px
-}
-
-.alert.top {
-    right: 0;
-    left: 0
-}
-
-.alert.top-right {
-    right: 0
-}
-
-.alert.top-right .close {
-    padding-left: 10px
-}
-
-.alert.top-left {
-    left: 0
-}
-
-.alert.top-left .close {
-    padding-right: 10px
-}
-
-.alert.bottom, .alert.bottom-left, .alert.bottom-right {
-    bottom: 0
-}
-
-.alert.bottom {
-    right: 0;
-    left: 0
-}
-
-.alert.bottom-right {
-    right: 0
-}
-
-.alert.bottom-right .close {
-    padding-left: 10px
-}
-
-.alert.bottom-left {
-    left: 0
-}
-
-.alert.bottom-left .close {
-    padding-right: 10px
-}
-
-//  Summary page
-#cfgResult textarea {
-    font-family: monospace;
-    font-size: 12px;
-}
-
-input[type="number"]::-webkit-outer-spin-button,
-input[type="number"]::-webkit-inner-spin-button {
-    -webkit-appearance: none;
-    margin: 0;
-}
-
-input[type="number"] {
-    -moz-appearance: textfield;
-}
-
-input.ng-dirty.ng-invalid, button.ng-dirty.ng-invalid {
-    border-color: $ignite-red;
-
-    :focus {
-        border-color: $ignite-red;
-    }
-}
-
-.form-control-feedback {
-    display: inline-block;
-    color: $ignite-red;
-    right: 18px;
-    line-height: $input-height;
-    pointer-events: initial;
-}
-
-.syntaxhighlighter {
-    padding: 10px 5px;
-    border-radius: 6px;
-}
-
-.theme-line table.links-edit-small-padding {
-    @extend table.links;
-
-    label {
-        line-height: $input-height;
-        color: #666;
-    }
-
-    a {
-        line-height: $input-height;
-    }
-
-    input[type="checkbox"] {
-        line-height: 20px;
-        margin-right: 5px;
-    }
-
-    .checkbox label {
-        line-height: 20px;
-        vertical-align: middle;
-    }
-
-    th {
-        text-align: center;
-    }
-
-    td {
-        padding-left: 10px;
-    }
-
-    margin-top: 10px;
-}
-
-.nav-tabs > li > a {
-    padding: 5px 5px;
-}
-
-.viewedUser {
-    position: absolute;
-    width: 100%;
-    left: 0;
-
-    text-align: center;
-
-    margin-top: -15px;
-
-    background-color: #f8d5d8;
-}
-
-a {
-    cursor: pointer;
-}
-
-.st-sort-ascent:after {
-    content: '\25B2';
-}
-
-.st-sort-descent:after {
-    content: '\25BC';
-}
-
-.panel {
-    margin-bottom: 0;
-}
-
-.panel-group {
-    margin-bottom: 0;
-}
-
-.panel-group .panel + .panel {
-    margin-top: 20px;
-}
-
-.margin-top-dflt {
-    margin-top: 10px;
-}
-
-.margin-bottom-dflt {
-    margin-bottom: 10px;
-}
-
-.margin-dflt {
-    margin-top: 10px;
-    margin-bottom: 10px;
-}
-
-.padding-top-dflt {
-    padding-top: 10px;
-}
-
-.padding-bottom-dflt {
-    padding-bottom: 10px;
-}
-
-.padding-dflt {
-    padding-top: 10px;
-    padding-bottom: 10px;
-}
-
-.theme-line .panel-title h3 {
-    margin-top: 20px;
-    margin-bottom: 20px;
-}
-
-.block-callout-parent {
-    background-color: $ignite-block-callout-background;
-    overflow: hidden;
-}
-
-.block-callout {
-    background-color: $ignite-block-callout-background;
-    display: inline-block;
-    vertical-align: top;
-    width: 50%;
-
-    i {
-        padding: 10px 5px 0 10px;
-        color: $ignite-block-callout;
-    }
-
-    ul {
-        padding-left: 20px;
-        margin-bottom: 0;
-    }
-
-    p {
-        padding: 5px 0 10px 10px;
-        margin: 0;
-    }
-
-    label {
-        font-weight: bold;
-        color: $ignite-block-callout;
-    }
-}
-
-.block-callout-border {
-    border-left: 5px solid;
-    border-color: $ignite-block-callout;
-}
-
-.labelHeader {
-    font-weight: bold;
-}
-
-.ace_editor, #ace_document {
-    margin: 0.65em 0 0 0;
-
-    width: 100%;
-    height: 400px;
-
-    .ace_gutter {
-        background: transparent !important;
-        border: 1px #ddd;
-        border-right-style: solid;
-    }
-
-    .ace_gutter-cell, .ace_folding-enabled > .ace_gutter-cell {
-        padding-left: 0.65em;
-        padding-right: 0.9em;
-    }
-}
-
-.loading-indicator {
-    box-sizing: border-box;
-    -webkit-box-sizing: border-box;
-    -moz-box-sizing: border-box;
-    width: 100%;
-    text-align: center;
-    padding: 0.7em;
-
-    :before {
-        display: inline-block;
-        margin: 0 0.4em;
-        min-width: 1em;
-        min-height: 1em;
-        border: 4px solid #646464;
-        border-right-color: #e6e6e6;
-        border-left-color: #e6e6e6;
-        content: "";
-        -webkit-animation: halfspin 1s ease infinite;
-        -moz-animation: halfspin 1s ease infinite;
-        -o-animation: halfspin 1s ease infinite;
-        animation: halfspin 1s ease infinite;
-        border-radius: 100%;
-    }
-}
-
-@-webkit-keyframes halfspin {
-    to {
-        -webkit-transform: rotate(180deg);
-        -moz-transform: rotate(180deg);
-        transform: rotate(180deg);
-    }
-}
-
-@-moz-keyframes halfspin {
-    to {
-        -webkit-transform: rotate(180deg);
-        -moz-transform: rotate(180deg);
-        transform: rotate(180deg);
-    }
-}
-
-@keyframes halfspin {
-    to {
-        -webkit-transform: rotate(180deg);
-        -moz-transform: rotate(180deg);
-        transform: rotate(180deg);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/web-control-center/src/main/js/routes/admin.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/routes/admin.js b/modules/web-control-center/src/main/js/routes/admin.js
deleted file mode 100644
index 5af72f7..0000000
--- a/modules/web-control-center/src/main/js/routes/admin.js
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-var router = require('express').Router();
-var db = require('../db');
-
-router.get('/', function (req, res) {
-    res.render('settings/admin');
-});
-
-/**
- * Get list of user accounts.
- */
-router.post('/list', function (req, res) {
-    db.Account.find({}).sort('username').exec(function (err, users) {
-        if (err)
-            return res.status(500).send(err.message);
-
-        res.json(users);
-    });
-});
-
-router.post('/remove', function (req, res) {
-    var userId = req.body.userId;
-
-    db.Account.findByIdAndRemove(userId, function (err) {
-        if (err)
-            return res.status(500).send(err);
-
-        res.sendStatus(200);
-    });
-});
-
-router.post('/save', function (req, res) {
-    var userId = req.body.userId;
-    var adminFlag = req.body.adminFlag;
-
-    db.Account.findByIdAndUpdate(userId, {admin: adminFlag}, function (err) {
-        if (err)
-            return res.status(500).send(err.message);
-
-        res.sendStatus(200);
-    });
-});
-
-router.get('/become', function (req, res) {
-    var viewedUserId = req.query.viewedUserId;
-
-    if (!viewedUserId) {
-        req.session.viewedUser = null;
-
-        return res.redirect('/admin');
-    }
-
-    db.Account.findById(viewedUserId).exec(function (err, viewedUser) {
-        if (err)
-            return res.sendStatus(404);
-
-        req.session.viewedUser = viewedUser;
-
-        res.redirect('/');
-    })
-});
-
-module.exports = router;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/web-control-center/src/main/js/routes/caches.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/routes/caches.js b/modules/web-control-center/src/main/js/routes/caches.js
deleted file mode 100644
index 24152af..0000000
--- a/modules/web-control-center/src/main/js/routes/caches.js
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-var router = require('express').Router();
-var db = require('../db');
-
-/* GET caches page. */
-router.get('/', function (req, res) {
-    res.render('configuration/caches');
-});
-
-/**
- * Get spaces and caches accessed for user account.
- *
- * @param req Request.
- * @param res Response.
- */
-router.post('/list', function (req, res) {
-    var user_id = req.currentUserId();
-
-    // Get owned space and all accessed space.
-    db.Space.find({$or: [{owner: user_id}, {usedBy: {$elemMatch: {account: user_id}}}]}, function (err, spaces) {
-        if (err)
-            return res.status(500).send(err.message);
-
-        var space_ids = spaces.map(function (value) {
-            return value._id;
-        });
-
-        // Get all caches type metadata for spaces.
-        db.CacheTypeMetadata.find({space: {$in: space_ids}}, '_id name kind', function (err, metadatas) {
-            if (err)
-                return res.status(500).send(err);
-
-            // Get all caches for spaces.
-            db.Cache.find({space: {$in: space_ids}}).sort('name').exec(function (err, caches) {
-                if (err)
-                    return res.status(500).send(err.message);
-
-                var metadatasJson = metadatas.map(function (meta) {
-                    return {value: meta._id, label: meta.name, kind: meta.kind};
-                });
-
-                res.json({spaces: spaces, metadatas: metadatasJson, caches: caches});
-            });
-        });
-    });
-});
-
-/**
- * Save cache.
- */
-router.post('/save', function (req, res) {
-    if (req.body._id)
-        db.Cache.update({_id: req.body._id}, req.body, {upsert: true}, function (err) {
-            if (err)
-                return res.status(500).send(err.message);
-
-            res.send(req.body._id);
-        });
-    else {
-        db.Cache.findOne({space: req.body.space, name: req.body.name}, function (err, cache) {
-            if (err)
-                return res.status(500).send(err.message);
-
-            if (cache)
-                return res.status(500).send('Cache with name: "' + cache.name + '" already exist.');
-
-            (new db.Cache(req.body)).save(function (err, cache) {
-                if (err)
-                    return res.status(500).send(err.message);
-
-                res.send(cache._id);
-            });
-        });
-    }
-});
-
-/**
- * Remove cache by ._id.
- */
-router.post('/remove', function (req, res) {
-    db.Cache.remove(req.body, function (err) {
-        if (err)
-            return res.status(500).send(err.message);
-
-        res.sendStatus(200);
-    })
-});
-
-module.exports = router;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/web-control-center/src/main/js/routes/clusters.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/routes/clusters.js b/modules/web-control-center/src/main/js/routes/clusters.js
deleted file mode 100644
index 683630e..0000000
--- a/modules/web-control-center/src/main/js/routes/clusters.js
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-var router = require('express').Router();
-var db = require('../db');
-
-/* GET clusters page. */
-router.get('/', function (req, res) {
-    res.render('configuration/clusters');
-});
-
-/**
- * Get spaces and clusters accessed for user account.
- *
- * @param req Request.
- * @param res Response.
- */
-router.post('/list', function (req, res) {
-    var user_id = req.currentUserId();
-
-    // Get owned space and all accessed space.
-    db.Space.find({$or: [{owner: user_id}, {usedBy: {$elemMatch: {account: user_id}}}]}, function (err, spaces) {
-        if (err)
-            return res.status(500).send(err.message);
-
-        var space_ids = spaces.map(function (value) {
-            return value._id;
-        });
-
-        db.Cache.find({space: {$in: space_ids}}, '_id name swapEnabled', function (err, caches) {
-            if (err)
-                return res.status(500).send(err);
-
-            // Get all clusters for spaces.
-            db.Cluster.find({space: {$in: space_ids}}).sort('name').exec(function (err, clusters) {
-                if (err)
-                    return res.status(500).send(err.message);
-
-                var cachesJson = caches.map(function (cache) {
-                    return {value: cache._id, label: cache.name, swapEnabled: cache.swapEnabled};
-                });
-
-                res.json({spaces: spaces, caches: cachesJson, clusters: clusters});
-            });
-        });
-    });
-});
-
-/**
- * Save cluster.
- */
-router.post('/save', function (req, res) {
-    if (req.body._id)
-        db.Cluster.update({_id: req.body._id}, req.body, {upsert: true}, function (err) {
-            if (err)
-                return res.status(500).send(err.message);
-
-            res.send(req.body._id);
-        });
-    else {
-        db.Cluster.findOne({space: req.body.space, name: req.body.name}, function (err, cluster) {
-            if (err)
-                return res.status(500).send(err.message);
-
-            if (cluster)
-                return res.status(500).send('Cluster with name: "' + cluster.name + '" already exist.');
-
-            (new db.Cluster(req.body)).save(function (err, cluster) {
-                if (err)
-                    return res.status(500).send(err.message);
-
-                res.send(cluster._id);
-            });
-        });
-    }
-});
-
-/**
- * Remove cluster by ._id.
- */
-router.post('/remove', function (req, res) {
-    db.Cluster.remove(req.body, function (err) {
-        if (err)
-            return res.status(500).send(err.message);
-
-        res.sendStatus(200);
-    })
-});
-
-module.exports = router;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/web-control-center/src/main/js/routes/generator/common.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/routes/generator/common.js b/modules/web-control-center/src/main/js/routes/generator/common.js
deleted file mode 100644
index 44ddf31..0000000
--- a/modules/web-control-center/src/main/js/routes/generator/common.js
+++ /dev/null
@@ -1,312 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-var _ = require('lodash');
-
-exports.isDefined = function (v) {
-    return !(v === undefined || v === null);
-};
-
-exports.mainComment = mainComment;
-
-function mainComment() {
-    return 'This configuration was generated by Ignite Control Center ('
-        + formatDate(new Date()) + ')';
-}
-
-function addLeadingZero(numberStr, minSize) {
-    if (typeof (numberStr) != 'string')
-        numberStr = '' + numberStr;
-
-    while (numberStr.length < minSize) {
-        numberStr = '0' + numberStr;
-    }
-
-    return numberStr;
-}
-
-exports.formatDate = formatDate;
-
-function formatDate(date) {
-    var dd = addLeadingZero(date.getDate(), 2);
-    var mm = addLeadingZero(date.getMonth() + 1, 2);
-
-    var yyyy = date.getFullYear();
-
-    return mm + '/' + dd + '/' + yyyy + ' ' + addLeadingZero(date.getHours(), 2) + ':' + addLeadingZero(date.getMinutes(), 2);
-}
-
-exports.builder = function () {
-    var res = [];
-
-    res.deep = 0;
-    res.lineStart = true;
-
-    res.append = function (s) {
-        if (this.lineStart) {
-            for (var i = 0; i < this.deep; i++)
-                this.push('    ');
-
-            this.lineStart = false;
-        }
-
-        this.push(s);
-
-        return this;
-    };
-
-    res.line = function (s) {
-        if (s)
-            this.append(s);
-
-        this.push('\n');
-        this.lineStart = true;
-
-        return this;
-    };
-
-    res.startBlock = function (s) {
-        if (s)
-            this.append(s);
-
-        this.push('\n');
-        this.lineStart = true;
-        this.deep++;
-
-        return this;
-    };
-
-    res.endBlock = function (s) {
-        this.deep--;
-
-        if (s)
-            this.append(s);
-
-        this.push('\n');
-        this.lineStart = true;
-
-        return this;
-    };
-
-    res.emptyLineIfNeeded = function () {
-        if (this.needEmptyLine) {
-            this.line();
-
-            this.needEmptyLine = false;
-
-            return true;
-        }
-
-        return false;
-    };
-
-    res.imports = {};
-
-    res.importClass = function (fullClassName) {
-        var dotIdx = fullClassName.lastIndexOf('.');
-
-        var shortName;
-
-        if (dotIdx > 0)
-            shortName = fullClassName.substr(dotIdx + 1);
-        else
-            shortName = fullClassName;
-
-        if (this.imports[shortName]) {
-            if (this.imports[shortName] != fullClassName)
-                throw "Class name conflict: " + this.imports[shortName] + ' and ' + fullClassName;
-        }
-        else {
-            this.imports[shortName] = fullClassName;
-        }
-
-        return shortName;
-    };
-
-    res.generateImports = function () {
-        var res = [];
-
-        for (var clsName in this.imports) {
-            if (this.imports.hasOwnProperty(clsName))
-                res.push('import ' + this.imports[clsName] + ';');
-        }
-
-        return res.join('\n')
-    };
-
-    return res;
-};
-
-function ClassDescriptor(className, fields) {
-    this.className = className;
-    this.fields = fields;
-}
-
-exports.evictionPolicies = {
-    'LRU': new ClassDescriptor('org.apache.ignite.cache.eviction.lru.LruEvictionPolicy',
-        {batchSize: null, maxMemorySize: null, maxSize: null}),
-    'RND': new ClassDescriptor('org.apache.ignite.cache.eviction.random.RandomEvictionPolicy', {maxSize: null}),
-    'FIFO': new ClassDescriptor('org.apache.ignite.cache.eviction.fifo.FifoEvictionPolicy',
-        {batchSize: null, maxMemorySize: null, maxSize: null}),
-    'SORTED': new ClassDescriptor('org.apache.ignite.cache.eviction.sorted.SortedEvictionPolicy',
-        {batchSize: null, maxMemorySize: null, maxSize: null})
-};
-
-exports.marshallers = {
-    OptimizedMarshaller: new ClassDescriptor('org.apache.ignite.marshaller.optimized.OptimizedMarshaller', {
-        poolSize: null,
-        requireSerializable: null
-    }),
-    JdkMarshaller: new ClassDescriptor('org.apache.ignite.marshaller.jdk.JdkMarshaller', {})
-};
-
-var javaBuildInClasses = {
-    BigDecimal: {className: 'java.math.Boolean'},
-    Boolean: {className: 'java.lang.Boolean'},
-    Byte: {className: 'java.lang.Byte'},
-    Date: {className: 'java.sql.Date'},
-    Double: {className: 'java.lang.Double'},
-    Float: {className: 'java.lang.Float'},
-    Integer: {className: 'java.lang.Integer'},
-    Long: {className: 'java.lang.Long'},
-    Short: {className: 'java.lang.Short'},
-    String: {className: 'java.lang.String'},
-    Time: {className: 'java.sql.Time'},
-    Timestamp: {className: 'java.sql.Timestamp'},
-    UUID: {className: 'java.util.UUID'}
-};
-
-exports.javaBuildInClass = function (className) {
-    var fullClassName = javaBuildInClasses[className];
-
-    if (fullClassName)
-        return fullClassName.className;
-
-    return className;
-};
-
-exports.knownClasses = {
-    Oracle: new ClassDescriptor('org.apache.ignite.cache.store.jdbc.dialect.OracleDialect', {}),
-    DB2: new ClassDescriptor('org.apache.ignite.cache.store.jdbc.dialect.DB2Dialect', {}),
-    SQLServer: new ClassDescriptor('org.apache.ignite.cache.store.jdbc.dialect.SQLServerDialect', {}),
-    MySQL: new ClassDescriptor('org.apache.ignite.cache.store.jdbc.dialect.MySQLDialect', {}),
-    PostgreSQL: new ClassDescriptor('org.apache.ignite.cache.store.jdbc.dialect.BasicJdbcDialect', {}),
-    H2: new ClassDescriptor('org.apache.ignite.cache.store.jdbc.dialect.H2Dialect', {})
-};
-
-exports.dataSources = {
-    Oracle: 'oracle.jdbc.pool.OracleDataSource',
-    DB2: 'com.ibm.db2.jcc.DB2ConnectionPoolDataSource',
-    SQLServer: 'com.microsoft.sqlserver.jdbc.SQLServerDataSource',
-    MySQL: 'com.mysql.jdbc.jdbc2.optional.MysqlDataSource',
-    PostgreSQL: 'org.postgresql.ds.PGPoolingDataSource',
-    H2: 'org.h2.jdbcx.JdbcDataSource'
-};
-
-exports.storeFactories = {
-    CacheJdbcPojoStoreFactory: new ClassDescriptor('org.apache.ignite.cache.store.jdbc.CacheJdbcPojoStoreFactory', {
-        dataSourceBean: null,
-        dialect: {type: 'className'}
-    }),
-
-    CacheJdbcBlobStoreFactory: new ClassDescriptor('org.apache.ignite.cache.store.jdbc.CacheJdbcBlobStoreFactory', {
-        user: null,
-        dataSourceBean: null,
-        initSchema: null,
-        createTableQuery: null,
-        loadQuery: null,
-        insertQuery: null,
-        updateQuery: null,
-        deleteQuery: null
-    }),
-
-    CacheHibernateBlobStoreFactory: new ClassDescriptor('org.apache.ignite.cache.store.hibernate.CacheHibernateBlobStoreFactory', {
-        hibernateProperties: {type: 'propertiesAsList', propVarName: 'props'}
-    })
-};
-
-exports.atomicConfiguration = new ClassDescriptor('org.apache.ignite.configuration.AtomicConfiguration', {
-    backups: null,
-    cacheMode: {type: 'enum', enumClass: 'CacheMode'},
-    atomicSequenceReserveSize: null
-});
-
-exports.swapSpaceSpi = new ClassDescriptor('org.apache.ignite.spi.swapspace.file.FileSwapSpaceSpi', {
-    baseDirectory: null,
-    readStripesNumber: null,
-    maximumSparsity: {type: 'float'},
-    maxWriteQueueSize: null,
-    writeBufferSize: null
-});
-
-exports.transactionConfiguration = new ClassDescriptor('org.apache.ignite.configuration.TransactionConfiguration', {
-    defaultTxConcurrency: {type: 'enum', enumClass: 'TransactionConcurrency'},
-    transactionIsolation: {type: 'TransactionIsolation', setterName: 'defaultTxIsolation'},
-    defaultTxTimeout: null,
-    pessimisticTxLogLinger: null,
-    pessimisticTxLogSize: null,
-    txSerializableEnabled: null
-});
-
-exports.hasProperty = function (obj, props) {
-    for (var propName in props) {
-        if (props.hasOwnProperty(propName)) {
-            if (obj[propName])
-                return true;
-        }
-    }
-
-    return false;
-};
-
-/**
- * Generate properties file with properties stubs for stores data sources.
- *
- * @param cluster Configuration to process.
- * @returns {string} Generated content.
- */
-exports.generateProperties = function (cluster) {
-    var res = exports.builder();
-
-    var datasources = [];
-
-    if (cluster.caches && cluster.caches.length > 0) {
-        _.forEach(cluster.caches, function (cache) {
-            if (cache.cacheStoreFactory && cache.cacheStoreFactory.kind) {
-                var storeFactory = cache.cacheStoreFactory[cache.cacheStoreFactory.kind];
-
-                if (storeFactory.dialect) {
-                    var beanId = storeFactory.dataSourceBean;
-
-                    if (!_.contains(datasources, beanId)) {
-                        datasources.push(beanId);
-
-                        res.line(beanId + '.jdbc.url=YOUR_JDBC_URL');
-                        res.line(beanId + '.jdbc.username=YOUR_USER_NAME');
-                        res.line(beanId + '.jdbc.password=YOUR_PASSWORD');
-                        res.line();
-                    }
-                }
-            }
-        });
-    }
-
-    if (datasources.length > 0)
-        return '# ' + mainComment() + '\n\n' + res.join();
-
-    return undefined;
-};

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/web-control-center/src/main/js/routes/generator/docker.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/routes/generator/docker.js b/modules/web-control-center/src/main/js/routes/generator/docker.js
deleted file mode 100644
index 93faf8e..0000000
--- a/modules/web-control-center/src/main/js/routes/generator/docker.js
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-exports.generateClusterConfiguration = function(cluster, os) {
-    if (!os)
-        os = 'debian:8';
-
-    return "" +
-        "# Start from a OS image.\n"+
-        "FROM " + os + "\n"+
-        "\n"+
-        "# Install tools.\n"+
-        "RUN apt-get update && apt-get install -y --fix-missing \\\n"+
-        "  wget \\\n"+
-        "  dstat \\\n"+
-        "  maven \\\n"+
-        "  git\n"+
-        "\n"+
-        "# Install Oracle JDK.\n"+
-        "RUN mkdir /opt/jdk\n"+
-        "\n"+
-        "RUN wget --header \"Cookie: oraclelicense=accept-securebackup-cookie\" \\\n"+
-        "  http://download.oracle.com/otn-pub/java/jdk/7u79-b15/jdk-7u79-linux-x64.tar.gz\n"+
-        "\n"+
-        "RUN tar -zxf jdk-7u79-linux-x64.tar.gz -C /opt/jdk\n"+
-        "\n"+
-        "RUN rm jdk-7u79-linux-x64.tar.gz\n"+
-        "\n"+
-        "RUN update-alternatives --install /usr/bin/java java /opt/jdk/jdk1.7.0_79/bin/java 100\n"+
-        "\n"+
-        "RUN update-alternatives --install /usr/bin/javac javac /opt/jdk/jdk1.7.0_79/bin/javac 100\n"+
-        "\n"+
-        "# Sets java variables.\n"+
-        "ENV JAVA_HOME /opt/jdk/jdk1.7.0_79/\n"+
-        "\n"+
-        "# Create working directory\n"+
-        "WORKDIR /home\n"+
-        "\n"+
-        "RUN wget -O ignite.zip http://tiny.cc/updater/download_ignite.php && unzip ignite.zip && rm ignite.zip\n"+
-        "\n"+
-        "COPY *.xml /tmp/\n"+
-        "\n"+
-        "RUN mv /tmp/*.xml /home/$(ls)/config";
-};


[17/41] incubator-ignite git commit: Merge branch 'ignite-843' of https://git-wip-us.apache.org/repos/asf/incubator-ignite into ignite-1121

Posted by an...@apache.org.
Merge branch 'ignite-843' of https://git-wip-us.apache.org/repos/asf/incubator-ignite into ignite-1121


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

Branch: refs/heads/ignite-1121
Commit: 49bf1e26706f7b5451c7b40ec5f9059bfd00d016
Parents: f58d813 ce7ab19
Author: Andrey <an...@gridgain.com>
Authored: Tue Jul 28 10:56:53 2015 +0700
Committer: Andrey <an...@gridgain.com>
Committed: Tue Jul 28 10:56:53 2015 +0700

----------------------------------------------------------------------
 .../main/js/controllers/caches-controller.js    |   1 +
 .../src/main/js/controllers/common-module.js    |   5 +-
 .../main/js/controllers/metadata-controller.js  |  63 +++++-----
 .../main/js/controllers/models/metadata.json    |   4 +-
 modules/web-control-center/src/main/js/db.js    |  20 +++-
 .../web-control-center/src/main/js/package.json |   1 +
 .../src/main/js/routes/generator/common.js      |  16 +++
 .../src/main/js/routes/generator/xml.js         | 114 +++++++++++++++++--
 .../src/main/js/routes/summary.js               |   2 +-
 .../src/main/js/views/configuration/caches.jade |   2 +-
 .../main/js/views/configuration/clusters.jade   |   2 +-
 .../main/js/views/configuration/metadata.jade   |   8 +-
 .../main/js/views/configuration/summary.jade    |  27 +++--
 .../src/main/js/views/includes/controls.jade    |  44 ++++---
 .../src/main/js/views/login.jade                |   4 +-
 .../src/main/js/views/settings/admin.jade       |   2 +-
 .../src/main/js/views/settings/profile.jade     |   2 +-
 .../src/main/js/views/sql/sql.jade              |   2 +-
 .../src/main/js/views/templates/confirm.jade    |   6 +-
 .../src/main/js/views/templates/copy.jade       |   8 +-
 .../src/main/js/views/templates/tab.jade        |   2 +-
 21 files changed, 237 insertions(+), 98 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/49bf1e26/modules/web-control-center/src/main/js/package.json
----------------------------------------------------------------------


[28/41] incubator-ignite git commit: # ignite-843 Rename

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/web-control-center/src/main/js/routes/generator/java.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/routes/generator/java.js b/modules/web-control-center/src/main/js/routes/generator/java.js
deleted file mode 100644
index 41b9bb8..0000000
--- a/modules/web-control-center/src/main/js/routes/generator/java.js
+++ /dev/null
@@ -1,788 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-var _ = require('lodash');
-
-var generatorUtils = require("./common");
-
-/**
- * Convert some name to valid java name.
- *
- * @param name to convert.
- * @returns {string} Valid java name.
- */
-function toJavaName(name) {
-    var javaName = name.replace(/[^A-Za-z_0-9]+/, '_');
-
-    return javaName.charAt(0).toLocaleUpperCase() + javaName.slice(1);
-}
-
-exports.generateClusterConfiguration = function(cluster, javaClass, clientNearConfiguration) {
-    var res = generatorUtils.builder();
-
-    res.datasourceBeans = [];
-
-    if (javaClass) {
-        res.line('/**');
-        res.line(' * ' + generatorUtils.mainComment());
-        res.line(' */');
-        res.startBlock('public class ConfigurationFactory {');
-        res.line('/**');
-        res.line(' * Configure grid.');
-        res.line(' */');
-        res.startBlock('public IgniteConfiguration createConfiguration() {');
-    }
-    
-    res.importClass('org.apache.ignite.configuration.IgniteConfiguration');
-    
-    res.line('IgniteConfiguration cfg = new IgniteConfiguration();');
-    res.line();
-
-    if (clientNearConfiguration) {
-        res.line('cfg.setClientMode(true);');
-
-        res.line();
-    }
-
-    if (cluster.discovery) {
-        var d = cluster.discovery;
-
-        res.importClass('org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi');
-        res.line('TcpDiscoverySpi discovery = new TcpDiscoverySpi();');
-
-        switch (d.kind) {
-            case 'Multicast':
-                res.importClass('org.apache.ignite.spi.discovery.tcp.ipfinder.multicast.TcpDiscoveryMulticastIpFinder');
-
-                addBeanWithProperties(res, d.Multicast, 'discovery', 'ipFinder', 'ipFinder',
-                    'TcpDiscoveryMulticastIpFinder', {
-                        multicastGroup: null,
-                        multicastPort: null,
-                        responseWaitTime: null,
-                        addressRequestAttempts: null,
-                        localAddress: null
-                    }, true);
-
-                break;
-
-            case 'Vm':
-                res.importClass('org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder');
-
-                addBeanWithProperties(res, d.Vm, 'discovery', 'ipFinder', 'ipFinder', 'TcpDiscoveryVmIpFinder', {
-                        addresses: {type: 'list'}
-                    }, true);
-
-                break;
-
-            case 'S3':
-                res.importClass('org.apache.ignite.spi.discovery.tcp.ipfinder.s3.TcpDiscoveryS3IpFinder');
-
-                if (d.S3)
-                    addBeanWithProperties(res, d.S3, 'discovery', 'ipFinder', 'ipFinder', 'TcpDiscoveryS3IpFinder',
-                        {bucketName: null}, true);
-                else
-                    res.line('discovery.setIpFinder(new TcpDiscoveryS3IpFinder());');
-
-                break;
-
-            case 'Cloud':
-                res.importClass('org.apache.ignite.spi.discovery.tcp.ipfinder.cloud.TcpDiscoveryCloudIpFinder');
-
-                addBeanWithProperties(res, d.Cloud, 'discovery', 'ipFinder', 'ipFinder', 'TcpDiscoveryCloudIpFinder', {
-                        credential: null,
-                        credentialPath: null,
-                        identity: null,
-                        provider: null,
-                        regions: {type: 'list'},
-                        zones: {type: 'list'}
-                    }, true);
-
-                break;
-
-            case 'GoogleStorage':
-                res.importClass('org.apache.ignite.spi.discovery.tcp.ipfinder.gce.TcpDiscoveryGoogleStorageIpFinder');
-
-                addBeanWithProperties(res, d.GoogleStorage, 'discovery', 'ipFinder', 'ipFinder',
-                    'TcpDiscoveryGoogleStorageIpFinder', {
-                        projectName: null,
-                        bucketName: null,
-                        serviceAccountP12FilePath: null
-                    }, true);
-
-                //if (d.GoogleStorage.addrReqAttempts) todo ????
-                //    res.line('<property name="serviceAccountP12FilePath" value="' + escapeAttr(d.GoogleStorage.addrReqAttempts) + '"/>');
-
-                break;
-
-            case 'Jdbc':
-                res.importClass('org.apache.ignite.spi.discovery.tcp.ipfinder.jdbc.TcpDiscoveryJdbcIpFinder');
-                
-                res.line();
-                res.line('TcpDiscoveryJdbcIpFinder ipFinder = new TcpDiscoveryJdbcIpFinder();');
-                res.line('ipFinder.setInitSchema(' + (d.Jdbc.initSchema != null || d.Jdbc.initSchema) + ');');
-                res.line('discovery.setIpFinder(ipFinder);');
-                res.needEmptyLine = true;
-
-                break;
-
-            case 'SharedFs':
-                res.importClass('org.apache.ignite.spi.discovery.tcp.ipfinder.sharedfs.TcpDiscoverySharedFsIpFinder');
-
-                addBeanWithProperties(res, d.SharedFs, 'discovery', 'ipFinder', 'ipFinder',
-                    'TcpDiscoverySharedFsIpFinder', {path: null}, true);
-
-                break;
-
-            default:
-                throw "Unknown discovery kind: " + d.kind;
-        }
-
-        res.emptyLineIfNeeded();
-
-        res.line('cfg.setDiscoverySpi(discovery);');
-
-        res.needEmptyLine = true;
-    }
-
-    if (cluster.caches && cluster.caches.length > 0) {
-        res.emptyLineIfNeeded();
-
-        var names = [];
-
-        for (var i = 0; i < cluster.caches.length; i++) {
-            res.emptyLineIfNeeded();
-
-            var cache = cluster.caches[i];
-
-            var cacheName = 'cache' + toJavaName(cache.name);
-
-            names.push(cacheName);
-
-            generateCacheConfiguration(res, cache, cacheName);
-
-            res.needEmptyLine = true;
-        }
-
-        res.emptyLineIfNeeded();
-
-        res.append('cfg.setCacheConfiguration(');
-
-        for (i = 0; i < names.length; i++) {
-            if (i > 0)
-                res.append(', ');
-
-            res.append(names[i]);
-        }
-
-        res.line(');');
-
-        res.needEmptyLine = true;
-    }
-
-    addBeanWithProperties(res, cluster.atomicConfiguration, 'cfg', 'atomicConfiguration', 'atomicCfg',
-        generatorUtils.atomicConfiguration.className, generatorUtils.atomicConfiguration.fields);
-
-    res.needEmptyLine = true;
-
-    addProperty(res, cluster, 'cfg', 'networkTimeout');
-    addProperty(res, cluster, 'cfg', 'networkSendRetryDelay');
-    addProperty(res, cluster, 'cfg', 'networkSendRetryCount');
-    addProperty(res, cluster, 'cfg', 'segmentCheckFrequency');
-    addProperty(res, cluster, 'cfg', 'waitForSegmentOnStart');
-    addProperty(res, cluster, 'cfg', 'discoveryStartupDelay');
-
-    res.needEmptyLine = true;
-
-    addProperty(res, cluster, 'cfg', 'deploymentMode', 'DeploymentMode');
-
-    res.needEmptyLine = true;
-
-    if (cluster.includeEventTypes && cluster.includeEventTypes.length > 0) {
-        res.emptyLineIfNeeded();
-        
-        if (cluster.includeEventTypes.length == 1) {
-            res.importClass('org.apache.ignite.events.EventType');
-            
-            res.line('cfg.setIncludeEventTypes(EventType.' + cluster.includeEventTypes[0] + ');');
-        }
-        else {
-            res.append('int[] events = new int[EventType.' + cluster.includeEventTypes[0] + '.length');
-            
-            for (i = 1; i < cluster.includeEventTypes.length; i++) {
-                res.line();
-                
-                res.append('    + EventType.' + cluster.includeEventTypes[i] + '.length');
-            }
-            
-            res.line('];');
-            res.line();
-            res.line('int k = 0;');
-
-            for (i = 0; i < cluster.includeEventTypes.length; i++) {
-                res.line();
-
-                var e = cluster.includeEventTypes[i];
-                
-                res.line('System.arraycopy(EventType.' + e + ', 0, events, k, EventType.' + e + '.length);');
-                res.line('k += EventType.' + e + '.length;');
-            }
-            
-            res.line();
-            res.line('cfg.setIncludeEventTypes(events);');
-        }
-
-        res.needEmptyLine = true;
-    }
-
-    res.needEmptyLine = true;
-
-    var marshaller = cluster.marshaller;
-
-    if (marshaller && marshaller.kind) {
-        var marshallerDesc = generatorUtils.marshallers[marshaller.kind];
-
-        addBeanWithProperties(res, marshaller[marshaller.kind], 'cfg', 'marshaller', 'marshaller',
-            marshallerDesc.className, marshallerDesc.fields, true);
-
-        addBeanWithProperties(res, marshaller[marshaller.kind], 'marshaller', marshallerDesc.className, marshallerDesc.fields, true);
-    }
-
-    addProperty(res, cluster, 'cfg', 'marshalLocalJobs');
-    addProperty(res, cluster, 'cfg', 'marshallerCacheKeepAliveTime');
-    addProperty(res, cluster, 'cfg', 'marshallerCacheThreadPoolSize');
-
-    res.needEmptyLine = true;
-
-    addProperty(res, cluster, 'cfg', 'metricsExpireTime');
-    addProperty(res, cluster, 'cfg', 'metricsHistorySize');
-    addProperty(res, cluster, 'cfg', 'metricsLogFrequency');
-    addProperty(res, cluster, 'cfg', 'metricsUpdateFrequency');
-    res.needEmptyLine = true;
-
-    addProperty(res, cluster, 'cfg', 'peerClassLoadingEnabled');
-    addMultiparamProperty(res, cluster, 'cfg', 'peerClassLoadingLocalClassPathExclude');
-    addProperty(res, cluster, 'cfg', 'peerClassLoadingMissedResourcesCacheSize');
-    addProperty(res, cluster, 'cfg', 'peerClassLoadingThreadPoolSize');
-    res.needEmptyLine = true;
-
-    if (cluster.swapSpaceSpi && cluster.swapSpaceSpi.kind == 'FileSwapSpaceSpi') {
-        addBeanWithProperties(res, cluster.swapSpaceSpi.FileSwapSpaceSpi, 'cfg', 'swapSpaceSpi', 'swapSpi',
-            generatorUtils.swapSpaceSpi.className, generatorUtils.swapSpaceSpi.fields, true);
-
-        res.needEmptyLine = true;
-    }
-
-    addProperty(res, cluster, 'cfg', 'clockSyncSamples');
-    addProperty(res, cluster, 'cfg', 'clockSyncFrequency');
-    addProperty(res, cluster, 'cfg', 'timeServerPortBase');
-    addProperty(res, cluster, 'cfg', 'timeServerPortRange');
-
-    res.needEmptyLine = true;
-
-    addProperty(res, cluster, 'cfg', 'publicThreadPoolSize');
-    addProperty(res, cluster, 'cfg', 'systemThreadPoolSize');
-    addProperty(res, cluster, 'cfg', 'managementThreadPoolSize');
-    addProperty(res, cluster, 'cfg', 'igfsThreadPoolSize');
-
-    res.needEmptyLine = true;
-
-    addBeanWithProperties(res, cluster.transactionConfiguration, 'cfg', 'transactionConfiguration',
-        'transactionConfiguration', generatorUtils.transactionConfiguration.className,
-        generatorUtils.transactionConfiguration.fields);
-
-    res.needEmptyLine = true;
-
-    addProperty(res, cluster, 'cfg', 'cacheSanityCheckEnabled');
-
-    res.needEmptyLine = true;
-
-    if (javaClass) {
-        res.line();
-        res.line('return cfg;');
-        res.endBlock('}');
-        res.endBlock('}');
-        
-        return res.generateImports() + '\n\n' + res.join('')
-    }
-    
-    return res.join('');
-};
-
-function createEvictionPolicy(res, evictionPolicy, varName, propertyName) {
-    if (evictionPolicy && evictionPolicy.kind) {
-        var e = generatorUtils.evictionPolicies[evictionPolicy.kind];
-
-        var obj = evictionPolicy[evictionPolicy.kind.toUpperCase()];
-
-        addBeanWithProperties(res, obj, varName, propertyName, propertyName, e.className, e.fields, true);
-    }
-}
-
-function addCacheTypeMetadataDatabaseFields(res, meta, varName, fieldsProperty) {
-    var fields = meta[fieldsProperty];
-
-    if (fields && fields.length > 0) {
-        res.line('addCacheTypeMetadataDatabaseFields for ' + varName);
-        //res.startBlock('<property name="' + fieldsProperty + '">');
-        //
-        //res.startBlock('<list>');
-        //
-        //_.forEach(fields, function (field) {
-        //    res.startBlock('<bean class="org.apache.ignite.cache.CacheTypeFieldMetadata">');
-        //
-        //    addProperty(res, field, 'databaseName');
-        //
-        //    res.startBlock('<property name="databaseType">');
-        //    res.line('<util:constant static-field="java.sql.Types.' + field.databaseType + '"/>');
-        //    res.endBlock('</property>');
-        //
-        //    addProperty(res, field, 'javaName');
-        //
-        //    addElement(res, 'property', 'name', 'javaType', 'value', generatorUtils.javaBuildInClass(field.javaType));
-        //
-        //    res.endBlock('</bean>');
-        //});
-        //
-        //res.endBlock('</list>');
-        //res.endBlock('</property>');
-    }
-}
-
-function addCacheTypeMetadataQueryFields(res, meta, varName, fieldsProperty) {
-    var fields = meta[fieldsProperty];
-
-    if (fields && fields.length > 0) {
-        res.line('addCacheTypeMetadataQueryFields for ' + varName);
-        //res.startBlock('<property name="' + fieldsProperty + '">');
-        //
-        //res.startBlock('<map>');
-        //
-        //_.forEach(fields, function (field) {
-        //    addElement(res, 'entry', 'key', field.name, 'value', generatorUtils.javaBuildInClass(field.className));
-        //});
-        //
-        //res.endBlock('</map>');
-        //
-        //res.endBlock('</property>');
-    }
-}
-
-function addCacheTypeMetadataGroups(res, meta, varName) {
-    var groups = meta.groups;
-
-    if (groups && groups.length > 0) {
-        res.line('addCacheTypeMetadataGroups for ' + varName);
-        //res.startBlock('<property name="groups">');
-        //res.startBlock('<map>');
-        //
-        //_.forEach(groups, function (group) {
-        //    var fields = group.fields;
-        //
-        //    if (fields && fields.length > 0) {
-        //        res.startBlock('<entry key="' + group.name + '">');
-        //        res.startBlock('<map>');
-        //
-        //        _.forEach(fields, function (field) {
-        //            res.startBlock('<entry key="' + field.name + '">');
-        //
-        //            res.startBlock('<bean class="org.apache.ignite.lang.IgniteBiTuple">');
-        //            res.line('<constructor-arg value="' + generatorUtils.javaBuildInClass(field.className) + '"/>');
-        //            res.line('<constructor-arg value="' + field.direction + '"/>');
-        //            res.endBlock('</bean>');
-        //
-        //            res.endBlock('</entry>');
-        //        });
-        //
-        //        res.endBlock('</map>');
-        //        res.endBlock('</entry>');
-        //    }
-        //});
-        //
-        //res.endBlock('</map>');
-        //res.endBlock('</property>');
-    }
-}
-
-function generateCacheTypeMetadataConfiguration(res, meta, varCacheTypeMetadata) {
-    if (!res)
-        res = generatorUtils.builder();
-
-    res.importClass('org.apache.ignite.cache.CacheTypeMetadata');
-
-    var varType = varCacheTypeMetadata + 'Item';
-
-    addProperty(res, meta, varType, 'databaseSchema');
-    addProperty(res, meta, varType, 'databaseTable');
-
-    addProperty(res, meta, varType, 'keyType');
-    addProperty(res, meta, varType, 'valueType');
-
-    addCacheTypeMetadataDatabaseFields(res, meta, varType, 'keyFields');
-    addCacheTypeMetadataDatabaseFields(res, meta, varType, 'valueFields');
-
-    addCacheTypeMetadataQueryFields(res, meta, varType, 'queryFields');
-    addCacheTypeMetadataQueryFields(res, meta, varType, 'ascendingFields');
-    addCacheTypeMetadataQueryFields(res, meta, varType, 'descendingFields');
-
-    addListProperty(res, meta, varType, 'textFields');
-
-    addCacheTypeMetadataGroups(res, varType, meta);
-
-    res.line(varCacheTypeMetadata + '.add(' + varType + ')');
-
-    return res;
-}
-
-/**
- * Generate java code for cache configuration.
- *
- * @param cache Cache config.
- * @param varName Variable name.
- * @param res Result builder.
- * @returns {*} Append generated java code to builder and return it.
- */
-function generateCacheConfiguration(res, cache, varName) {
-    if (!res)
-        res = generatorUtils.builder();
-
-    res.emptyLineIfNeeded();
-
-    res.importClass('org.apache.ignite.cache.CacheAtomicityMode');
-    res.importClass('org.apache.ignite.cache.CacheMode');
-    res.importClass('org.apache.ignite.configuration.CacheConfiguration');
-
-    res.line('CacheConfiguration ' + varName + ' = new CacheConfiguration();');
-
-    res.needEmptyLine = true;
-
-    addProperty(res, cache, varName, 'name');
-    
-    addProperty(res, cache, varName, 'mode', 'CacheMode', 'cacheMode');
-
-    addProperty(res, cache, varName, 'atomicityMode', 'CacheAtomicityMode');
-    addProperty(res, cache, varName, 'backups');
-    addProperty(res, cache, varName, 'startSize');
-    addProperty(res, cache, varName, 'readFromBackup');
-
-    res.needEmptyLine = true;
-    
-    addProperty(res, cache, varName, 'memoryMode', 'CacheMemoryMode');
-    addProperty(res, cache, varName, 'offHeapMaxMemory');
-    addProperty(res, cache, varName, 'swapEnabled');
-    addProperty(res, cache, varName, 'copyOnRead');
-
-    res.needEmptyLine = true;
-
-    createEvictionPolicy(res, cache.evictionPolicy, varName, 'evictionPolicy');
-
-    if (cache.nearCacheEnabled) {
-        res.needEmptyLine = true;
-
-        res.importClass('org.apache.ignite.configuration.NearCacheConfiguration');
-
-        addBeanWithProperties(res, cache.nearConfiguration, varName, 'nearConfiguration', 'nearConfiguration',
-            'NearCacheConfiguration', {nearStartSize: null}, true);
-
-        if (cache.nearConfiguration && cache.nearConfiguration.nearEvictionPolicy && cache.nearConfiguration.nearEvictionPolicy.kind) {
-            createEvictionPolicy(res, cache.nearConfiguration.nearEvictionPolicy, 'nearConfiguration', 'nearEvictionPolicy');
-        }
-    }
-
-    res.needEmptyLine = true;
-    
-    addProperty(res, cache, varName, 'sqlEscapeAll');
-    addProperty(res, cache, varName, 'sqlOnheapRowCacheSize');
-    addProperty(res, cache, varName, 'longQueryWarningTimeout');
-    
-    if (cache.indexedTypes && cache.indexedTypes.length > 0) {
-        res.emptyLineIfNeeded();
-        
-        res.append(varName + '.setIndexedTypes(');
-        
-        for (var i = 0; i < cache.indexedTypes.length; i++) {
-            if (i > 0)
-                res.append(', ');
-
-            var pair = cache.indexedTypes[i];
-            
-            res.append(toJavaCode(pair.keyClass, 'class')).append(', ').append(toJavaCode(pair.valueClass, 'class'))
-        }
-        
-        res.line(');');
-    }
-
-    addMultiparamProperty(res, cache, varName, 'sqlFunctionClasses', 'class');
-    
-    res.needEmptyLine = true;
-
-    addProperty(res, cache, varName, 'rebalanceMode', 'CacheRebalanceMode');
-    addProperty(res, cache, varName, 'rebalanceThreadPoolSize');
-    addProperty(res, cache, varName, 'rebalanceBatchSize');
-    addProperty(res, cache, varName, 'rebalanceOrder');
-    addProperty(res, cache, varName, 'rebalanceDelay');
-    addProperty(res, cache, varName, 'rebalanceTimeout');
-    addProperty(res, cache, varName, 'rebalanceThrottle');
-
-    res.needEmptyLine = true;
-    
-    if (cache.cacheStoreFactory && cache.cacheStoreFactory.kind) {
-        var storeFactory = cache.cacheStoreFactory[cache.cacheStoreFactory.kind];
-        var data = generatorUtils.storeFactories[cache.cacheStoreFactory.kind];
-
-        var sfVarName = 'storeFactory' + toJavaName(cache.name);
-        var dsVarName = 'none';
-
-        if (storeFactory.dialect) {
-            var dataSourceBean = storeFactory.dataSourceBean;
-
-            dsVarName = 'dataSource' + generatorUtils.toJavaName(dataSourceBean);
-
-            if (!_.contains(res.datasourceBeans, dataSourceBean)) {
-                res.datasourceBeans.push(dataSourceBean);
-
-                var dataSource = generatorUtils.dataSources[storeFactory.dialect];
-
-                res.line();
-                res.line(dataSource.className + ' ' + dsVarName + ' = new ' + dataSource.className + '();');
-                res.line(dsVarName + '.setURL(_URL_);');
-                res.line(dsVarName + '.setUsername(_User_Name_);');
-                res.line(dsVarName + '.setPassword(_Password_);');
-            }
-        }
-
-        addBeanWithProperties(res, storeFactory, varName, 'cacheStoreFactory', sfVarName, data.className,
-            data.fields, true);
-
-        if (dsVarName != 'none')
-            res.line(sfVarName + '.setDataSource(' + dsVarName + ');');
-    }
-
-    res.needEmptyLine = true;
-
-    addProperty(res, cache, varName, 'loadPreviousValue');
-    addProperty(res, cache, varName, 'readThrough');
-    addProperty(res, cache, varName, 'writeThrough');
-
-    res.needEmptyLine = true;
-    
-    addProperty(res, cache, varName, 'invalidate');
-    addProperty(res, cache, varName, 'defaultLockTimeout');
-    addProperty(res, cache, varName, 'transactionManagerLookupClassName');
-    
-    res.needEmptyLine = true;
-    
-    addProperty(res, cache, varName, 'writeBehindEnabled');
-    addProperty(res, cache, varName, 'writeBehindBatchSize');
-    addProperty(res, cache, varName, 'writeBehindFlushSize');
-    addProperty(res, cache, varName, 'writeBehindFlushFrequency');
-    addProperty(res, cache, varName, 'writeBehindFlushThreadCount');
-    
-    res.needEmptyLine = true;
-
-    addProperty(res, cache, varName, 'statisticsEnabled');
-    addProperty(res, cache, varName, 'managementEnabled');
-
-    res.needEmptyLine = true;
-
-    addProperty(res, cache, varName, 'maxConcurrentAsyncOperations');
-
-    res.needEmptyLine = true;
-
-    // Generate cache type metadata configs.
-    if ((cache.queryMetadata && cache.queryMetadata.length > 0) ||
-        (cache.storeMetadata && cache.storeMetadata.length > 0)) {
-        res.emptyLineIfNeeded();
-
-        var varCacheTypeMetadata = varName + 'TypeMetadata';
-
-        res.line('Collection ' + varCacheTypeMetadata + ' = new ArrayList();');
-        res.line();
-
-        var metaNames = [];
-
-        if (cache.queryMetadata && cache.queryMetadata.length > 0) {
-            _.forEach(cache.queryMetadata, function (meta) {
-                if (!_.contains(metaNames, meta.name)) {
-                    metaNames.push(meta.name);
-
-                    generateCacheTypeMetadataConfiguration(res, meta, varCacheTypeMetadata);
-                }
-            });
-        }
-
-        if (cache.storeMetadata && cache.storeMetadata.length > 0) {
-            _.forEach(cache.storeMetadata, function (meta) {
-                if (!_.contains(metaNames, meta.name)) {
-                    metaNames.push(meta.name);
-
-                    generateCacheTypeMetadataConfiguration(meta, res);
-                }
-            });
-        }
-
-        res.line(varName + '.setCacheTypeMetadata(' + varCacheTypeMetadata + ');');
-    }
-    
-    return res;
-}
-
-function toJavaCode(val, type) {
-    if (val == null)
-       return 'null';
-
-    if (type == 'float')
-        return val + 'f';
-    
-    if (type == 'class')
-        return val + '.class';
-    
-    if (type)
-        return type + '.' + val;
-    
-    if (typeof(val) == 'string')
-        return '"' + val.replace('"', '\\"') + '"';
-
-    if (typeof(val) == 'number' || typeof(val) == 'boolean')
-        return '' + val;
-
-    throw "Unknown type: " + typeof(val) + ' (' + val + ')';
-}
-
-function addProperty(res, obj, objVariableName, propName, enumType, setterName) {
-    var val = obj[propName];
-    
-    if (generatorUtils.isDefined(val)) {
-        res.emptyLineIfNeeded();
-
-        res.line(objVariableName + '.' + getSetterName(setterName ? setterName : propName)
-            + '(' + toJavaCode(val, enumType)  + ');');
-    }
-}
-
-function getSetterName(propName) {
-    return 'set' + propName.charAt(0).toLocaleUpperCase() + propName.slice(1);
-}
-
-function addListProperty(res, obj, objVariableName, propName, enumType, setterName) {
-    var val = obj[propName];
-    
-    if (val && val.length > 0) {
-        res.append(objVariableName + '.' + getSetterName(setterName ? setterName : propName) + '(Arrays.asList(');
-
-        for (var i = 0; i < val.length; i++) {
-            if (i > 0)
-                res.append(', ');
-            
-            res.append(toJavaCode(val[i], enumType));
-        }
-        
-        res.line('));');
-    }
-}
-
-function addMultiparamProperty(res, obj, objVariableName, propName, type, setterName) {
-    var val = obj[propName];
-    
-    if (val && val.length > 0) {
-        res.append(objVariableName + '.' + getSetterName(setterName ? setterName : propName) + '(');
-
-        for (var i = 0; i < val.length; i++) {
-            if (i > 0)
-                res.append(', ');
-            
-            res.append(toJavaCode(val[i], type));
-        }
-        
-        res.line(');');
-    }
-}
-
-function addBeanWithProperties(res, bean, objVarName, beanPropName, beanVarName, beanClass, props, createBeanAlthoughNoProps) {
-    if (bean && generatorUtils.hasProperty(bean, props)) {
-        if (!res.emptyLineIfNeeded()) {
-            res.line();
-        }
-        
-        res.line(beanClass + ' ' + beanVarName + ' = new ' + beanClass + '();');
-
-        for (var propName in props) {
-            if (props.hasOwnProperty(propName)) {
-                var descr = props[propName];
-
-                if (descr) {
-                    switch (descr.type) {
-                        case 'list':
-                            addListProperty(res, bean, beanVarName, propName, descr.elementsType, descr.setterName);
-                            break;
-                        
-                        case 'enum':
-                            addProperty(res, bean, beanVarName, propName, descr.enumClass, descr.setterName);
-                            break;
-                        
-                        case 'float':
-                            addProperty(res, bean, beanVarName, propName, 'float', descr.setterName);
-                            break;
-                        
-                        case 'propertiesAsList':
-                            var val = bean[propName];
-                            
-                            if (val && val.length > 0) {
-                                res.line('Properties ' + descr.propVarName + ' = new Properties();');
-                                
-                                for (var i = 0; i < val.length; i++) {
-                                    var nameAndValue = val[i];
-                                    
-                                    var eqIndex = nameAndValue.indexOf('=');
-                                    if (eqIndex >= 0) {
-                                        res.line(descr.propVarName + '.setProperty(' 
-                                            + nameAndValue.substring(0, eqIndex) + ', ' 
-                                            + nameAndValue.substr(eqIndex + 1) + ');');
-                                    }
-
-                                }
-                                
-                                res.line(beanVarName + '.' + getSetterName(propName) + '(' + descr.propVarName + ');');
-                            }
-                            break;
-                        
-                        case 'className':
-                            if (bean[propName]) {
-                                res.line(beanVarName + '.' + getSetterName(propName) + '(new ' + generatorUtils.knownClasses[bean[propName]].className + '());');
-                            }
-
-                            break;
-                        
-                        default:
-                            addProperty(res, bean, beanVarName, propName, null, descr.setterName);
-                    }
-                }
-                else {
-                    addProperty(res, bean, beanVarName, propName);
-                }
-            }
-        }
-        
-        res.line(objVarName + '.' + getSetterName(beanPropName) + '(' + beanVarName + ');');
-        
-        res.needEmptyLine = true;
-    }
-    else if (createBeanAlthoughNoProps) {
-        res.emptyLineIfNeeded();
-        
-        res.line(objVarName + '.' + getSetterName(beanPropName) + '(new ' + beanClass + '());');
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/web-control-center/src/main/js/routes/generator/xml.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/routes/generator/xml.js b/modules/web-control-center/src/main/js/routes/generator/xml.js
deleted file mode 100644
index 079f268..0000000
--- a/modules/web-control-center/src/main/js/routes/generator/xml.js
+++ /dev/null
@@ -1,736 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-var _ = require('lodash');
-
-var generatorUtils = require("./common");
-var dataStructures = require("../../helpers/data-structures.js");
-
-exports.generateClusterConfiguration = function(cluster, clientNearConfiguration) {
-    var res = generatorUtils.builder();
-
-    res.datasources = [];
-    res.deep = 1;
-
-    if (clientNearConfiguration) {
-        res.startBlock('<bean id="nearCacheBean" class="org.apache.ignite.configuration.NearCacheConfiguration">');
-
-        if (clientNearConfiguration.nearStartSize)
-            addProperty(res, clientNearConfiguration, 'nearStartSize');
-
-        if (clientNearConfiguration.nearEvictionPolicy && clientNearConfiguration.nearEvictionPolicy.kind)
-            createEvictionPolicy(res, clientNearConfiguration.nearEvictionPolicy, 'nearEvictionPolicy');
-
-        res.endBlock('</bean>');
-
-        res.line();
-    }
-
-    // Generate Ignite Configuration.
-    res.startBlock('<bean class="org.apache.ignite.configuration.IgniteConfiguration">');
-
-    if (clientNearConfiguration) {
-        res.line('<property name="clientMode" value="true" />');
-
-        res.line();
-    }
-
-    // Generate discovery.
-    if (cluster.discovery) {
-        res.startBlock('<property name="discoverySpi">');
-        res.startBlock('<bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi">');
-        res.startBlock('<property name="ipFinder">');
-
-        var d = cluster.discovery;
-
-        switch (d.kind) {
-            case 'Multicast':
-                res.startBlock('<bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.multicast.TcpDiscoveryMulticastIpFinder">');
-
-                addProperty(res, d.Multicast, 'multicastGroup');
-                addProperty(res, d.Multicast, 'multicastPort');
-                addProperty(res, d.Multicast, 'responseWaitTime');
-                addProperty(res, d.Multicast, 'addressRequestAttempts');
-                addProperty(res, d.Multicast, 'localAddress');
-
-                res.endBlock('</bean>');
-
-                break;
-
-            case 'Vm':
-                if (d.Vm.addresses.length > 0) {
-                    res.startBlock('<bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder">');
-
-                    addListProperty(res, d.Vm, 'addresses');
-
-                    res.endBlock('</bean>');
-                }
-                else {
-                    res.line('<bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder"/>');
-                }
-
-                break;
-
-            case 'S3':
-                res.startBlock('<bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.s3.TcpDiscoveryS3IpFinder">');
-
-                if (d.S3 && d.S3.bucketName)
-                    res.line('<property name="bucketName" value="' + escapeAttr(d.S3.bucketName) + '" />');
-
-                res.endBlock('</bean>');
-
-                break;
-
-            case 'Cloud':
-                res.startBlock('<bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.cloud.TcpDiscoveryCloudIpFinder">');
-
-                addProperty(res, d.Cloud, 'credential');
-                addProperty(res, d.Cloud, 'credentialPath');
-                addProperty(res, d.Cloud, 'identity');
-                addProperty(res, d.Cloud, 'provider');
-                addListProperty(res, d.Cloud, 'regions');
-                addListProperty(res, d.Cloud, 'zones');
-
-                res.endBlock('</bean>');
-
-                break;
-
-            case 'GoogleStorage':
-                res.startBlock('<bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.gce.TcpDiscoveryGoogleStorageIpFinder">');
-
-                addProperty(res, d.GoogleStorage, 'projectName');
-                addProperty(res, d.GoogleStorage, 'bucketName');
-                addProperty(res, d.GoogleStorage, 'serviceAccountP12FilePath');
-
-                //if (d.GoogleStorage.addrReqAttempts) todo ????
-                //    res.line('<property name="serviceAccountP12FilePath" value="' + escapeAttr(d.GoogleStorage.addrReqAttempts) + '"/>');
-
-                res.endBlock('</bean>');
-
-                break;
-
-            case 'Jdbc':
-                res.startBlock('<bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.jdbc.TcpDiscoveryJdbcIpFinder">');
-                res.line('<property name="initSchema" value="' + (d.Jdbc.initSchema != null || d.Jdbc.initSchema) + '"/>');
-                res.endBlock('</bean>');
-
-                break;
-
-            case 'SharedFs':
-                if (d.SharedFs.path) {
-                    res.startBlock('<bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.sharedfs.TcpDiscoverySharedFsIpFinder">');
-                    addProperty(res, d.SharedFs, 'path');
-                    res.endBlock('</bean>');
-                }
-                else {
-                    res.line('<bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.sharedfs.TcpDiscoverySharedFsIpFinder"/>');
-                }
-
-                break;
-
-            default:
-                throw "Unknown discovery kind: " + d.kind;
-        }
-
-        res.endBlock('</property>');
-        res.endBlock('</bean>');
-        res.endBlock('</property>');
-
-        res.needEmptyLine = true
-    }
-
-    // Generate atomics group.
-    addBeanWithProperties(res, cluster.atomicConfiguration, 'atomicConfiguration',
-        generatorUtils.atomicConfiguration.className, generatorUtils.atomicConfiguration.fields);
-    res.needEmptyLine = true;
-
-    // Generate communication group.
-    addProperty(res, cluster, 'networkTimeout');
-    addProperty(res, cluster, 'networkSendRetryDelay');
-    addProperty(res, cluster, 'networkSendRetryCount');
-    addProperty(res, cluster, 'segmentCheckFrequency');
-    addProperty(res, cluster, 'waitForSegmentOnStart');
-    addProperty(res, cluster, 'discoveryStartupDelay');
-    res.needEmptyLine = true;
-
-    // Generate deployment group.
-    addProperty(res, cluster, 'deploymentMode');
-    res.needEmptyLine = true;
-
-    // Generate events group.
-    if (cluster.includeEventTypes && cluster.includeEventTypes.length > 0) {
-        res.emptyLineIfNeeded();
-        
-        res.startBlock('<property name="includeEventTypes">');
-        
-        if (cluster.includeEventTypes.length == 1)
-            res.line('<util:constant static-field="org.apache.ignite.events.EventType.' + cluster.includeEventTypes[0] + '"/>');
-        else {
-            res.startBlock('<array>');
-
-            for (i = 0; i < cluster.includeEventTypes.length; i++) {
-                if (i > 0)
-                    res.line();
-
-                var eventGroup = cluster.includeEventTypes[i];
-
-                res.line('<!-- EventType.' + eventGroup + ' -->');
-
-                var eventList = dataStructures.eventGroups[eventGroup];
-
-                for (var k = 0; k < eventList.length; k++) {
-                    res.line('<util:constant static-field="org.apache.ignite.events.EventType.' + eventList[k] + '"/>')
-                }
-            }
-
-            res.endBlock('</array>');
-        }
-        
-        res.endBlock('</property>');
-
-        res.needEmptyLine = true;
-    }
-
-    // Generate marshaller group.
-    var marshaller = cluster.marshaller;
-
-    if (marshaller && marshaller.kind) {
-        var marshallerDesc = generatorUtils.marshallers[marshaller.kind];
-
-        addBeanWithProperties(res, marshaller[marshaller.kind], 'marshaller', marshallerDesc.className, marshallerDesc.fields, true);
-        res.needEmptyLine = true;
-    }
-
-    addProperty(res, cluster, 'marshalLocalJobs');
-    addProperty(res, cluster, 'marshallerCacheKeepAliveTime');
-    addProperty(res, cluster, 'marshallerCacheThreadPoolSize');
-    res.needEmptyLine = true;
-
-    // Generate metrics group.
-    addProperty(res, cluster, 'metricsExpireTime');
-    addProperty(res, cluster, 'metricsHistorySize');
-    addProperty(res, cluster, 'metricsLogFrequency');
-    addProperty(res, cluster, 'metricsUpdateFrequency');
-    res.needEmptyLine = true;
-
-    // Generate PeerClassLoading group.
-    addProperty(res, cluster, 'peerClassLoadingEnabled');
-    addListProperty(res, cluster, 'peerClassLoadingLocalClassPathExclude');
-    addProperty(res, cluster, 'peerClassLoadingMissedResourcesCacheSize');
-    addProperty(res, cluster, 'peerClassLoadingThreadPoolSize');
-    res.needEmptyLine = true;
-
-    // Generate swap group.
-    if (cluster.swapSpaceSpi && cluster.swapSpaceSpi.kind == 'FileSwapSpaceSpi') {
-        addBeanWithProperties(res, cluster.swapSpaceSpi.FileSwapSpaceSpi, 'swapSpaceSpi',
-            generatorUtils.swapSpaceSpi.className, generatorUtils.swapSpaceSpi.fields, true);
-
-        res.needEmptyLine = true;
-    }
-
-    // Generate time group.
-    addProperty(res, cluster, 'clockSyncSamples');
-    addProperty(res, cluster, 'clockSyncFrequency');
-    addProperty(res, cluster, 'timeServerPortBase');
-    addProperty(res, cluster, 'timeServerPortRange');
-    res.needEmptyLine = true;
-
-    // Generate thread pools group.
-    addProperty(res, cluster, 'publicThreadPoolSize');
-    addProperty(res, cluster, 'systemThreadPoolSize');
-    addProperty(res, cluster, 'managementThreadPoolSize');
-    addProperty(res, cluster, 'igfsThreadPoolSize');
-    res.needEmptyLine = true;
-
-    // Generate transactions group.
-    addBeanWithProperties(res, cluster.transactionConfiguration, 'transactionConfiguration',
-        generatorUtils.transactionConfiguration.className, generatorUtils.transactionConfiguration.fields);
-    res.needEmptyLine = true;
-
-    // Generate caches configs.
-    if (cluster.caches && cluster.caches.length > 0) {
-        res.emptyLineIfNeeded();
-
-        res.startBlock('<property name="cacheConfiguration">');
-        res.startBlock('<list>');
-
-        for (var i = 0; i < cluster.caches.length; i++) {
-            if (i > 0)
-                res.line();
-
-            var cache = cluster.caches[i];
-
-            generateCacheConfiguration(res, cache);
-        }
-
-        res.endBlock('</list>');
-        res.endBlock('</property>');
-
-        res.needEmptyLine = true;
-    }
-
-    res.endBlock('</bean>');
-
-    // Build final XML:
-    // 1. Add header.
-    var xml = '<?xml version="1.0" encoding="UTF-8"?>\n\n';
-
-    xml += '<!-- ' + generatorUtils.mainComment() + ' -->\n';
-    xml += '<beans xmlns="http://www.springframework.org/schema/beans"\n';
-    xml += '       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\n';
-    xml += '       xmlns:util="http://www.springframework.org/schema/util"\n';
-    xml += '       xsi:schemaLocation="http://www.springframework.org/schema/beans\n';
-    xml += '                           http://www.springframework.org/schema/beans/spring-beans.xsd\n';
-    xml += '                           http://www.springframework.org/schema/util\n';
-    xml += '                           http://www.springframework.org/schema/util/spring-util.xsd">\n';
-
-    // 2. Add external property file and all data sources.
-    if (res.datasources.length > 0) {
-        xml += '    <!-- Load external properties file. -->\n';
-        xml += '    <bean id="placeholderConfig" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">\n';
-        xml += '        <property name="location" value="classpath:secret.properties"/>\n';
-        xml += '    </bean>\n\n';
-
-        xml += '    <!-- Data source beans will be initialized from external properties file. -->\n';
-
-        _.forEach(res.datasources, function(item) {
-            var beanId = item.dataSourceBean;
-
-            xml += '    <bean id= "' + beanId + '" class="' + item.className + '">\n';
-            xml += '        <property name="URL" value="${' + beanId + '.jdbc.url}" />\n';
-            xml += '        <property name="user" value="${' + beanId + '.jdbc.username}" />\n';
-            xml += '        <property name="password" value="${' + beanId + '.jdbc.password}" />\n';
-            xml += '    </bean>\n\n';
-        });
-    }
-
-    // 3. Add main content.
-    xml += res.join('');
-
-    // 4. Add footer.
-    xml += '</beans>\n';
-
-    return xml;
-};
-
-function createEvictionPolicy(res, evictionPolicy, propertyName) {
-    if (evictionPolicy && evictionPolicy.kind) {
-        var e = generatorUtils.evictionPolicies[evictionPolicy.kind];
-
-        var obj = evictionPolicy[evictionPolicy.kind.toUpperCase()];
-
-        addBeanWithProperties(res, obj, propertyName, e.className, e.fields, true);
-    }
-}
-
-function addCacheTypeMetadataDatabaseFields(res, meta, fieldsProperty) {
-    var fields = meta[fieldsProperty];
-
-    if (fields && fields.length > 0) {
-        res.startBlock('<property name="' + fieldsProperty + '">');
-
-        res.startBlock('<list>');
-
-        _.forEach(fields, function (field) {
-            res.startBlock('<bean class="org.apache.ignite.cache.CacheTypeFieldMetadata">');
-
-            addProperty(res, field, 'databaseName');
-
-            res.startBlock('<property name="databaseType">');
-            res.line('<util:constant static-field="java.sql.Types.' + field.databaseType + '"/>');
-            res.endBlock('</property>');
-
-            addProperty(res, field, 'javaName');
-
-            addElement(res, 'property', 'name', 'javaType', 'value', generatorUtils.javaBuildInClass(field.javaType));
-
-            res.endBlock('</bean>');
-        });
-
-        res.endBlock('</list>');
-        res.endBlock('</property>');
-    }
-}
-
-function addCacheTypeMetadataQueryFields(res, meta, fieldsProperty) {
-    var fields = meta[fieldsProperty];
-
-    if (fields && fields.length > 0) {
-        res.startBlock('<property name="' + fieldsProperty + '">');
-
-        res.startBlock('<map>');
-
-        _.forEach(fields, function (field) {
-            addElement(res, 'entry', 'key', field.name, 'value', generatorUtils.javaBuildInClass(field.className));
-        });
-
-        res.endBlock('</map>');
-
-        res.endBlock('</property>');
-    }
-}
-
-function addCacheTypeMetadataGroups(res, meta) {
-    var groups = meta.groups;
-
-    if (groups && groups.length > 0) {
-        res.startBlock('<property name="groups">');
-        res.startBlock('<map>');
-
-        _.forEach(groups, function (group) {
-            var fields = group.fields;
-
-            if (fields && fields.length > 0) {
-                res.startBlock('<entry key="' + group.name + '">');
-                res.startBlock('<map>');
-
-                _.forEach(fields, function (field) {
-                    res.startBlock('<entry key="' + field.name + '">');
-
-                    res.startBlock('<bean class="org.apache.ignite.lang.IgniteBiTuple">');
-                    res.line('<constructor-arg value="' + generatorUtils.javaBuildInClass(field.className) + '"/>');
-                    res.line('<constructor-arg value="' + field.direction + '"/>');
-                    res.endBlock('</bean>');
-
-                    res.endBlock('</entry>');
-                });
-
-                res.endBlock('</map>');
-                res.endBlock('</entry>');
-            }
-        });
-
-        res.endBlock('</map>');
-        res.endBlock('</property>');
-    }
-}
-
-function generateCacheTypeMetadataConfiguration(res, meta) {
-    if (!res)
-        res = generatorUtils.builder();
-
-    res.startBlock('<bean class="org.apache.ignite.cache.CacheTypeMetadata">');
-
-    addProperty(res, meta, 'databaseSchema');
-    addProperty(res, meta, 'databaseTable');
-
-    addProperty(res, meta, 'keyType');
-    addProperty(res, meta, 'valueType');
-
-    addCacheTypeMetadataDatabaseFields(res, meta, 'keyFields');
-    addCacheTypeMetadataDatabaseFields(res, meta, 'valueFields');
-
-    addCacheTypeMetadataQueryFields(res, meta, 'queryFields');
-    addCacheTypeMetadataQueryFields(res, meta, 'ascendingFields');
-    addCacheTypeMetadataQueryFields(res, meta, 'descendingFields');
-
-    addListProperty(res, meta, 'textFields');
-
-    addCacheTypeMetadataGroups(res, meta);
-
-    res.endBlock('</bean>');
-
-    return res;
-}
-
-function generateCacheConfiguration(res, cacheCfg) {
-    if (!res)
-        res = generatorUtils.builder();
-
-    res.startBlock('<bean class="org.apache.ignite.configuration.CacheConfiguration">');
-
-    addProperty(res, cacheCfg, 'name');
-
-    res.needEmptyLine = true;
-
-    addProperty(res, cacheCfg, 'mode', 'cacheMode');
-
-    addProperty(res, cacheCfg, 'atomicityMode');
-    addProperty(res, cacheCfg, 'backups');
-    addProperty(res, cacheCfg, 'startSize');
-    addProperty(res, cacheCfg, 'readFromBackup');
-
-    res.needEmptyLine = true;
-
-    addProperty(res, cacheCfg, 'memoryMode');
-    addProperty(res, cacheCfg, 'offHeapMaxMemory');
-    addProperty(res, cacheCfg, 'swapEnabled');
-    addProperty(res, cacheCfg, 'copyOnRead');
-
-    res.needEmptyLine = true;
-
-    createEvictionPolicy(res, cacheCfg.evictionPolicy, 'evictionPolicy');
-
-    res.needEmptyLine = true;
-
-    if (cacheCfg.nearCacheEnabled) {
-        res.emptyLineIfNeeded();
-
-        res.startBlock('<property name="nearConfiguration">');
-        res.startBlock('<bean class="org.apache.ignite.configuration.NearCacheConfiguration">');
-
-        if (cacheCfg.nearConfiguration && cacheCfg.nearConfiguration.nearStartSize)
-            addProperty(res, cacheCfg.nearConfiguration, 'nearStartSize');
-
-        if (cacheCfg.nearConfiguration && cacheCfg.nearConfiguration.nearEvictionPolicy.kind)
-            createEvictionPolicy(res, cacheCfg.nearConfiguration.nearEvictionPolicy, 'nearEvictionPolicy');
-
-        res.endBlock('</bean>');
-        res.endBlock('</property>');
-    }
-
-    res.needEmptyLine = true;
-
-    addProperty(res, cacheCfg, 'sqlEscapeAll');
-    addProperty(res, cacheCfg, 'sqlOnheapRowCacheSize');
-    addProperty(res, cacheCfg, 'longQueryWarningTimeout');
-
-    if (cacheCfg.indexedTypes && cacheCfg.indexedTypes.length > 0) {
-        res.startBlock('<property name="indexedTypes">');
-        res.startBlock('<list>');
-
-        for (var i = 0; i < cacheCfg.indexedTypes.length; i++) {
-            var pair = cacheCfg.indexedTypes[i];
-
-            res.line('<value>' + generatorUtils.javaBuildInClass(pair.keyClass) + '</value>');
-            res.line('<value>' + generatorUtils.javaBuildInClass(pair.valueClass) + '</value>');
-        }
-
-        res.endBlock('</list>');
-        res.endBlock('</property>');
-    }
-
-    addListProperty(res, cacheCfg, 'sqlFunctionClasses', 'array');
-
-    res.needEmptyLine = true;
-
-    addProperty(res, cacheCfg, 'rebalanceMode');
-    addProperty(res, cacheCfg, 'rebalanceThreadPoolSize');
-    addProperty(res, cacheCfg, 'rebalanceBatchSize');
-    addProperty(res, cacheCfg, 'rebalanceOrder');
-    addProperty(res, cacheCfg, 'rebalanceDelay');
-    addProperty(res, cacheCfg, 'rebalanceTimeout');
-    addProperty(res, cacheCfg, 'rebalanceThrottle');
-
-    res.needEmptyLine = true;
-
-    if (cacheCfg.cacheStoreFactory && cacheCfg.cacheStoreFactory.kind) {
-        var storeFactory = cacheCfg.cacheStoreFactory[cacheCfg.cacheStoreFactory.kind];
-        var data = generatorUtils.storeFactories[cacheCfg.cacheStoreFactory.kind];
-
-        addBeanWithProperties(res, storeFactory, 'cacheStoreFactory', data.className, data.fields, true);
-
-        if (storeFactory.dialect) {
-            if (_.findIndex(res.datasources, function (ds) {
-                    return ds.dataSourceBean == storeFactory.dataSourceBean;
-                }) < 0) {
-                res.datasources.push({
-                    dataSourceBean: storeFactory.dataSourceBean,
-                    className: generatorUtils.dataSources[storeFactory.dialect]
-                });
-            }
-        }
-    }
-
-    res.needEmptyLine = true;
-
-    addProperty(res, cacheCfg, 'loadPreviousValue');
-    addProperty(res, cacheCfg, 'readThrough');
-    addProperty(res, cacheCfg, 'writeThrough');
-
-    res.needEmptyLine = true;
-
-    addProperty(res, cacheCfg, 'invalidate');
-    addProperty(res, cacheCfg, 'defaultLockTimeout');
-    addProperty(res, cacheCfg, 'transactionManagerLookupClassName');
-
-    res.needEmptyLine = true;
-
-    addProperty(res, cacheCfg, 'writeBehindEnabled');
-    addProperty(res, cacheCfg, 'writeBehindBatchSize');
-    addProperty(res, cacheCfg, 'writeBehindFlushSize');
-    addProperty(res, cacheCfg, 'writeBehindFlushFrequency');
-    addProperty(res, cacheCfg, 'writeBehindFlushThreadCount');
-
-    res.needEmptyLine = true;
-
-    addProperty(res, cacheCfg, 'statisticsEnabled');
-    addProperty(res, cacheCfg, 'managementEnabled');
-
-    res.needEmptyLine = true;
-
-    addProperty(res, cacheCfg, 'maxConcurrentAsyncOperations');
-
-    // Generate cache type metadata configs.
-    if ((cacheCfg.queryMetadata && cacheCfg.queryMetadata.length > 0) ||
-        (cacheCfg.storeMetadata && cacheCfg.storeMetadata.length > 0)) {
-        res.emptyLineIfNeeded();
-
-        res.startBlock('<property name="typeMetadata">');
-        res.startBlock('<list>');
-
-        var metaNames = [];
-
-        if (cacheCfg.queryMetadata && cacheCfg.queryMetadata.length > 0) {
-            _.forEach(cacheCfg.queryMetadata, function (meta) {
-                if (!_.contains(metaNames, meta.name)) {
-                    metaNames.push(meta.name);
-
-                    generateCacheTypeMetadataConfiguration(res, meta);
-                }
-            });
-        }
-
-        if (cacheCfg.storeMetadata && cacheCfg.storeMetadata.length > 0) {
-            _.forEach(cacheCfg.storeMetadata, function (meta) {
-                if (!_.contains(metaNames, meta.name)) {
-                    metaNames.push(meta.name);
-
-                    generateCacheTypeMetadataConfiguration(res, meta);
-                }
-            });
-        }
-
-        res.endBlock('</list>');
-        res.endBlock('</property>');
-    }
-
-    res.endBlock('</bean>');
-
-    return res;
-}
-
-function addElement(res, tag, attr1, val1, attr2, val2) {
-    var elem = '<' + tag;
-
-    if (attr1) {
-        elem += ' ' + attr1 + '="' + val1 + '"'
-    }
-
-    if (attr2) {
-        elem += ' ' + attr2 + '="' + val2 + '"'
-    }
-
-    elem += '/>';
-
-    res.emptyLineIfNeeded();
-    res.line(elem);
-}
-
-function addProperty(res, obj, propName, setterName) {
-    var val = obj[propName];
-
-    if (generatorUtils.isDefined(val))
-        addElement(res, 'property', 'name', setterName ? setterName : propName, 'value', escapeAttr(val));
-}
-
-function addBeanWithProperties(res, bean, beanPropName, beanClass, props, createBeanAlthoughNoProps) {
-    if (bean && generatorUtils.hasProperty(bean, props)) {
-        res.emptyLineIfNeeded();
-        res.startBlock('<property name="' + beanPropName + '">');
-        res.startBlock('<bean class="' + beanClass + '">');
-
-        for (var propName in props) {
-            if (props.hasOwnProperty(propName)) {
-                var descr = props[propName];
-
-                if (descr) {
-                    if (descr.type == 'list') {
-                        addListProperty(res, bean, propName, descr.setterName);
-                    }
-                    else if (descr.type == 'className') {
-                        if (bean[propName]) {
-                            res.startBlock('<property name="' + propName + '">');
-                            res.line('<bean class="' + generatorUtils.knownClasses[bean[propName]].className + '"/>');
-                            res.endBlock('</property>');
-                        }
-                    }
-                    else if (descr.type == 'propertiesAsList') {
-                        var val = bean[propName];
-
-                        if (val && val.length > 0) {
-                            res.startBlock('<property name="' + propName + '">');
-                            res.startBlock('<props>');
-
-                            for (var i = 0; i < val.length; i++) {
-                                var nameAndValue = val[i];
-
-                                var eqIndex = nameAndValue.indexOf('=');
-                                if (eqIndex >= 0) {
-                                    res.line('<prop key="' + escapeAttr(nameAndValue.substring(0, eqIndex)) + '">' +
-                                            + escape(nameAndValue.substr(eqIndex + 1)) + '</prop>');
-                                }
-                            }
-
-                            res.endBlock('</props>');
-                            res.endBlock('</property>');
-                        }
-                    }
-                    else
-                        addProperty(res, bean, propName, descr.setterName);
-                }
-                else
-                    addProperty(res, bean, propName);
-            }
-        }
-
-        res.endBlock('</bean>');
-        res.endBlock('</property>');
-    }
-    else if (createBeanAlthoughNoProps) {
-        res.emptyLineIfNeeded();
-        res.line('<property name="' + beanPropName + '">');
-        res.line('    <bean class="' + beanClass + '"/>');
-        res.line('</property>');
-    }
-}
-function addListProperty(res, obj, propName, listType, rowFactory) {
-    var val = obj[propName];
-
-    if (val && val.length > 0) {
-        res.emptyLineIfNeeded();
-
-        if (!listType)
-            listType = 'list';
-
-        if (!rowFactory)
-            rowFactory = function(val) { return '<value>' + escape(val) + '</value>' };
-
-        res.startBlock('<property name="' + propName + '">');
-        res.startBlock('<' + listType + '>');
-
-        for (var i = 0; i < val.length; i++)
-            res.line(rowFactory(val[i]));
-
-        res.endBlock('</' + listType + '>');
-        res.endBlock('</property>');
-    }
-}
-
-function escapeAttr(s) {
-    if (typeof(s) != 'string')
-        return s;
-
-    return s.replace(/&/g, '&amp;').replace(/"/g, '&quot;');
-}
-
-function escape(s) {
-    if (typeof(s) != 'string')
-        return s;
-
-    return s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
-}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/web-control-center/src/main/js/routes/metadata.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/routes/metadata.js b/modules/web-control-center/src/main/js/routes/metadata.js
deleted file mode 100644
index 0af624e..0000000
--- a/modules/web-control-center/src/main/js/routes/metadata.js
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-var router = require('express').Router();
-var db = require('../db');
-
-/* GET metadata page. */
-router.get('/', function (req, res) {
-    res.render('configuration/metadata');
-});
-
-/**
- * Get spaces and metadata accessed for user account.
- *
- * @param req Request.
- * @param res Response.
- */
-router.post('/list', function (req, res) {
-    var user_id = req.currentUserId();
-
-    // Get owned space and all accessed space.
-    db.Space.find({$or: [{owner: user_id}, {usedBy: {$elemMatch: {account: user_id}}}]}, function (err, spaces) {
-        if (err)
-            return res.status(500).send(err.message);
-
-        var space_ids = spaces.map(function (value) {
-            return value._id;
-        });
-
-        // Get all metadata for spaces.
-        db.CacheTypeMetadata.find({space: {$in: space_ids}}).sort('name').exec(function (err, metadatas) {
-            if (err)
-                return res.status(500).send(err.message);
-
-            res.json({spaces: spaces, metadatas: metadatas});
-        });
-    });
-});
-
-/**
- * Save metadata.
- */
-router.post('/save', function (req, res) {
-    if (req.body._id)
-        db.CacheTypeMetadata.update({_id: req.body._id}, req.body, {upsert: true}, function (err) {
-            if (err)
-                return res.status(500).send(err.message);
-
-            res.send(req.body._id);
-        });
-    else {
-        db.CacheTypeMetadata.findOne({space: req.body.space, name: req.body.name}, function (err, metadata) {
-            if (err)
-                return res.status(500).send(err.message);
-
-            if (metadata)
-                return res.status(500).send('Cache type metadata with name: "' + metadata.name + '" already exist.');
-
-            (new db.CacheTypeMetadata(req.body)).save(function (err, metadata) {
-                if (err)
-                    return res.status(500).send(err.message);
-
-                res.send(metadata._id);
-            });
-        });
-    }
-});
-
-/**
- * Remove metadata by ._id.
- */
-router.post('/remove', function (req, res) {
-    db.CacheTypeMetadata.remove(req.body, function (err) {
-        if (err)
-            return res.status(500).send(err.message);
-
-        res.sendStatus(200);
-    })
-});
-
-module.exports = router;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/web-control-center/src/main/js/routes/profile.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/routes/profile.js b/modules/web-control-center/src/main/js/routes/profile.js
deleted file mode 100644
index 0269e7d..0000000
--- a/modules/web-control-center/src/main/js/routes/profile.js
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-var router = require('express').Router();
-var db = require('../db');
-
-router.all('/profile/*', function (req, res, next) {
-    var userId = req.body._id;
-
-    if (userId != req.currentUserId() && userId != req.user._id)
-        return res.sendStatus(403);
-    else
-        next();
-});
-
-/**
- * Get user profile page.
- */
-router.get('/', function (req, res) {
-    var user_id = req.currentUserId();
-
-    db.Account.findById(user_id, function (err) {
-        if (err)
-            return res.status(500).send(err.message);
-
-        res.render('settings/profile');
-    });
-});
-
-/**
- * Save user profile.
- */
-router.post('/saveUser', function (req, res) {
-    var params = req.body;
-
-    if (params.newPassword) {
-        var newPassword = params.newPassword;
-
-        if (!newPassword || newPassword.length == 0)
-            return res.status(500).send('Wrong value for new password');
-
-        db.Account.findById(params._id, function (err, user) {
-            if (err)
-                return res.status(500).send(err);
-
-            user.setPassword(newPassword, function (err, updatedUser) {
-                if (err)
-                    return res.status(500).send(err.message);
-
-                if (params.userName)
-                    updatedUser.username = params.userName;
-
-                if (params.email)
-                    updatedUser.email = params.email;
-
-                updatedUser.save(function (err) {
-                    if (err)
-                        return res.status(500).send(err.message);
-
-                    res.json(user);
-                });
-            });
-        });
-    }
-    else if (params.userName || params.email) {
-        var upd = {};
-
-        if (params.userName)
-            upd.username = params.userName;
-
-        if (params.email)
-            upd.email = params.email;
-
-        db.Account.findByIdAndUpdate(params._id, upd, {new: true}, function (err, val) {
-            if (err)
-                return res.status(500).send(err.message);
-
-            res.json(val);
-        })
-    }
-});
-
-module.exports = router;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/web-control-center/src/main/js/routes/public.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/routes/public.js b/modules/web-control-center/src/main/js/routes/public.js
deleted file mode 100644
index b3cb983..0000000
--- a/modules/web-control-center/src/main/js/routes/public.js
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-var router = require('express').Router();
-var passport = require('passport');
-var db = require('../db');
-
-// GET dropdown-menu template.
-router.get('/select', function (req, res) {
-    res.render('templates/select', {});
-});
-
-// GET dynamic tabs template.
-router.get('/tab', function (req, res) {
-    res.render('templates/tab', {});
-});
-
-// GET confirmation dialog.
-router.get('/confirm', function (req, res) {
-    res.render('templates/confirm', {});
-});
-
-// GET copy dialog.
-router.get('/copy', function (req, res) {
-    res.render('templates/copy', {});
-});
-
-/* GET login page. */
-router.get('/login', function (req, res) {
-    res.render('login');
-});
-
-/**
- * Register new account.
- */
-router.post('/register', function (req, res) {
-    db.Account.count(function (err, cnt) {
-        if (err)
-            return res.status(401).send(err.message);
-
-        req.body.admin = cnt == 0;
-
-        db.Account.register(new db.Account(req.body), req.body.password, function (err, account) {
-            if (err)
-                return res.status(401).send(err.message);
-
-            if (!account)
-                return res.status(500).send('Failed to create account.');
-
-            new db.Space({name: 'Personal space', owner: account._id}).save();
-
-            req.logIn(account, {}, function (err) {
-                if (err)
-                    return res.status(401).send(err.message);
-
-                return res.redirect('/configuration/clusters');
-            });
-        });
-    });
-});
-
-/**
- * Login in exist account.
- */
-router.post('/login', function (req, res, next) {
-    passport.authenticate('local', function (err, user) {
-        if (err)
-            return res.status(401).send(err.message);
-
-        if (!user)
-            return res.status(401).send('Invalid email or password');
-
-        req.logIn(user, {}, function (err) {
-            if (err)
-                return res.status(401).send(err.message);
-
-            res.redirect('/configuration/clusters');
-        });
-    })(req, res, next);
-});
-
-/**
- * Logout.
- */
-router.get('/logout', function (req, res) {
-    req.logout();
-
-    res.redirect('/');
-});
-
-/* GET home page. */
-router.get('/', function (req, res) {
-    if (req.isAuthenticated())
-        res.redirect('/configuration/clusters');
-    else
-        res.render('index');
-});
-
-///* GET sql page. */
-//router.get('/sql', function(req, res) {
-//    res.render('sql', { user: req.user });
-//});
-//
-///* GET clients page. */
-//router.get('/clients', function(req, res) {
-//    res.render('clients', { user: req.user });
-//});
-
-module.exports = router;

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/web-control-center/src/main/js/routes/sql.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/routes/sql.js b/modules/web-control-center/src/main/js/routes/sql.js
deleted file mode 100644
index ce4565d..0000000
--- a/modules/web-control-center/src/main/js/routes/sql.js
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-var router = require('express').Router();
-var db = require('../db');
-router.get('/', function(req, res) {
-    res.render('sql/sql');
-});
-
-module.exports = router;

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/web-control-center/src/main/js/routes/summary.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/routes/summary.js b/modules/web-control-center/src/main/js/routes/summary.js
deleted file mode 100644
index 9f8df2a..0000000
--- a/modules/web-control-center/src/main/js/routes/summary.js
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-var db = require('../db');
-
-var router = require('express').Router();
-
-var generatorXml = require('./generator/xml');
-var generatorJava = require('./generator/java');
-var generatorDocker = require('./generator/docker');
-
-/* GET summary page. */
-router.get('/', function (req, res) {
-    res.render('configuration/summary');
-});
-
-router.post('/generator', function (req, res) {
-    // Get cluster.
-    db.Cluster.findById(req.body._id).deepPopulate('caches caches.queryMetadata caches.storeMetadata').exec(function (err, cluster) {
-        if (err)
-            return res.status(500).send(err.message);
-
-        if (!cluster)
-            return res.sendStatus(404);
-
-        var clientCache = req.body.clientNearConfiguration;
-
-        if (clientCache)
-            return res.send({
-                xmlClient: generatorXml.generateClusterConfiguration(cluster, clientCache),
-                javaClient: generatorJava.generateClusterConfiguration(cluster, req.body.javaClass, clientCache)
-            });
-
-        return res.send({
-            xmlServer: generatorXml.generateClusterConfiguration(cluster),
-            javaSnippetServer: generatorJava.generateClusterConfiguration(cluster, false),
-            javaClassServer: generatorJava.generateClusterConfiguration(cluster, true),
-            docker: generatorDocker.generateClusterConfiguration(cluster, '%OS%')
-        });
-    });
-});
-
-router.post('/download', function (req, res) {
-    // Get cluster.
-    db.Cluster.findById(req.body._id).populate('caches').exec(function (err, cluster) {
-        if (err)
-            return res.status(500).send(err.message);
-
-        if (!cluster)
-            return res.sendStatus(404);
-
-        var clientNearConfiguration = req.body.clientNearConfiguration;
-
-        var archiver = require('archiver');
-
-        // Creating archive.
-        var zip = archiver('zip');
-
-        zip.on('error', function (err) {
-            res.status(500).send({error: err.message});
-        });
-
-        // On stream closed we can end the request.
-        res.on('close', function () {
-            return res.status(200).send('OK').end();
-        });
-
-        // Set the archive name.
-        res.attachment(cluster.name + (clientNearConfiguration ? '-client' : '') + '-configuration.zip');
-
-        var generatorCommon = require('./generator/common');
-
-        // Send the file to the page output.
-        zip.pipe(res);
-
-        var javaClass = req.body.javaClass;
-
-        if (!clientNearConfiguration) {
-            zip.append(generatorDocker.generateClusterConfiguration(cluster, req.body.os), {name: "Dockerfile"});
-
-            var props = generatorCommon.generateProperties(cluster);
-
-            if (props)
-                zip.append(props, {name: "secret.properties"});
-        }
-
-        zip.append(generatorXml.generateClusterConfiguration(cluster, clientNearConfiguration), {name: cluster.name + ".xml"})
-            .append(generatorJava.generateClusterConfiguration(cluster, javaClass, clientNearConfiguration),
-                {name: javaClass ? 'ConfigurationFactory.java' : cluster.name + '.snipplet.java'})
-            .finalize();
-    });
-});
-
-module.exports = router;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/web-control-center/src/main/js/views/configuration/caches.jade
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/views/configuration/caches.jade b/modules/web-control-center/src/main/js/views/configuration/caches.jade
deleted file mode 100644
index 15d8f40..0000000
--- a/modules/web-control-center/src/main/js/views/configuration/caches.jade
+++ /dev/null
@@ -1,74 +0,0 @@
-//-
-    Licensed to the Apache Software Foundation (ASF) under one or more
-    contributor license agreements.  See the NOTICE file distributed with
-    this work for additional information regarding copyright ownership.
-    The ASF licenses this file to You under the Apache License, Version 2.0
-    (the "License"); you may not use this file except in compliance with
-    the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
-
-extends sidebar
-
-append scripts
-    script(src='/caches-controller.js')
-
-include ../includes/controls
-
-block content
-    .docs-header
-        h1 Create and Configure Ignite Caches
-        hr
-    .docs-body(ng-controller='cachesController')
-        +block-callout('{{screenTip.workflowTitle}}', 'joinTip(screenTip.workflowContent)', '{{screenTip.whatsNextTitle}}', 'joinTip(screenTip.whatsNextContent)')
-        div(ng-hide='caches.length == 0')
-            .padding-dflt
-                lable.labelHeader Caches:
-                table.links(st-table='caches')
-                    tbody
-                        tr(ng-repeat='row in caches track by row._id')
-                            td.col-sm-6(ng-class='{active: row._id == selectedItem._id}')
-                                a(event-focus='click' event-focus-id='defaultFocusId' ng-click='selectItem(row)') {{$index + 1}}) {{row.name}}, {{row.mode | displayValue:modes:'Cache mode not set'}}, {{row.atomicityMode | displayValue:atomicities:'Cache atomicity not set'}}
-        .padding-top-dflt
-            button.btn.btn-primary(event-focus='click' event-focus-id='defaultFocusId' ng-click='createItem()') Add cache
-        hr
-        form.form-horizontal(name='inputForm' ng-if='backupItem' novalidate)
-            div(bs-collapse data-start-collapsed='false')
-                .panel.panel-default
-                    .panel-heading
-                        h3
-                            a(bs-collapse-toggle) General
-                    .panel-collapse(bs-collapse-target)
-                        .panel-body
-                            .settings-row(ng-repeat='field in general')
-                                +form-row(['col-sm-3'], ['col-sm-3'])
-            .panel-group(bs-collapse data-allow-multiple='true')
-                div(bs-collapse data-start-collapsed='true')
-                    .panel-title(ng-show='expanded')
-                        h3
-                            a(bs-collapse-toggle='0' ng-click='expanded = !expanded;') {{expanded ? 'Hide advanced settings...' : 'Show advanced settings...'}}
-                    .panel-collapse(bs-collapse-target)
-                        .span(bs-collapse data-start-collapsed='true' data-allow-multiple='true')
-                            .panel.panel-default(ng-repeat='group in advanced')
-                                .panel-heading
-                                    h3
-                                        a(bs-collapse-toggle) {{group.label}}
-                                        i.tipLabel.fa.fa-question-circle(ng-if='group.tip' bs-tooltip='joinTip(group.tip)' type='button')
-                                        i.tipLabel.fa.fa-question-circle.blank(ng-if='!group.tip')
-                                .panel-collapse(bs-collapse-target)
-                                    .panel-body
-                                        .settings-row(ng-repeat='field in group.fields')
-                                            +form-row
-                    .panel-title
-                        h3
-                            a(bs-collapse-toggle='0' ng-click='expanded = !expanded;') {{expanded ? 'Hide advanced settings...' : 'Show advanced settings...'}}
-            div
-                button.btn.btn-primary(ng-disabled='inputForm.$invalid' ng-click='saveItem()') Save
-                button.btn.btn-primary(ng-show='backupItem._id' ng-disabled='inputForm.$invalid' ng-click='saveItemAs()') Copy
-                button.btn.btn-primary.btn-second(ng-show='backupItem._id' ng-click='removeItem()') Remove

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/web-control-center/src/main/js/views/configuration/clusters.jade
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/views/configuration/clusters.jade b/modules/web-control-center/src/main/js/views/configuration/clusters.jade
deleted file mode 100644
index 239a31f..0000000
--- a/modules/web-control-center/src/main/js/views/configuration/clusters.jade
+++ /dev/null
@@ -1,77 +0,0 @@
-//-
-    Licensed to the Apache Software Foundation (ASF) under one or more
-    contributor license agreements.  See the NOTICE file distributed with
-    this work for additional information regarding copyright ownership.
-    The ASF licenses this file to You under the Apache License, Version 2.0
-    (the "License"); you may not use this file except in compliance with
-    the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
-
-extends sidebar
-
-append scripts
-    script(src='/clusters-controller.js')
-
-include ../includes/controls
-
-block content
-    .docs-header
-        h1 Create and Configure Ignite Clusters
-        hr
-    .docs-body(ng-controller='clustersController')
-        +block-callout('{{screenTip.workflowTitle}}', 'joinTip(screenTip.workflowContent)', '{{screenTip.whatsNextTitle}}', 'joinTip(screenTip.whatsNextContent)')
-        div(ng-hide='clusters.length == 0')
-            .padding-dflt
-                lable.labelHeader Clusters:
-                table.links(st-table='clusters')
-                    tbody
-                        tr(ng-repeat='row in clusters track by row._id')
-                            td.col-sm-6(ng-class='{active: row._id == selectedItem._id}')
-                                a(event-focus='click' event-focus-id='defaultFocusId' ng-click='selectItem(row)') {{$index + 1}}) {{row.name}}, {{row.discovery.kind | displayValue:discoveries:'Discovery not set'}}
-        .padding-top-dflt
-            button.btn.btn-primary(event-focus='click' event-focus-id='defaultFocusId' ng-click='createItem()') &nbspAdd cluster
-            label(style='margin-left: 10px; margin-right: 10px') Use template:
-            button.btn.btn-default.base-control(ng-init='create.template = templates[0].value' ng-model='create.template' data-template='/select' data-placeholder='Choose cluster template' bs-options='item.value as item.label for item in templates' bs-select)
-            i.tiplabel.fa.fa-question-circle(bs-tooltip data-title='{{joinTip(templateTip)}}' type='button')
-        hr
-        form.form-horizontal(name='inputForm' ng-if='backupItem' novalidate)
-            div(bs-collapse data-start-collapsed='false')
-                .panel.panel-default
-                    .panel-heading
-                        h3
-                            a(bs-collapse-toggle) General
-                    .panel-collapse(bs-collapse-target)
-                        .panel-body
-                            .settings-row(ng-repeat='field in general')
-                                +form-row
-            .panel-group(bs-collapse data-allow-multiple='true')
-                div(bs-collapse data-start-collapsed='true')
-                    .panel-title(ng-show='expanded')
-                        h3
-                            a(bs-collapse-toggle='0' ng-click='expanded = !expanded;') {{expanded ? 'Hide advanced settings...' : 'Show advanced settings...'}}
-                    .panel-collapse(bs-collapse-target)
-                        .span(bs-collapse data-start-collapsed='true' data-allow-multiple='true')
-                            .panel.panel-default(ng-repeat='group in advanced')
-                                .panel-heading
-                                    h3
-                                        a(bs-collapse-toggle) {{group.label}}
-                                        i.tipLabel.fa.fa-question-circle(ng-if='group.tip' bs-tooltip='joinTip(group.tip)' type='button')
-                                        i.tipLabel.fa.fa-question-circle.blank(ng-if='!group.tip')
-                                .panel-collapse(bs-collapse-target)
-                                    .panel-body
-                                        .settings-row(ng-repeat='field in group.fields')
-                                            +form-row
-                    .panel-title
-                        h3
-                            a(bs-collapse-toggle='0' ng-click='expanded = !expanded;') {{expanded ? 'Hide advanced settings...' : 'Show advanced settings...'}}
-            div
-                button.btn.btn-primary(ng-disabled='inputForm.$invalid' ng-click='saveItem()') Save
-                button.btn.btn-primary(ng-show='backupItem._id' ng-disabled='inputForm.$invalid' ng-click='saveItemAs()') Copy
-                button.btn.btn-primary(ng-show='backupItem._id' ng-click='removeItem()') Remove
\ No newline at end of file


[19/41] incubator-ignite git commit: IGNITE-843: WIP Generate cache type metadata groups.

Posted by an...@apache.org.
IGNITE-843: WIP Generate cache type metadata groups.


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

Branch: refs/heads/ignite-1121
Commit: 34cd6ec1abe4bb3097d15396b082bd4a043f6613
Parents: ce7ab19
Author: AKuznetsov <ak...@gridgain.com>
Authored: Tue Jul 28 13:30:52 2015 +0700
Committer: AKuznetsov <ak...@gridgain.com>
Committed: Tue Jul 28 13:30:52 2015 +0700

----------------------------------------------------------------------
 .../src/main/js/routes/generator/xml.js         | 54 +++++++++++++++++---
 1 file changed, 47 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/34cd6ec1/modules/web-control-center/src/main/js/routes/generator/xml.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/routes/generator/xml.js b/modules/web-control-center/src/main/js/routes/generator/xml.js
index 8009698..c266722 100644
--- a/modules/web-control-center/src/main/js/routes/generator/xml.js
+++ b/modules/web-control-center/src/main/js/routes/generator/xml.js
@@ -360,6 +360,7 @@ function addFields(res, meta, fieldsProperty) {
         });
 
         res.endBlock('</list>');
+        res.endBlock('</property>');
     }
 }
 
@@ -390,6 +391,39 @@ function addQueryFields(res, meta, fieldsProperty) {
     }
 }
 
+function addCacheTypeMetadataGroups(res, meta) {
+    var groups = meta.groups;
+
+    if (groups && groups.length > 0) {
+        res.startBlock('<property name="groups">');
+        res.startBlock('<map>');
+
+        _.forEach(groups, function (group) {
+            var fields = group.fields;
+
+            if (fields && fields.length > 0) {
+                res.startBlock('<entry key="' + group.name + '">');
+                res.startBlock('<map>');
+
+                _.forEach(fields, function (field) {
+                    res.startBlock('<entry key="' + field.name + '">');
+                    res.startBlock('<bean class="org.apache.ignite.lang.IgniteBiTuple">');
+                    res.line('<constructor-arg value="java.lang.String"/>');
+                    res.line('<constructor-arg value="false"/>');
+                    res.endBlock('</bean>');
+                    res.endBlock('</entry>');
+                });
+
+                res.endBlock('</map>');
+                res.endBlock('</entry>');
+            }
+        });
+
+        res.endBlock('</map>');
+        res.endBlock('</property>');
+    }
+}
+
 function generateCacheTypeMetadataConfiguration(metaCfg, res) {
     if (!res)
         res = generatorUtils.builder();
@@ -411,6 +445,8 @@ function generateCacheTypeMetadataConfiguration(metaCfg, res) {
 
     addListProperty(res, metaCfg, 'textFields');
 
+    addCacheTypeMetadataGroups(res, metaCfg);
+
     res.endBlock('</bean>');
 
     return res;
@@ -552,24 +588,28 @@ function generateCacheConfiguration(cacheCfg, res) {
         res.startBlock('<property name="typeMetadata">');
         res.startBlock('<list>');
 
-        var metas = [];
+        var metaNames = [];
 
         if (cacheCfg.queryMetadata && cacheCfg.queryMetadata.length > 0) {
             _.forEach(cacheCfg.queryMetadata, function (meta) {
-                metas.push(meta);
+                if (!_.contains(metaNames, meta.name)) {
+                    metaNames.push(meta.name);
+
+                    generateCacheTypeMetadataConfiguration(meta, res);
+                }
             });
         }
 
         if (cacheCfg.storeMetadata && cacheCfg.storeMetadata.length > 0) {
             _.forEach(cacheCfg.storeMetadata, function (meta) {
-                metas.push(meta);
+                if (!_.contains(metaNames, meta.name)) {
+                    metaNames.push(meta.name);
+
+                    generateCacheTypeMetadataConfiguration(meta, res);
+                }
             });
         }
 
-        _.forEach(metas, function (meta) {
-            generateCacheTypeMetadataConfiguration(meta, res);
-        });
-
         res.endBlock('</list>');
         res.endBlock('</property>');
     }


[33/41] incubator-ignite git commit: # ignite-843 Rename

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/control-center-web/src/main/js/routes/generator/xml.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/routes/generator/xml.js b/modules/control-center-web/src/main/js/routes/generator/xml.js
new file mode 100644
index 0000000..079f268
--- /dev/null
+++ b/modules/control-center-web/src/main/js/routes/generator/xml.js
@@ -0,0 +1,736 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var _ = require('lodash');
+
+var generatorUtils = require("./common");
+var dataStructures = require("../../helpers/data-structures.js");
+
+exports.generateClusterConfiguration = function(cluster, clientNearConfiguration) {
+    var res = generatorUtils.builder();
+
+    res.datasources = [];
+    res.deep = 1;
+
+    if (clientNearConfiguration) {
+        res.startBlock('<bean id="nearCacheBean" class="org.apache.ignite.configuration.NearCacheConfiguration">');
+
+        if (clientNearConfiguration.nearStartSize)
+            addProperty(res, clientNearConfiguration, 'nearStartSize');
+
+        if (clientNearConfiguration.nearEvictionPolicy && clientNearConfiguration.nearEvictionPolicy.kind)
+            createEvictionPolicy(res, clientNearConfiguration.nearEvictionPolicy, 'nearEvictionPolicy');
+
+        res.endBlock('</bean>');
+
+        res.line();
+    }
+
+    // Generate Ignite Configuration.
+    res.startBlock('<bean class="org.apache.ignite.configuration.IgniteConfiguration">');
+
+    if (clientNearConfiguration) {
+        res.line('<property name="clientMode" value="true" />');
+
+        res.line();
+    }
+
+    // Generate discovery.
+    if (cluster.discovery) {
+        res.startBlock('<property name="discoverySpi">');
+        res.startBlock('<bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi">');
+        res.startBlock('<property name="ipFinder">');
+
+        var d = cluster.discovery;
+
+        switch (d.kind) {
+            case 'Multicast':
+                res.startBlock('<bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.multicast.TcpDiscoveryMulticastIpFinder">');
+
+                addProperty(res, d.Multicast, 'multicastGroup');
+                addProperty(res, d.Multicast, 'multicastPort');
+                addProperty(res, d.Multicast, 'responseWaitTime');
+                addProperty(res, d.Multicast, 'addressRequestAttempts');
+                addProperty(res, d.Multicast, 'localAddress');
+
+                res.endBlock('</bean>');
+
+                break;
+
+            case 'Vm':
+                if (d.Vm.addresses.length > 0) {
+                    res.startBlock('<bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder">');
+
+                    addListProperty(res, d.Vm, 'addresses');
+
+                    res.endBlock('</bean>');
+                }
+                else {
+                    res.line('<bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder"/>');
+                }
+
+                break;
+
+            case 'S3':
+                res.startBlock('<bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.s3.TcpDiscoveryS3IpFinder">');
+
+                if (d.S3 && d.S3.bucketName)
+                    res.line('<property name="bucketName" value="' + escapeAttr(d.S3.bucketName) + '" />');
+
+                res.endBlock('</bean>');
+
+                break;
+
+            case 'Cloud':
+                res.startBlock('<bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.cloud.TcpDiscoveryCloudIpFinder">');
+
+                addProperty(res, d.Cloud, 'credential');
+                addProperty(res, d.Cloud, 'credentialPath');
+                addProperty(res, d.Cloud, 'identity');
+                addProperty(res, d.Cloud, 'provider');
+                addListProperty(res, d.Cloud, 'regions');
+                addListProperty(res, d.Cloud, 'zones');
+
+                res.endBlock('</bean>');
+
+                break;
+
+            case 'GoogleStorage':
+                res.startBlock('<bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.gce.TcpDiscoveryGoogleStorageIpFinder">');
+
+                addProperty(res, d.GoogleStorage, 'projectName');
+                addProperty(res, d.GoogleStorage, 'bucketName');
+                addProperty(res, d.GoogleStorage, 'serviceAccountP12FilePath');
+
+                //if (d.GoogleStorage.addrReqAttempts) todo ????
+                //    res.line('<property name="serviceAccountP12FilePath" value="' + escapeAttr(d.GoogleStorage.addrReqAttempts) + '"/>');
+
+                res.endBlock('</bean>');
+
+                break;
+
+            case 'Jdbc':
+                res.startBlock('<bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.jdbc.TcpDiscoveryJdbcIpFinder">');
+                res.line('<property name="initSchema" value="' + (d.Jdbc.initSchema != null || d.Jdbc.initSchema) + '"/>');
+                res.endBlock('</bean>');
+
+                break;
+
+            case 'SharedFs':
+                if (d.SharedFs.path) {
+                    res.startBlock('<bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.sharedfs.TcpDiscoverySharedFsIpFinder">');
+                    addProperty(res, d.SharedFs, 'path');
+                    res.endBlock('</bean>');
+                }
+                else {
+                    res.line('<bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.sharedfs.TcpDiscoverySharedFsIpFinder"/>');
+                }
+
+                break;
+
+            default:
+                throw "Unknown discovery kind: " + d.kind;
+        }
+
+        res.endBlock('</property>');
+        res.endBlock('</bean>');
+        res.endBlock('</property>');
+
+        res.needEmptyLine = true
+    }
+
+    // Generate atomics group.
+    addBeanWithProperties(res, cluster.atomicConfiguration, 'atomicConfiguration',
+        generatorUtils.atomicConfiguration.className, generatorUtils.atomicConfiguration.fields);
+    res.needEmptyLine = true;
+
+    // Generate communication group.
+    addProperty(res, cluster, 'networkTimeout');
+    addProperty(res, cluster, 'networkSendRetryDelay');
+    addProperty(res, cluster, 'networkSendRetryCount');
+    addProperty(res, cluster, 'segmentCheckFrequency');
+    addProperty(res, cluster, 'waitForSegmentOnStart');
+    addProperty(res, cluster, 'discoveryStartupDelay');
+    res.needEmptyLine = true;
+
+    // Generate deployment group.
+    addProperty(res, cluster, 'deploymentMode');
+    res.needEmptyLine = true;
+
+    // Generate events group.
+    if (cluster.includeEventTypes && cluster.includeEventTypes.length > 0) {
+        res.emptyLineIfNeeded();
+        
+        res.startBlock('<property name="includeEventTypes">');
+        
+        if (cluster.includeEventTypes.length == 1)
+            res.line('<util:constant static-field="org.apache.ignite.events.EventType.' + cluster.includeEventTypes[0] + '"/>');
+        else {
+            res.startBlock('<array>');
+
+            for (i = 0; i < cluster.includeEventTypes.length; i++) {
+                if (i > 0)
+                    res.line();
+
+                var eventGroup = cluster.includeEventTypes[i];
+
+                res.line('<!-- EventType.' + eventGroup + ' -->');
+
+                var eventList = dataStructures.eventGroups[eventGroup];
+
+                for (var k = 0; k < eventList.length; k++) {
+                    res.line('<util:constant static-field="org.apache.ignite.events.EventType.' + eventList[k] + '"/>')
+                }
+            }
+
+            res.endBlock('</array>');
+        }
+        
+        res.endBlock('</property>');
+
+        res.needEmptyLine = true;
+    }
+
+    // Generate marshaller group.
+    var marshaller = cluster.marshaller;
+
+    if (marshaller && marshaller.kind) {
+        var marshallerDesc = generatorUtils.marshallers[marshaller.kind];
+
+        addBeanWithProperties(res, marshaller[marshaller.kind], 'marshaller', marshallerDesc.className, marshallerDesc.fields, true);
+        res.needEmptyLine = true;
+    }
+
+    addProperty(res, cluster, 'marshalLocalJobs');
+    addProperty(res, cluster, 'marshallerCacheKeepAliveTime');
+    addProperty(res, cluster, 'marshallerCacheThreadPoolSize');
+    res.needEmptyLine = true;
+
+    // Generate metrics group.
+    addProperty(res, cluster, 'metricsExpireTime');
+    addProperty(res, cluster, 'metricsHistorySize');
+    addProperty(res, cluster, 'metricsLogFrequency');
+    addProperty(res, cluster, 'metricsUpdateFrequency');
+    res.needEmptyLine = true;
+
+    // Generate PeerClassLoading group.
+    addProperty(res, cluster, 'peerClassLoadingEnabled');
+    addListProperty(res, cluster, 'peerClassLoadingLocalClassPathExclude');
+    addProperty(res, cluster, 'peerClassLoadingMissedResourcesCacheSize');
+    addProperty(res, cluster, 'peerClassLoadingThreadPoolSize');
+    res.needEmptyLine = true;
+
+    // Generate swap group.
+    if (cluster.swapSpaceSpi && cluster.swapSpaceSpi.kind == 'FileSwapSpaceSpi') {
+        addBeanWithProperties(res, cluster.swapSpaceSpi.FileSwapSpaceSpi, 'swapSpaceSpi',
+            generatorUtils.swapSpaceSpi.className, generatorUtils.swapSpaceSpi.fields, true);
+
+        res.needEmptyLine = true;
+    }
+
+    // Generate time group.
+    addProperty(res, cluster, 'clockSyncSamples');
+    addProperty(res, cluster, 'clockSyncFrequency');
+    addProperty(res, cluster, 'timeServerPortBase');
+    addProperty(res, cluster, 'timeServerPortRange');
+    res.needEmptyLine = true;
+
+    // Generate thread pools group.
+    addProperty(res, cluster, 'publicThreadPoolSize');
+    addProperty(res, cluster, 'systemThreadPoolSize');
+    addProperty(res, cluster, 'managementThreadPoolSize');
+    addProperty(res, cluster, 'igfsThreadPoolSize');
+    res.needEmptyLine = true;
+
+    // Generate transactions group.
+    addBeanWithProperties(res, cluster.transactionConfiguration, 'transactionConfiguration',
+        generatorUtils.transactionConfiguration.className, generatorUtils.transactionConfiguration.fields);
+    res.needEmptyLine = true;
+
+    // Generate caches configs.
+    if (cluster.caches && cluster.caches.length > 0) {
+        res.emptyLineIfNeeded();
+
+        res.startBlock('<property name="cacheConfiguration">');
+        res.startBlock('<list>');
+
+        for (var i = 0; i < cluster.caches.length; i++) {
+            if (i > 0)
+                res.line();
+
+            var cache = cluster.caches[i];
+
+            generateCacheConfiguration(res, cache);
+        }
+
+        res.endBlock('</list>');
+        res.endBlock('</property>');
+
+        res.needEmptyLine = true;
+    }
+
+    res.endBlock('</bean>');
+
+    // Build final XML:
+    // 1. Add header.
+    var xml = '<?xml version="1.0" encoding="UTF-8"?>\n\n';
+
+    xml += '<!-- ' + generatorUtils.mainComment() + ' -->\n';
+    xml += '<beans xmlns="http://www.springframework.org/schema/beans"\n';
+    xml += '       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\n';
+    xml += '       xmlns:util="http://www.springframework.org/schema/util"\n';
+    xml += '       xsi:schemaLocation="http://www.springframework.org/schema/beans\n';
+    xml += '                           http://www.springframework.org/schema/beans/spring-beans.xsd\n';
+    xml += '                           http://www.springframework.org/schema/util\n';
+    xml += '                           http://www.springframework.org/schema/util/spring-util.xsd">\n';
+
+    // 2. Add external property file and all data sources.
+    if (res.datasources.length > 0) {
+        xml += '    <!-- Load external properties file. -->\n';
+        xml += '    <bean id="placeholderConfig" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">\n';
+        xml += '        <property name="location" value="classpath:secret.properties"/>\n';
+        xml += '    </bean>\n\n';
+
+        xml += '    <!-- Data source beans will be initialized from external properties file. -->\n';
+
+        _.forEach(res.datasources, function(item) {
+            var beanId = item.dataSourceBean;
+
+            xml += '    <bean id= "' + beanId + '" class="' + item.className + '">\n';
+            xml += '        <property name="URL" value="${' + beanId + '.jdbc.url}" />\n';
+            xml += '        <property name="user" value="${' + beanId + '.jdbc.username}" />\n';
+            xml += '        <property name="password" value="${' + beanId + '.jdbc.password}" />\n';
+            xml += '    </bean>\n\n';
+        });
+    }
+
+    // 3. Add main content.
+    xml += res.join('');
+
+    // 4. Add footer.
+    xml += '</beans>\n';
+
+    return xml;
+};
+
+function createEvictionPolicy(res, evictionPolicy, propertyName) {
+    if (evictionPolicy && evictionPolicy.kind) {
+        var e = generatorUtils.evictionPolicies[evictionPolicy.kind];
+
+        var obj = evictionPolicy[evictionPolicy.kind.toUpperCase()];
+
+        addBeanWithProperties(res, obj, propertyName, e.className, e.fields, true);
+    }
+}
+
+function addCacheTypeMetadataDatabaseFields(res, meta, fieldsProperty) {
+    var fields = meta[fieldsProperty];
+
+    if (fields && fields.length > 0) {
+        res.startBlock('<property name="' + fieldsProperty + '">');
+
+        res.startBlock('<list>');
+
+        _.forEach(fields, function (field) {
+            res.startBlock('<bean class="org.apache.ignite.cache.CacheTypeFieldMetadata">');
+
+            addProperty(res, field, 'databaseName');
+
+            res.startBlock('<property name="databaseType">');
+            res.line('<util:constant static-field="java.sql.Types.' + field.databaseType + '"/>');
+            res.endBlock('</property>');
+
+            addProperty(res, field, 'javaName');
+
+            addElement(res, 'property', 'name', 'javaType', 'value', generatorUtils.javaBuildInClass(field.javaType));
+
+            res.endBlock('</bean>');
+        });
+
+        res.endBlock('</list>');
+        res.endBlock('</property>');
+    }
+}
+
+function addCacheTypeMetadataQueryFields(res, meta, fieldsProperty) {
+    var fields = meta[fieldsProperty];
+
+    if (fields && fields.length > 0) {
+        res.startBlock('<property name="' + fieldsProperty + '">');
+
+        res.startBlock('<map>');
+
+        _.forEach(fields, function (field) {
+            addElement(res, 'entry', 'key', field.name, 'value', generatorUtils.javaBuildInClass(field.className));
+        });
+
+        res.endBlock('</map>');
+
+        res.endBlock('</property>');
+    }
+}
+
+function addCacheTypeMetadataGroups(res, meta) {
+    var groups = meta.groups;
+
+    if (groups && groups.length > 0) {
+        res.startBlock('<property name="groups">');
+        res.startBlock('<map>');
+
+        _.forEach(groups, function (group) {
+            var fields = group.fields;
+
+            if (fields && fields.length > 0) {
+                res.startBlock('<entry key="' + group.name + '">');
+                res.startBlock('<map>');
+
+                _.forEach(fields, function (field) {
+                    res.startBlock('<entry key="' + field.name + '">');
+
+                    res.startBlock('<bean class="org.apache.ignite.lang.IgniteBiTuple">');
+                    res.line('<constructor-arg value="' + generatorUtils.javaBuildInClass(field.className) + '"/>');
+                    res.line('<constructor-arg value="' + field.direction + '"/>');
+                    res.endBlock('</bean>');
+
+                    res.endBlock('</entry>');
+                });
+
+                res.endBlock('</map>');
+                res.endBlock('</entry>');
+            }
+        });
+
+        res.endBlock('</map>');
+        res.endBlock('</property>');
+    }
+}
+
+function generateCacheTypeMetadataConfiguration(res, meta) {
+    if (!res)
+        res = generatorUtils.builder();
+
+    res.startBlock('<bean class="org.apache.ignite.cache.CacheTypeMetadata">');
+
+    addProperty(res, meta, 'databaseSchema');
+    addProperty(res, meta, 'databaseTable');
+
+    addProperty(res, meta, 'keyType');
+    addProperty(res, meta, 'valueType');
+
+    addCacheTypeMetadataDatabaseFields(res, meta, 'keyFields');
+    addCacheTypeMetadataDatabaseFields(res, meta, 'valueFields');
+
+    addCacheTypeMetadataQueryFields(res, meta, 'queryFields');
+    addCacheTypeMetadataQueryFields(res, meta, 'ascendingFields');
+    addCacheTypeMetadataQueryFields(res, meta, 'descendingFields');
+
+    addListProperty(res, meta, 'textFields');
+
+    addCacheTypeMetadataGroups(res, meta);
+
+    res.endBlock('</bean>');
+
+    return res;
+}
+
+function generateCacheConfiguration(res, cacheCfg) {
+    if (!res)
+        res = generatorUtils.builder();
+
+    res.startBlock('<bean class="org.apache.ignite.configuration.CacheConfiguration">');
+
+    addProperty(res, cacheCfg, 'name');
+
+    res.needEmptyLine = true;
+
+    addProperty(res, cacheCfg, 'mode', 'cacheMode');
+
+    addProperty(res, cacheCfg, 'atomicityMode');
+    addProperty(res, cacheCfg, 'backups');
+    addProperty(res, cacheCfg, 'startSize');
+    addProperty(res, cacheCfg, 'readFromBackup');
+
+    res.needEmptyLine = true;
+
+    addProperty(res, cacheCfg, 'memoryMode');
+    addProperty(res, cacheCfg, 'offHeapMaxMemory');
+    addProperty(res, cacheCfg, 'swapEnabled');
+    addProperty(res, cacheCfg, 'copyOnRead');
+
+    res.needEmptyLine = true;
+
+    createEvictionPolicy(res, cacheCfg.evictionPolicy, 'evictionPolicy');
+
+    res.needEmptyLine = true;
+
+    if (cacheCfg.nearCacheEnabled) {
+        res.emptyLineIfNeeded();
+
+        res.startBlock('<property name="nearConfiguration">');
+        res.startBlock('<bean class="org.apache.ignite.configuration.NearCacheConfiguration">');
+
+        if (cacheCfg.nearConfiguration && cacheCfg.nearConfiguration.nearStartSize)
+            addProperty(res, cacheCfg.nearConfiguration, 'nearStartSize');
+
+        if (cacheCfg.nearConfiguration && cacheCfg.nearConfiguration.nearEvictionPolicy.kind)
+            createEvictionPolicy(res, cacheCfg.nearConfiguration.nearEvictionPolicy, 'nearEvictionPolicy');
+
+        res.endBlock('</bean>');
+        res.endBlock('</property>');
+    }
+
+    res.needEmptyLine = true;
+
+    addProperty(res, cacheCfg, 'sqlEscapeAll');
+    addProperty(res, cacheCfg, 'sqlOnheapRowCacheSize');
+    addProperty(res, cacheCfg, 'longQueryWarningTimeout');
+
+    if (cacheCfg.indexedTypes && cacheCfg.indexedTypes.length > 0) {
+        res.startBlock('<property name="indexedTypes">');
+        res.startBlock('<list>');
+
+        for (var i = 0; i < cacheCfg.indexedTypes.length; i++) {
+            var pair = cacheCfg.indexedTypes[i];
+
+            res.line('<value>' + generatorUtils.javaBuildInClass(pair.keyClass) + '</value>');
+            res.line('<value>' + generatorUtils.javaBuildInClass(pair.valueClass) + '</value>');
+        }
+
+        res.endBlock('</list>');
+        res.endBlock('</property>');
+    }
+
+    addListProperty(res, cacheCfg, 'sqlFunctionClasses', 'array');
+
+    res.needEmptyLine = true;
+
+    addProperty(res, cacheCfg, 'rebalanceMode');
+    addProperty(res, cacheCfg, 'rebalanceThreadPoolSize');
+    addProperty(res, cacheCfg, 'rebalanceBatchSize');
+    addProperty(res, cacheCfg, 'rebalanceOrder');
+    addProperty(res, cacheCfg, 'rebalanceDelay');
+    addProperty(res, cacheCfg, 'rebalanceTimeout');
+    addProperty(res, cacheCfg, 'rebalanceThrottle');
+
+    res.needEmptyLine = true;
+
+    if (cacheCfg.cacheStoreFactory && cacheCfg.cacheStoreFactory.kind) {
+        var storeFactory = cacheCfg.cacheStoreFactory[cacheCfg.cacheStoreFactory.kind];
+        var data = generatorUtils.storeFactories[cacheCfg.cacheStoreFactory.kind];
+
+        addBeanWithProperties(res, storeFactory, 'cacheStoreFactory', data.className, data.fields, true);
+
+        if (storeFactory.dialect) {
+            if (_.findIndex(res.datasources, function (ds) {
+                    return ds.dataSourceBean == storeFactory.dataSourceBean;
+                }) < 0) {
+                res.datasources.push({
+                    dataSourceBean: storeFactory.dataSourceBean,
+                    className: generatorUtils.dataSources[storeFactory.dialect]
+                });
+            }
+        }
+    }
+
+    res.needEmptyLine = true;
+
+    addProperty(res, cacheCfg, 'loadPreviousValue');
+    addProperty(res, cacheCfg, 'readThrough');
+    addProperty(res, cacheCfg, 'writeThrough');
+
+    res.needEmptyLine = true;
+
+    addProperty(res, cacheCfg, 'invalidate');
+    addProperty(res, cacheCfg, 'defaultLockTimeout');
+    addProperty(res, cacheCfg, 'transactionManagerLookupClassName');
+
+    res.needEmptyLine = true;
+
+    addProperty(res, cacheCfg, 'writeBehindEnabled');
+    addProperty(res, cacheCfg, 'writeBehindBatchSize');
+    addProperty(res, cacheCfg, 'writeBehindFlushSize');
+    addProperty(res, cacheCfg, 'writeBehindFlushFrequency');
+    addProperty(res, cacheCfg, 'writeBehindFlushThreadCount');
+
+    res.needEmptyLine = true;
+
+    addProperty(res, cacheCfg, 'statisticsEnabled');
+    addProperty(res, cacheCfg, 'managementEnabled');
+
+    res.needEmptyLine = true;
+
+    addProperty(res, cacheCfg, 'maxConcurrentAsyncOperations');
+
+    // Generate cache type metadata configs.
+    if ((cacheCfg.queryMetadata && cacheCfg.queryMetadata.length > 0) ||
+        (cacheCfg.storeMetadata && cacheCfg.storeMetadata.length > 0)) {
+        res.emptyLineIfNeeded();
+
+        res.startBlock('<property name="typeMetadata">');
+        res.startBlock('<list>');
+
+        var metaNames = [];
+
+        if (cacheCfg.queryMetadata && cacheCfg.queryMetadata.length > 0) {
+            _.forEach(cacheCfg.queryMetadata, function (meta) {
+                if (!_.contains(metaNames, meta.name)) {
+                    metaNames.push(meta.name);
+
+                    generateCacheTypeMetadataConfiguration(res, meta);
+                }
+            });
+        }
+
+        if (cacheCfg.storeMetadata && cacheCfg.storeMetadata.length > 0) {
+            _.forEach(cacheCfg.storeMetadata, function (meta) {
+                if (!_.contains(metaNames, meta.name)) {
+                    metaNames.push(meta.name);
+
+                    generateCacheTypeMetadataConfiguration(res, meta);
+                }
+            });
+        }
+
+        res.endBlock('</list>');
+        res.endBlock('</property>');
+    }
+
+    res.endBlock('</bean>');
+
+    return res;
+}
+
+function addElement(res, tag, attr1, val1, attr2, val2) {
+    var elem = '<' + tag;
+
+    if (attr1) {
+        elem += ' ' + attr1 + '="' + val1 + '"'
+    }
+
+    if (attr2) {
+        elem += ' ' + attr2 + '="' + val2 + '"'
+    }
+
+    elem += '/>';
+
+    res.emptyLineIfNeeded();
+    res.line(elem);
+}
+
+function addProperty(res, obj, propName, setterName) {
+    var val = obj[propName];
+
+    if (generatorUtils.isDefined(val))
+        addElement(res, 'property', 'name', setterName ? setterName : propName, 'value', escapeAttr(val));
+}
+
+function addBeanWithProperties(res, bean, beanPropName, beanClass, props, createBeanAlthoughNoProps) {
+    if (bean && generatorUtils.hasProperty(bean, props)) {
+        res.emptyLineIfNeeded();
+        res.startBlock('<property name="' + beanPropName + '">');
+        res.startBlock('<bean class="' + beanClass + '">');
+
+        for (var propName in props) {
+            if (props.hasOwnProperty(propName)) {
+                var descr = props[propName];
+
+                if (descr) {
+                    if (descr.type == 'list') {
+                        addListProperty(res, bean, propName, descr.setterName);
+                    }
+                    else if (descr.type == 'className') {
+                        if (bean[propName]) {
+                            res.startBlock('<property name="' + propName + '">');
+                            res.line('<bean class="' + generatorUtils.knownClasses[bean[propName]].className + '"/>');
+                            res.endBlock('</property>');
+                        }
+                    }
+                    else if (descr.type == 'propertiesAsList') {
+                        var val = bean[propName];
+
+                        if (val && val.length > 0) {
+                            res.startBlock('<property name="' + propName + '">');
+                            res.startBlock('<props>');
+
+                            for (var i = 0; i < val.length; i++) {
+                                var nameAndValue = val[i];
+
+                                var eqIndex = nameAndValue.indexOf('=');
+                                if (eqIndex >= 0) {
+                                    res.line('<prop key="' + escapeAttr(nameAndValue.substring(0, eqIndex)) + '">' +
+                                            + escape(nameAndValue.substr(eqIndex + 1)) + '</prop>');
+                                }
+                            }
+
+                            res.endBlock('</props>');
+                            res.endBlock('</property>');
+                        }
+                    }
+                    else
+                        addProperty(res, bean, propName, descr.setterName);
+                }
+                else
+                    addProperty(res, bean, propName);
+            }
+        }
+
+        res.endBlock('</bean>');
+        res.endBlock('</property>');
+    }
+    else if (createBeanAlthoughNoProps) {
+        res.emptyLineIfNeeded();
+        res.line('<property name="' + beanPropName + '">');
+        res.line('    <bean class="' + beanClass + '"/>');
+        res.line('</property>');
+    }
+}
+function addListProperty(res, obj, propName, listType, rowFactory) {
+    var val = obj[propName];
+
+    if (val && val.length > 0) {
+        res.emptyLineIfNeeded();
+
+        if (!listType)
+            listType = 'list';
+
+        if (!rowFactory)
+            rowFactory = function(val) { return '<value>' + escape(val) + '</value>' };
+
+        res.startBlock('<property name="' + propName + '">');
+        res.startBlock('<' + listType + '>');
+
+        for (var i = 0; i < val.length; i++)
+            res.line(rowFactory(val[i]));
+
+        res.endBlock('</' + listType + '>');
+        res.endBlock('</property>');
+    }
+}
+
+function escapeAttr(s) {
+    if (typeof(s) != 'string')
+        return s;
+
+    return s.replace(/&/g, '&amp;').replace(/"/g, '&quot;');
+}
+
+function escape(s) {
+    if (typeof(s) != 'string')
+        return s;
+
+    return s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/control-center-web/src/main/js/routes/metadata.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/routes/metadata.js b/modules/control-center-web/src/main/js/routes/metadata.js
new file mode 100644
index 0000000..0af624e
--- /dev/null
+++ b/modules/control-center-web/src/main/js/routes/metadata.js
@@ -0,0 +1,95 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var router = require('express').Router();
+var db = require('../db');
+
+/* GET metadata page. */
+router.get('/', function (req, res) {
+    res.render('configuration/metadata');
+});
+
+/**
+ * Get spaces and metadata accessed for user account.
+ *
+ * @param req Request.
+ * @param res Response.
+ */
+router.post('/list', function (req, res) {
+    var user_id = req.currentUserId();
+
+    // Get owned space and all accessed space.
+    db.Space.find({$or: [{owner: user_id}, {usedBy: {$elemMatch: {account: user_id}}}]}, function (err, spaces) {
+        if (err)
+            return res.status(500).send(err.message);
+
+        var space_ids = spaces.map(function (value) {
+            return value._id;
+        });
+
+        // Get all metadata for spaces.
+        db.CacheTypeMetadata.find({space: {$in: space_ids}}).sort('name').exec(function (err, metadatas) {
+            if (err)
+                return res.status(500).send(err.message);
+
+            res.json({spaces: spaces, metadatas: metadatas});
+        });
+    });
+});
+
+/**
+ * Save metadata.
+ */
+router.post('/save', function (req, res) {
+    if (req.body._id)
+        db.CacheTypeMetadata.update({_id: req.body._id}, req.body, {upsert: true}, function (err) {
+            if (err)
+                return res.status(500).send(err.message);
+
+            res.send(req.body._id);
+        });
+    else {
+        db.CacheTypeMetadata.findOne({space: req.body.space, name: req.body.name}, function (err, metadata) {
+            if (err)
+                return res.status(500).send(err.message);
+
+            if (metadata)
+                return res.status(500).send('Cache type metadata with name: "' + metadata.name + '" already exist.');
+
+            (new db.CacheTypeMetadata(req.body)).save(function (err, metadata) {
+                if (err)
+                    return res.status(500).send(err.message);
+
+                res.send(metadata._id);
+            });
+        });
+    }
+});
+
+/**
+ * Remove metadata by ._id.
+ */
+router.post('/remove', function (req, res) {
+    db.CacheTypeMetadata.remove(req.body, function (err) {
+        if (err)
+            return res.status(500).send(err.message);
+
+        res.sendStatus(200);
+    })
+});
+
+module.exports = router;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/control-center-web/src/main/js/routes/profile.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/routes/profile.js b/modules/control-center-web/src/main/js/routes/profile.js
new file mode 100644
index 0000000..0269e7d
--- /dev/null
+++ b/modules/control-center-web/src/main/js/routes/profile.js
@@ -0,0 +1,97 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var router = require('express').Router();
+var db = require('../db');
+
+router.all('/profile/*', function (req, res, next) {
+    var userId = req.body._id;
+
+    if (userId != req.currentUserId() && userId != req.user._id)
+        return res.sendStatus(403);
+    else
+        next();
+});
+
+/**
+ * Get user profile page.
+ */
+router.get('/', function (req, res) {
+    var user_id = req.currentUserId();
+
+    db.Account.findById(user_id, function (err) {
+        if (err)
+            return res.status(500).send(err.message);
+
+        res.render('settings/profile');
+    });
+});
+
+/**
+ * Save user profile.
+ */
+router.post('/saveUser', function (req, res) {
+    var params = req.body;
+
+    if (params.newPassword) {
+        var newPassword = params.newPassword;
+
+        if (!newPassword || newPassword.length == 0)
+            return res.status(500).send('Wrong value for new password');
+
+        db.Account.findById(params._id, function (err, user) {
+            if (err)
+                return res.status(500).send(err);
+
+            user.setPassword(newPassword, function (err, updatedUser) {
+                if (err)
+                    return res.status(500).send(err.message);
+
+                if (params.userName)
+                    updatedUser.username = params.userName;
+
+                if (params.email)
+                    updatedUser.email = params.email;
+
+                updatedUser.save(function (err) {
+                    if (err)
+                        return res.status(500).send(err.message);
+
+                    res.json(user);
+                });
+            });
+        });
+    }
+    else if (params.userName || params.email) {
+        var upd = {};
+
+        if (params.userName)
+            upd.username = params.userName;
+
+        if (params.email)
+            upd.email = params.email;
+
+        db.Account.findByIdAndUpdate(params._id, upd, {new: true}, function (err, val) {
+            if (err)
+                return res.status(500).send(err.message);
+
+            res.json(val);
+        })
+    }
+});
+
+module.exports = router;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/control-center-web/src/main/js/routes/public.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/routes/public.js b/modules/control-center-web/src/main/js/routes/public.js
new file mode 100644
index 0000000..b3cb983
--- /dev/null
+++ b/modules/control-center-web/src/main/js/routes/public.js
@@ -0,0 +1,123 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var router = require('express').Router();
+var passport = require('passport');
+var db = require('../db');
+
+// GET dropdown-menu template.
+router.get('/select', function (req, res) {
+    res.render('templates/select', {});
+});
+
+// GET dynamic tabs template.
+router.get('/tab', function (req, res) {
+    res.render('templates/tab', {});
+});
+
+// GET confirmation dialog.
+router.get('/confirm', function (req, res) {
+    res.render('templates/confirm', {});
+});
+
+// GET copy dialog.
+router.get('/copy', function (req, res) {
+    res.render('templates/copy', {});
+});
+
+/* GET login page. */
+router.get('/login', function (req, res) {
+    res.render('login');
+});
+
+/**
+ * Register new account.
+ */
+router.post('/register', function (req, res) {
+    db.Account.count(function (err, cnt) {
+        if (err)
+            return res.status(401).send(err.message);
+
+        req.body.admin = cnt == 0;
+
+        db.Account.register(new db.Account(req.body), req.body.password, function (err, account) {
+            if (err)
+                return res.status(401).send(err.message);
+
+            if (!account)
+                return res.status(500).send('Failed to create account.');
+
+            new db.Space({name: 'Personal space', owner: account._id}).save();
+
+            req.logIn(account, {}, function (err) {
+                if (err)
+                    return res.status(401).send(err.message);
+
+                return res.redirect('/configuration/clusters');
+            });
+        });
+    });
+});
+
+/**
+ * Login in exist account.
+ */
+router.post('/login', function (req, res, next) {
+    passport.authenticate('local', function (err, user) {
+        if (err)
+            return res.status(401).send(err.message);
+
+        if (!user)
+            return res.status(401).send('Invalid email or password');
+
+        req.logIn(user, {}, function (err) {
+            if (err)
+                return res.status(401).send(err.message);
+
+            res.redirect('/configuration/clusters');
+        });
+    })(req, res, next);
+});
+
+/**
+ * Logout.
+ */
+router.get('/logout', function (req, res) {
+    req.logout();
+
+    res.redirect('/');
+});
+
+/* GET home page. */
+router.get('/', function (req, res) {
+    if (req.isAuthenticated())
+        res.redirect('/configuration/clusters');
+    else
+        res.render('index');
+});
+
+///* GET sql page. */
+//router.get('/sql', function(req, res) {
+//    res.render('sql', { user: req.user });
+//});
+//
+///* GET clients page. */
+//router.get('/clients', function(req, res) {
+//    res.render('clients', { user: req.user });
+//});
+
+module.exports = router;

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/control-center-web/src/main/js/routes/sql.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/routes/sql.js b/modules/control-center-web/src/main/js/routes/sql.js
new file mode 100644
index 0000000..ce4565d
--- /dev/null
+++ b/modules/control-center-web/src/main/js/routes/sql.js
@@ -0,0 +1,24 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var router = require('express').Router();
+var db = require('../db');
+router.get('/', function(req, res) {
+    res.render('sql/sql');
+});
+
+module.exports = router;

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/control-center-web/src/main/js/routes/summary.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/routes/summary.js b/modules/control-center-web/src/main/js/routes/summary.js
new file mode 100644
index 0000000..9f8df2a
--- /dev/null
+++ b/modules/control-center-web/src/main/js/routes/summary.js
@@ -0,0 +1,108 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var db = require('../db');
+
+var router = require('express').Router();
+
+var generatorXml = require('./generator/xml');
+var generatorJava = require('./generator/java');
+var generatorDocker = require('./generator/docker');
+
+/* GET summary page. */
+router.get('/', function (req, res) {
+    res.render('configuration/summary');
+});
+
+router.post('/generator', function (req, res) {
+    // Get cluster.
+    db.Cluster.findById(req.body._id).deepPopulate('caches caches.queryMetadata caches.storeMetadata').exec(function (err, cluster) {
+        if (err)
+            return res.status(500).send(err.message);
+
+        if (!cluster)
+            return res.sendStatus(404);
+
+        var clientCache = req.body.clientNearConfiguration;
+
+        if (clientCache)
+            return res.send({
+                xmlClient: generatorXml.generateClusterConfiguration(cluster, clientCache),
+                javaClient: generatorJava.generateClusterConfiguration(cluster, req.body.javaClass, clientCache)
+            });
+
+        return res.send({
+            xmlServer: generatorXml.generateClusterConfiguration(cluster),
+            javaSnippetServer: generatorJava.generateClusterConfiguration(cluster, false),
+            javaClassServer: generatorJava.generateClusterConfiguration(cluster, true),
+            docker: generatorDocker.generateClusterConfiguration(cluster, '%OS%')
+        });
+    });
+});
+
+router.post('/download', function (req, res) {
+    // Get cluster.
+    db.Cluster.findById(req.body._id).populate('caches').exec(function (err, cluster) {
+        if (err)
+            return res.status(500).send(err.message);
+
+        if (!cluster)
+            return res.sendStatus(404);
+
+        var clientNearConfiguration = req.body.clientNearConfiguration;
+
+        var archiver = require('archiver');
+
+        // Creating archive.
+        var zip = archiver('zip');
+
+        zip.on('error', function (err) {
+            res.status(500).send({error: err.message});
+        });
+
+        // On stream closed we can end the request.
+        res.on('close', function () {
+            return res.status(200).send('OK').end();
+        });
+
+        // Set the archive name.
+        res.attachment(cluster.name + (clientNearConfiguration ? '-client' : '') + '-configuration.zip');
+
+        var generatorCommon = require('./generator/common');
+
+        // Send the file to the page output.
+        zip.pipe(res);
+
+        var javaClass = req.body.javaClass;
+
+        if (!clientNearConfiguration) {
+            zip.append(generatorDocker.generateClusterConfiguration(cluster, req.body.os), {name: "Dockerfile"});
+
+            var props = generatorCommon.generateProperties(cluster);
+
+            if (props)
+                zip.append(props, {name: "secret.properties"});
+        }
+
+        zip.append(generatorXml.generateClusterConfiguration(cluster, clientNearConfiguration), {name: cluster.name + ".xml"})
+            .append(generatorJava.generateClusterConfiguration(cluster, javaClass, clientNearConfiguration),
+                {name: javaClass ? 'ConfigurationFactory.java' : cluster.name + '.snipplet.java'})
+            .finalize();
+    });
+});
+
+module.exports = router;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/control-center-web/src/main/js/views/configuration/caches.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/views/configuration/caches.jade b/modules/control-center-web/src/main/js/views/configuration/caches.jade
new file mode 100644
index 0000000..15d8f40
--- /dev/null
+++ b/modules/control-center-web/src/main/js/views/configuration/caches.jade
@@ -0,0 +1,74 @@
+//-
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+
+extends sidebar
+
+append scripts
+    script(src='/caches-controller.js')
+
+include ../includes/controls
+
+block content
+    .docs-header
+        h1 Create and Configure Ignite Caches
+        hr
+    .docs-body(ng-controller='cachesController')
+        +block-callout('{{screenTip.workflowTitle}}', 'joinTip(screenTip.workflowContent)', '{{screenTip.whatsNextTitle}}', 'joinTip(screenTip.whatsNextContent)')
+        div(ng-hide='caches.length == 0')
+            .padding-dflt
+                lable.labelHeader Caches:
+                table.links(st-table='caches')
+                    tbody
+                        tr(ng-repeat='row in caches track by row._id')
+                            td.col-sm-6(ng-class='{active: row._id == selectedItem._id}')
+                                a(event-focus='click' event-focus-id='defaultFocusId' ng-click='selectItem(row)') {{$index + 1}}) {{row.name}}, {{row.mode | displayValue:modes:'Cache mode not set'}}, {{row.atomicityMode | displayValue:atomicities:'Cache atomicity not set'}}
+        .padding-top-dflt
+            button.btn.btn-primary(event-focus='click' event-focus-id='defaultFocusId' ng-click='createItem()') Add cache
+        hr
+        form.form-horizontal(name='inputForm' ng-if='backupItem' novalidate)
+            div(bs-collapse data-start-collapsed='false')
+                .panel.panel-default
+                    .panel-heading
+                        h3
+                            a(bs-collapse-toggle) General
+                    .panel-collapse(bs-collapse-target)
+                        .panel-body
+                            .settings-row(ng-repeat='field in general')
+                                +form-row(['col-sm-3'], ['col-sm-3'])
+            .panel-group(bs-collapse data-allow-multiple='true')
+                div(bs-collapse data-start-collapsed='true')
+                    .panel-title(ng-show='expanded')
+                        h3
+                            a(bs-collapse-toggle='0' ng-click='expanded = !expanded;') {{expanded ? 'Hide advanced settings...' : 'Show advanced settings...'}}
+                    .panel-collapse(bs-collapse-target)
+                        .span(bs-collapse data-start-collapsed='true' data-allow-multiple='true')
+                            .panel.panel-default(ng-repeat='group in advanced')
+                                .panel-heading
+                                    h3
+                                        a(bs-collapse-toggle) {{group.label}}
+                                        i.tipLabel.fa.fa-question-circle(ng-if='group.tip' bs-tooltip='joinTip(group.tip)' type='button')
+                                        i.tipLabel.fa.fa-question-circle.blank(ng-if='!group.tip')
+                                .panel-collapse(bs-collapse-target)
+                                    .panel-body
+                                        .settings-row(ng-repeat='field in group.fields')
+                                            +form-row
+                    .panel-title
+                        h3
+                            a(bs-collapse-toggle='0' ng-click='expanded = !expanded;') {{expanded ? 'Hide advanced settings...' : 'Show advanced settings...'}}
+            div
+                button.btn.btn-primary(ng-disabled='inputForm.$invalid' ng-click='saveItem()') Save
+                button.btn.btn-primary(ng-show='backupItem._id' ng-disabled='inputForm.$invalid' ng-click='saveItemAs()') Copy
+                button.btn.btn-primary.btn-second(ng-show='backupItem._id' ng-click='removeItem()') Remove

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/control-center-web/src/main/js/views/configuration/clusters.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/views/configuration/clusters.jade b/modules/control-center-web/src/main/js/views/configuration/clusters.jade
new file mode 100644
index 0000000..239a31f
--- /dev/null
+++ b/modules/control-center-web/src/main/js/views/configuration/clusters.jade
@@ -0,0 +1,77 @@
+//-
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+
+extends sidebar
+
+append scripts
+    script(src='/clusters-controller.js')
+
+include ../includes/controls
+
+block content
+    .docs-header
+        h1 Create and Configure Ignite Clusters
+        hr
+    .docs-body(ng-controller='clustersController')
+        +block-callout('{{screenTip.workflowTitle}}', 'joinTip(screenTip.workflowContent)', '{{screenTip.whatsNextTitle}}', 'joinTip(screenTip.whatsNextContent)')
+        div(ng-hide='clusters.length == 0')
+            .padding-dflt
+                lable.labelHeader Clusters:
+                table.links(st-table='clusters')
+                    tbody
+                        tr(ng-repeat='row in clusters track by row._id')
+                            td.col-sm-6(ng-class='{active: row._id == selectedItem._id}')
+                                a(event-focus='click' event-focus-id='defaultFocusId' ng-click='selectItem(row)') {{$index + 1}}) {{row.name}}, {{row.discovery.kind | displayValue:discoveries:'Discovery not set'}}
+        .padding-top-dflt
+            button.btn.btn-primary(event-focus='click' event-focus-id='defaultFocusId' ng-click='createItem()') &nbspAdd cluster
+            label(style='margin-left: 10px; margin-right: 10px') Use template:
+            button.btn.btn-default.base-control(ng-init='create.template = templates[0].value' ng-model='create.template' data-template='/select' data-placeholder='Choose cluster template' bs-options='item.value as item.label for item in templates' bs-select)
+            i.tiplabel.fa.fa-question-circle(bs-tooltip data-title='{{joinTip(templateTip)}}' type='button')
+        hr
+        form.form-horizontal(name='inputForm' ng-if='backupItem' novalidate)
+            div(bs-collapse data-start-collapsed='false')
+                .panel.panel-default
+                    .panel-heading
+                        h3
+                            a(bs-collapse-toggle) General
+                    .panel-collapse(bs-collapse-target)
+                        .panel-body
+                            .settings-row(ng-repeat='field in general')
+                                +form-row
+            .panel-group(bs-collapse data-allow-multiple='true')
+                div(bs-collapse data-start-collapsed='true')
+                    .panel-title(ng-show='expanded')
+                        h3
+                            a(bs-collapse-toggle='0' ng-click='expanded = !expanded;') {{expanded ? 'Hide advanced settings...' : 'Show advanced settings...'}}
+                    .panel-collapse(bs-collapse-target)
+                        .span(bs-collapse data-start-collapsed='true' data-allow-multiple='true')
+                            .panel.panel-default(ng-repeat='group in advanced')
+                                .panel-heading
+                                    h3
+                                        a(bs-collapse-toggle) {{group.label}}
+                                        i.tipLabel.fa.fa-question-circle(ng-if='group.tip' bs-tooltip='joinTip(group.tip)' type='button')
+                                        i.tipLabel.fa.fa-question-circle.blank(ng-if='!group.tip')
+                                .panel-collapse(bs-collapse-target)
+                                    .panel-body
+                                        .settings-row(ng-repeat='field in group.fields')
+                                            +form-row
+                    .panel-title
+                        h3
+                            a(bs-collapse-toggle='0' ng-click='expanded = !expanded;') {{expanded ? 'Hide advanced settings...' : 'Show advanced settings...'}}
+            div
+                button.btn.btn-primary(ng-disabled='inputForm.$invalid' ng-click='saveItem()') Save
+                button.btn.btn-primary(ng-show='backupItem._id' ng-disabled='inputForm.$invalid' ng-click='saveItemAs()') Copy
+                button.btn.btn-primary(ng-show='backupItem._id' ng-click='removeItem()') Remove
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/control-center-web/src/main/js/views/configuration/metadata.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/views/configuration/metadata.jade b/modules/control-center-web/src/main/js/views/configuration/metadata.jade
new file mode 100644
index 0000000..e0cc76f
--- /dev/null
+++ b/modules/control-center-web/src/main/js/views/configuration/metadata.jade
@@ -0,0 +1,121 @@
+//-
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+
+extends sidebar
+
+append scripts
+    script(src='/metadata-controller.js')
+
+include ../includes/controls
+
+block content
+    .docs-header
+        h1 Create and Configure Cache Type Metadata
+        hr
+    .docs-body(ng-controller='metadataController')
+        +block-callout('{{screenTip.workflowTitle}}', 'joinTip(screenTip.workflowContent)', '{{screenTip.whatsNextTitle}}', 'joinTip(screenTip.whatsNextContent)')
+        div(ng-hide='metadatas.length == 0')
+            .padding-dflt
+                lable.labelHeader Types metadata:
+                table.links(st-table='metadatas')
+                    tbody
+                        tr(ng-repeat='row in metadatas track by row._id')
+                            td.col-sm-6(ng-class='{active: row._id == selectedItem._id}')
+                                a(event-focus='click' event-focus-id='defaultFocusId' ng-click='selectItem(row)') {{$index + 1}}) {{row.name}}
+        .padding-top-dflt
+            button.btn.btn-primary(event-focus='click' event-focus-id='defaultFocusId' ng-click='panels.activePanel = [0]; createItem()') &nbspAdd metadata
+            label(style='margin-left: 6px; margin-right: 10px') For:
+            button.btn.btn-default(ng-model='template' data-template='/select' data-placeholder='Choose metadata type' bs-options='item.value as item.label for item in templates' bs-select)
+            i.tiplabel.fa.fa-question-circle(bs-tooltip data-title='{{joinTip(templateTip)}}' type='button')
+        hr
+        .panel-group(bs-collapse ng-model='panels.activePanel' data-allow-multiple='false')
+            .panel.panel-default(ng-show='selectedItem || backupItem')
+                .panel-heading
+                    h3
+                        a(bs-collapse-toggle) Manual
+                .panel-collapse(role='tabpanel' bs-collapse-target)
+                    .panel-body
+                        form.form-horizontal(name='manualForm' ng-if='backupItem' novalidate)
+                            .settings-row(ng-repeat='field in metadataManual')
+                                +form-row
+                            button.btn.btn-primary(ng-disabled='manualForm.$invalid' ng-click='saveItem()') Save
+                            button.btn.btn-primary(ng-show='backupItem._id' ng-disabled='inputForm.$invalid' ng-click='saveItemAs()') Copy
+                            button.btn.btn-primary.btn-second(ng-show='backupItem._id' ng-click='removeItem()') Remove
+            .panel.panel-default
+                .panel-heading
+                    h3
+                        a(bs-collapse-toggle) Load from database
+                .panel-collapse(bs-collapse-target)
+                    .panel-body
+                        form.form-horizontal(name='dbForm' novalidate)
+                            .settings-row(ng-repeat='field in metadataDb')
+                                +form-row
+                        div(ng-hide='data.tables.length == 0')
+                            table.table-bordered.table-condensed.links-edit-small-padding.col-sm-12(st-table='data.tables')
+                                thead
+                                    tr
+                                        th.col-sm-3 Schema/Table
+                                        th Key class
+                                        th Value class
+                                tbody
+                                    tr(ng-repeat='row in data.tables')
+                                        td(colspan='{{row.tableName ? 1 : 3}}')
+                                            div.checkbox(ng-if='!row.tableName')
+                                                label(ng-click='selectSchema($index)')
+                                                    input(type='checkbox' ng-checked='row.use')
+                                                    | {{row.schemaName}}
+                                            div.checkbox(ng-if='row.tableName')
+                                                label(style='padding-left: 30px' ng-click='selectTable($index)')
+                                                    input(type='checkbox' ng-checked = 'row.use')
+                                                    | {{row.tableName}}
+                                        td(ng-if='row.tableName')
+                                            a(ng-show='data.curTableIdx != $index' ng-click='selectTable($index)') {{row.keyClass}}
+                                            input.form-control(type='text' ng-show='data.curTableIdx == $index' ng-model='data.curKeyClass' placeholder='Key class full name')
+                                        td(ng-if='row.tableName')
+                                            a(ng-show='data.curTableIdx != $index' ng-click='selectTable($index)') {{row.valueClass}}
+                                            input.form-control(type='text' ng-show='data.curTableIdx == $index' ng-model='data.curValueClass' placeholder='Value class full name')
+                        //div(ng-hide='data.curTableIdx < 0')
+                        //    table.table-bordered.table-condensed.links-edit-small-padding.col-sm-12(st-table='data.tables[data.curTableIdx].fields')
+                        //        thead
+                        //            tr
+                        //                th(style='width:45px') Use
+                        //                th(style='width:45px') Key
+                        //                th(style='width:45px') Ak
+                        //                th DB Name
+                        //                th DB Type
+                        //                th Java Name
+                        //                th Java Type
+                        //        tbody
+                        //            tr(ng-repeat='row in data.tables[data.curTableIdx].fields')
+                        //                td
+                        //                    +dbcheck('row.use')
+                        //                td
+                        //                    +dbcheck('row.key')
+                        //                td
+                        //                    +dbcheck('row.ak')
+                        //                td
+                        //                    label {{row.databaseName}}
+                        //                td
+                        //                    label {{row.databaseType}}
+                        //                td
+                        //                    a(ng-show='data.curFieldIdx != $index' ng-click='selectField($index)') {{row.javaName}}
+                        //                    input.form-control(type='text' ng-show='data.curFieldIdx == $index' ng-model='data.curJavaName' placeholder='Field Java name')
+                        //                td
+                        //                    a(ng-show='data.curFieldIdx != $index' ng-click='selectField($index)') {{row.javaType}}
+                        //                    input.form-control(type='text' ng-show='data.curFieldIdx == $index' ng-model='data.curJavaType' placeholder='Field Java type')
+                        button.btn.btn-primary(ng-disabled='dbForm.$invalid' ng-click='saveItem()') Save
+                        button.btn.btn-primary.btn-second(ng-show='backupItem._id' ng-click='removeItem()') Remove
+                        button.btn.btn-primary.btn-second(ng-click='reloadMetadata()') Reload
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/control-center-web/src/main/js/views/configuration/sidebar.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/views/configuration/sidebar.jade b/modules/control-center-web/src/main/js/views/configuration/sidebar.jade
new file mode 100644
index 0000000..7289f3e
--- /dev/null
+++ b/modules/control-center-web/src/main/js/views/configuration/sidebar.jade
@@ -0,0 +1,39 @@
+//-
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+
+extends ../templates/layout
+
+mixin sidebar-item(ref, num, txt)
+    li
+        a(ng-class='{active: isActive("#{ref}")}' href='#{ref}')
+            span.fa-stack
+                i.fa.fa-circle-thin.fa-stack-2x
+                i.fa.fa-stack-1x #{num}
+            | #{txt}
+
+block container
+    .row
+        .col-sm-2.border-right.section-left.greedy
+            .sidebar-nav(bs-affix)
+                ul.menu(ng-controller='activeLink')
+                    +sidebar-item('/configuration/clusters', 1, 'Clusters')
+                    +sidebar-item('/configuration/metadata', 2, 'Metadata')
+                    +sidebar-item('/configuration/caches', 3, 'Caches')
+                    +sidebar-item('/configuration/summary', 4, 'Summary')
+
+        .col-sm-10.border-left.section-right
+            .docs-content
+                block content
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/control-center-web/src/main/js/views/configuration/summary.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/views/configuration/summary.jade b/modules/control-center-web/src/main/js/views/configuration/summary.jade
new file mode 100644
index 0000000..ba63343
--- /dev/null
+++ b/modules/control-center-web/src/main/js/views/configuration/summary.jade
@@ -0,0 +1,113 @@
+//-
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+
+extends sidebar
+
+append scripts
+    script(src='/summary-controller.js')
+
+    script(src='//cdn.jsdelivr.net/angularjs/1.3.15/angular-animate.min.js')
+    script(src='//cdn.jsdelivr.net/angularjs/1.3.15/angular-sanitize.min.js')
+
+    script(src='//cdnjs.cloudflare.com/ajax/libs/ace/1.2.0/theme-chrome.js')
+    script(src='//cdnjs.cloudflare.com/ajax/libs/ace/1.2.0/mode-xml.js')
+    script(src='//cdnjs.cloudflare.com/ajax/libs/ace/1.2.0/mode-java.js')
+    script(src='//cdnjs.cloudflare.com/ajax/libs/ace/1.2.0/mode-dockerfile.js')
+
+append css
+
+include ../includes/controls
+
+mixin hard-link(ref, txt)
+    a(style='color:#ec1c24' href=ref target='_blank') #{txt}
+
+block content
+    .docs-header
+        h1 Configurations Summary
+        hr
+    .docs-body(ng-controller='summaryController')
+        +block-callout('{{screenTip.workflowTitle}}', 'joinTip(screenTip.workflowContent)', '{{screenTip.whatsNextTitle}}', 'joinTip(screenTip.whatsNextContent)')
+        .padding-dflt(ng-if='clusters.length == 0')
+            | No cluster configured. You can&nbsp;
+            a(href='clusters') configure
+            | &nbsp;it.
+        .padding-dflt(ng-if='clusters.length > 0')
+            lable.labelHeader Clusters:
+            table.links(st-table='clusters')
+                tbody
+                    tr(ng-repeat='row in clusters track by row._id')
+                        td.col-sm-6(ng-class='{active: row._id == selectedItem._id}')
+                            a(ng-click='selectItem(row)') {{$index + 1}}) {{row.name}}
+        div(ng-show='selectedItem' role='tab' method='post' action='summary/download')
+            .padding-dflt(bs-collapse data-start-collapsed='false')
+                .panel.panel-default
+                    form.panel-heading(role='tab' method='post' action='summary/download')
+                        input(type='hidden' name='_id' value='{{selectedItem._id}}')
+                        input(type='hidden' name='os' value='{{os}}')
+                        input(type='hidden' name='javaClass' value='{{javaClassServer}}')
+                        h3
+                            a(bs-collapse-toggle) Server
+                            button.btn.btn-primary.pull-right(type='submit' style='margin-top: -5px') Download
+                    .panel-collapse(role='tabpanel' bs-collapse-target)
+                        div(ng-show='selectedItem' bs-tabs style='margin-top: 0.65em')
+                            div(title='<img src="/images/xml.png" width="16px" height="16px"/> XML' bs-pane)
+                                div(ui-ace='{ onLoad: aceInit, mode: "xml" }' ng-model='xmlServer')
+                            div(title='<img src="/images/java.png" width="16px" height="16px"/> Java' bs-pane)
+                                .details-row
+                                    .col-sm-1
+                                        label Generate:
+                                    .col-sm-3
+                                        button.form-control(type='button' ng-model='configServer.javaClassServer'  bs-select data-placeholder='{{detail.placeholder}}' bs-options='item.value as item.label for item in javaClassItems' data-sort='false')
+                                div(ui-ace='{ onLoad: aceInit, mode: "java" }' ng-model='javaServer')
+                            div(title='<img src="/images/docker.png" width="16px" height="16px"/> Dockerfile' bs-pane)
+                                .details-row
+                                    p
+                                        +hard-link('https://docs.docker.com/reference/builder', 'Docker')
+                                        | &nbsp;file is a text file with instructions to create Docker image.<br/>
+                                        | To build image you have to store following Docker file with your Ignite XML configuration to the same directory.<br>
+                                        | Also you could use predefined&nbsp;
+                                        +hard-link('https://ignite.incubator.apache.org/download.html#docker', 'Apache Ignite docker image')
+                                        | . For more information about using Ignite with Docker please read&nbsp;
+                                        +hard-link('http://apacheignite.readme.io/docs/docker-deployment', 'documentation')
+                                        |.
+                                    .col-sm-2
+                                        label(for='os') Operation System:
+                                    .col-sm-4
+                                        input#os.form-control(type='text' ng-model='configServer.os' placeholder='debian:8' data-min-length='0' data-html='1' data-auto-select='true' data-animation='am-flip-x' bs-typeahead bs-options='os for os in oss')
+                                div(ui-ace='{ onLoad: aceInit, mode: "dockerfile" }' ng-model='dockerServer')
+            .padding-dflt(bs-collapse data-start-collapsed='false')
+                .panel.panel-default
+                    form.panel-heading(role='tab' method='post' action='summary/download')
+                        input(type='hidden' name='_id' value='{{selectedItem._id}}')
+                        input(type='hidden' name='javaClass' value='{{javaClassClient}}')
+                        input(type='hidden' name='clientNearConfiguration' value='{{backupItem}}')
+                        h3
+                            a(bs-collapse-toggle) Client
+                            button.btn.btn-primary.pull-right(type='submit' style='margin-top: -5px') Download
+                    .panel-collapse(role='tabpanel' bs-collapse-target)
+                        div(ng-show='selectedItem')
+                            .details-row(ng-repeat='field in clientFields')
+                                +form-row-custom(['col-sm-3'], ['col-sm-3'])
+                            div(bs-tabs style='margin-top: 0.65em')
+                                div(title='<img src="/images/xml.png" width="16px" height="16px"/> XML' bs-pane)
+                                    div(ui-ace='{ onLoad: aceInit, mode: "xml" }' ng-model='xmlClient')
+                                div(title='<img src="/images/java.png" width="16px" height="16px"/> Java' bs-pane)
+                                    .details-row
+                                        .col-sm-1
+                                            label Generate:
+                                        .col-sm-4
+                                            button.form-control(type='button' ng-model='backupItem.javaClassClient' bs-select data-placeholder='{{detail.placeholder}}' bs-options='item.value as item.label for item in javaClassItems' data-sort='false')
+                                    div(ui-ace='{ onLoad: aceInit, mode: "java" }' ng-model='javaClient')

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/control-center-web/src/main/js/views/error.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/views/error.jade b/modules/control-center-web/src/main/js/views/error.jade
new file mode 100644
index 0000000..b458fb7
--- /dev/null
+++ b/modules/control-center-web/src/main/js/views/error.jade
@@ -0,0 +1,22 @@
+//-
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+
+extends templates/layout
+
+block container
+  h1= message
+  h2= error.status
+  pre #{error.stack}


[25/41] incubator-ignite git commit: IGNITE-843: WIP java code generation.

Posted by an...@apache.org.
IGNITE-843: WIP java code generation.


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

Branch: refs/heads/ignite-1121
Commit: cb2ecb53b3332fe90b1bd3d39e7b226ed7b4114f
Parents: 2e4daaa
Author: AKuznetsov <ak...@gridgain.com>
Authored: Wed Jul 29 10:11:02 2015 +0700
Committer: AKuznetsov <ak...@gridgain.com>
Committed: Wed Jul 29 10:11:02 2015 +0700

----------------------------------------------------------------------
 .../src/main/js/routes/generator/common.js      |  12 -
 .../src/main/js/routes/generator/java.js        | 266 +++++++++++++++----
 .../src/main/js/routes/generator/xml.js         |  34 ++-
 3 files changed, 230 insertions(+), 82 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/cb2ecb53/modules/web-control-center/src/main/js/routes/generator/common.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/routes/generator/common.js b/modules/web-control-center/src/main/js/routes/generator/common.js
index a300bb5..44ddf31 100644
--- a/modules/web-control-center/src/main/js/routes/generator/common.js
+++ b/modules/web-control-center/src/main/js/routes/generator/common.js
@@ -274,18 +274,6 @@ exports.hasProperty = function (obj, props) {
 };
 
 /**
- * Convert some name to valid java name.
- *
- * @param name to convert.
- * @returns {string} Valid java name.
- */
-exports.toJavaName = function (name) {
-    var javaName = name.replace(/[^A-Za-z_0-9]+/, '_');
-
-    return javaName.charAt(0).toLocaleUpperCase() + javaName.slice(1);
-};
-
-/**
  * Generate properties file with properties stubs for stores data sources.
  *
  * @param cluster Configuration to process.

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/cb2ecb53/modules/web-control-center/src/main/js/routes/generator/java.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/routes/generator/java.js b/modules/web-control-center/src/main/js/routes/generator/java.js
index 31cd2ac..41b9bb8 100644
--- a/modules/web-control-center/src/main/js/routes/generator/java.js
+++ b/modules/web-control-center/src/main/js/routes/generator/java.js
@@ -19,6 +19,18 @@ var _ = require('lodash');
 
 var generatorUtils = require("./common");
 
+/**
+ * Convert some name to valid java name.
+ *
+ * @param name to convert.
+ * @returns {string} Valid java name.
+ */
+function toJavaName(name) {
+    var javaName = name.replace(/[^A-Za-z_0-9]+/, '_');
+
+    return javaName.charAt(0).toLocaleUpperCase() + javaName.slice(1);
+}
+
 exports.generateClusterConfiguration = function(cluster, javaClass, clientNearConfiguration) {
     var res = generatorUtils.builder();
 
@@ -156,11 +168,11 @@ exports.generateClusterConfiguration = function(cluster, javaClass, clientNearCo
 
             var cache = cluster.caches[i];
 
-            var cacheName = 'cache' + generatorUtils.toJavaName(cache.name);
+            var cacheName = 'cache' + toJavaName(cache.name);
 
             names.push(cacheName);
 
-            generateCacheConfiguration(cache, cacheName, res);
+            generateCacheConfiguration(res, cache, cacheName);
 
             res.needEmptyLine = true;
         }
@@ -320,17 +332,130 @@ function createEvictionPolicy(res, evictionPolicy, varName, propertyName) {
     }
 }
 
-exports.generateCacheConfiguration = generateCacheConfiguration;
+function addCacheTypeMetadataDatabaseFields(res, meta, varName, fieldsProperty) {
+    var fields = meta[fieldsProperty];
+
+    if (fields && fields.length > 0) {
+        res.line('addCacheTypeMetadataDatabaseFields for ' + varName);
+        //res.startBlock('<property name="' + fieldsProperty + '">');
+        //
+        //res.startBlock('<list>');
+        //
+        //_.forEach(fields, function (field) {
+        //    res.startBlock('<bean class="org.apache.ignite.cache.CacheTypeFieldMetadata">');
+        //
+        //    addProperty(res, field, 'databaseName');
+        //
+        //    res.startBlock('<property name="databaseType">');
+        //    res.line('<util:constant static-field="java.sql.Types.' + field.databaseType + '"/>');
+        //    res.endBlock('</property>');
+        //
+        //    addProperty(res, field, 'javaName');
+        //
+        //    addElement(res, 'property', 'name', 'javaType', 'value', generatorUtils.javaBuildInClass(field.javaType));
+        //
+        //    res.endBlock('</bean>');
+        //});
+        //
+        //res.endBlock('</list>');
+        //res.endBlock('</property>');
+    }
+}
+
+function addCacheTypeMetadataQueryFields(res, meta, varName, fieldsProperty) {
+    var fields = meta[fieldsProperty];
+
+    if (fields && fields.length > 0) {
+        res.line('addCacheTypeMetadataQueryFields for ' + varName);
+        //res.startBlock('<property name="' + fieldsProperty + '">');
+        //
+        //res.startBlock('<map>');
+        //
+        //_.forEach(fields, function (field) {
+        //    addElement(res, 'entry', 'key', field.name, 'value', generatorUtils.javaBuildInClass(field.className));
+        //});
+        //
+        //res.endBlock('</map>');
+        //
+        //res.endBlock('</property>');
+    }
+}
+
+function addCacheTypeMetadataGroups(res, meta, varName) {
+    var groups = meta.groups;
+
+    if (groups && groups.length > 0) {
+        res.line('addCacheTypeMetadataGroups for ' + varName);
+        //res.startBlock('<property name="groups">');
+        //res.startBlock('<map>');
+        //
+        //_.forEach(groups, function (group) {
+        //    var fields = group.fields;
+        //
+        //    if (fields && fields.length > 0) {
+        //        res.startBlock('<entry key="' + group.name + '">');
+        //        res.startBlock('<map>');
+        //
+        //        _.forEach(fields, function (field) {
+        //            res.startBlock('<entry key="' + field.name + '">');
+        //
+        //            res.startBlock('<bean class="org.apache.ignite.lang.IgniteBiTuple">');
+        //            res.line('<constructor-arg value="' + generatorUtils.javaBuildInClass(field.className) + '"/>');
+        //            res.line('<constructor-arg value="' + field.direction + '"/>');
+        //            res.endBlock('</bean>');
+        //
+        //            res.endBlock('</entry>');
+        //        });
+        //
+        //        res.endBlock('</map>');
+        //        res.endBlock('</entry>');
+        //    }
+        //});
+        //
+        //res.endBlock('</map>');
+        //res.endBlock('</property>');
+    }
+}
+
+function generateCacheTypeMetadataConfiguration(res, meta, varCacheTypeMetadata) {
+    if (!res)
+        res = generatorUtils.builder();
+
+    res.importClass('org.apache.ignite.cache.CacheTypeMetadata');
+
+    var varType = varCacheTypeMetadata + 'Item';
+
+    addProperty(res, meta, varType, 'databaseSchema');
+    addProperty(res, meta, varType, 'databaseTable');
+
+    addProperty(res, meta, varType, 'keyType');
+    addProperty(res, meta, varType, 'valueType');
+
+    addCacheTypeMetadataDatabaseFields(res, meta, varType, 'keyFields');
+    addCacheTypeMetadataDatabaseFields(res, meta, varType, 'valueFields');
+
+    addCacheTypeMetadataQueryFields(res, meta, varType, 'queryFields');
+    addCacheTypeMetadataQueryFields(res, meta, varType, 'ascendingFields');
+    addCacheTypeMetadataQueryFields(res, meta, varType, 'descendingFields');
+
+    addListProperty(res, meta, varType, 'textFields');
+
+    addCacheTypeMetadataGroups(res, varType, meta);
+
+    res.line(varCacheTypeMetadata + '.add(' + varType + ')');
+
+    return res;
+}
 
 /**
  * Generate java code for cache configuration.
  *
- * @param cacheCfg Cache config.
+ * @param cache Cache config.
  * @param varName Variable name.
  * @param res Result builder.
  * @returns {*} Append generated java code to builder and return it.
  */
-function generateCacheConfiguration(cacheCfg, varName, res) {
+function generateCacheConfiguration(res, cache, varName) {
     if (!res)
         res = generatorUtils.builder();
 
@@ -344,55 +469,55 @@ function generateCacheConfiguration(cacheCfg, varName, res) {
 
     res.needEmptyLine = true;
 
-    addProperty(res, cacheCfg, varName, 'name');
+    addProperty(res, cache, varName, 'name');
     
-    addProperty(res, cacheCfg, varName, 'mode', 'CacheMode', 'cacheMode');
+    addProperty(res, cache, varName, 'mode', 'CacheMode', 'cacheMode');
 
-    addProperty(res, cacheCfg, varName, 'atomicityMode', 'CacheAtomicityMode');
-    addProperty(res, cacheCfg, varName, 'backups');
-    addProperty(res, cacheCfg, varName, 'startSize');
-    addProperty(res, cacheCfg, varName, 'readFromBackup');
+    addProperty(res, cache, varName, 'atomicityMode', 'CacheAtomicityMode');
+    addProperty(res, cache, varName, 'backups');
+    addProperty(res, cache, varName, 'startSize');
+    addProperty(res, cache, varName, 'readFromBackup');
 
     res.needEmptyLine = true;
     
-    addProperty(res, cacheCfg, varName, 'memoryMode', 'CacheMemoryMode');
-    addProperty(res, cacheCfg, varName, 'offHeapMaxMemory');
-    addProperty(res, cacheCfg, varName, 'swapEnabled');
-    addProperty(res, cacheCfg, varName, 'copyOnRead');
+    addProperty(res, cache, varName, 'memoryMode', 'CacheMemoryMode');
+    addProperty(res, cache, varName, 'offHeapMaxMemory');
+    addProperty(res, cache, varName, 'swapEnabled');
+    addProperty(res, cache, varName, 'copyOnRead');
 
     res.needEmptyLine = true;
 
-    createEvictionPolicy(res, cacheCfg.evictionPolicy, varName, 'evictionPolicy');
+    createEvictionPolicy(res, cache.evictionPolicy, varName, 'evictionPolicy');
 
-    if (cacheCfg.nearCacheEnabled) {
+    if (cache.nearCacheEnabled) {
         res.needEmptyLine = true;
 
         res.importClass('org.apache.ignite.configuration.NearCacheConfiguration');
 
-        addBeanWithProperties(res, cacheCfg.nearConfiguration, varName, 'nearConfiguration', 'nearConfiguration',
+        addBeanWithProperties(res, cache.nearConfiguration, varName, 'nearConfiguration', 'nearConfiguration',
             'NearCacheConfiguration', {nearStartSize: null}, true);
 
-        if (cacheCfg.nearConfiguration && cacheCfg.nearConfiguration.nearEvictionPolicy && cacheCfg.nearConfiguration.nearEvictionPolicy.kind) {
-            createEvictionPolicy(res, cacheCfg.nearConfiguration.nearEvictionPolicy, 'nearConfiguration', 'nearEvictionPolicy');
+        if (cache.nearConfiguration && cache.nearConfiguration.nearEvictionPolicy && cache.nearConfiguration.nearEvictionPolicy.kind) {
+            createEvictionPolicy(res, cache.nearConfiguration.nearEvictionPolicy, 'nearConfiguration', 'nearEvictionPolicy');
         }
     }
 
     res.needEmptyLine = true;
     
-    addProperty(res, cacheCfg, varName, 'sqlEscapeAll');
-    addProperty(res, cacheCfg, varName, 'sqlOnheapRowCacheSize');
-    addProperty(res, cacheCfg, varName, 'longQueryWarningTimeout');
+    addProperty(res, cache, varName, 'sqlEscapeAll');
+    addProperty(res, cache, varName, 'sqlOnheapRowCacheSize');
+    addProperty(res, cache, varName, 'longQueryWarningTimeout');
     
-    if (cacheCfg.indexedTypes && cacheCfg.indexedTypes.length > 0) {
+    if (cache.indexedTypes && cache.indexedTypes.length > 0) {
         res.emptyLineIfNeeded();
         
         res.append(varName + '.setIndexedTypes(');
         
-        for (var i = 0; i < cacheCfg.indexedTypes.length; i++) {
+        for (var i = 0; i < cache.indexedTypes.length; i++) {
             if (i > 0)
                 res.append(', ');
 
-            var pair = cacheCfg.indexedTypes[i];
+            var pair = cache.indexedTypes[i];
             
             res.append(toJavaCode(pair.keyClass, 'class')).append(', ').append(toJavaCode(pair.valueClass, 'class'))
         }
@@ -400,25 +525,25 @@ function generateCacheConfiguration(cacheCfg, varName, res) {
         res.line(');');
     }
 
-    addMultiparamProperty(res, cacheCfg, varName, 'sqlFunctionClasses', 'class');
+    addMultiparamProperty(res, cache, varName, 'sqlFunctionClasses', 'class');
     
     res.needEmptyLine = true;
 
-    addProperty(res, cacheCfg, varName, 'rebalanceMode', 'CacheRebalanceMode');
-    addProperty(res, cacheCfg, varName, 'rebalanceThreadPoolSize');
-    addProperty(res, cacheCfg, varName, 'rebalanceBatchSize');
-    addProperty(res, cacheCfg, varName, 'rebalanceOrder');
-    addProperty(res, cacheCfg, varName, 'rebalanceDelay');
-    addProperty(res, cacheCfg, varName, 'rebalanceTimeout');
-    addProperty(res, cacheCfg, varName, 'rebalanceThrottle');
+    addProperty(res, cache, varName, 'rebalanceMode', 'CacheRebalanceMode');
+    addProperty(res, cache, varName, 'rebalanceThreadPoolSize');
+    addProperty(res, cache, varName, 'rebalanceBatchSize');
+    addProperty(res, cache, varName, 'rebalanceOrder');
+    addProperty(res, cache, varName, 'rebalanceDelay');
+    addProperty(res, cache, varName, 'rebalanceTimeout');
+    addProperty(res, cache, varName, 'rebalanceThrottle');
 
     res.needEmptyLine = true;
     
-    if (cacheCfg.cacheStoreFactory && cacheCfg.cacheStoreFactory.kind) {
-        var storeFactory = cacheCfg.cacheStoreFactory[cacheCfg.cacheStoreFactory.kind];
-        var data = generatorUtils.storeFactories[cacheCfg.cacheStoreFactory.kind];
+    if (cache.cacheStoreFactory && cache.cacheStoreFactory.kind) {
+        var storeFactory = cache.cacheStoreFactory[cache.cacheStoreFactory.kind];
+        var data = generatorUtils.storeFactories[cache.cacheStoreFactory.kind];
 
-        var sfVarName = 'storeFactory' + generatorUtils.toJavaName(cacheCfg.name);
+        var sfVarName = 'storeFactory' + toJavaName(cache.name);
         var dsVarName = 'none';
 
         if (storeFactory.dialect) {
@@ -448,32 +573,69 @@ function generateCacheConfiguration(cacheCfg, varName, res) {
 
     res.needEmptyLine = true;
 
-    addProperty(res, cacheCfg, varName, 'loadPreviousValue');
-    addProperty(res, cacheCfg, varName, 'readThrough');
-    addProperty(res, cacheCfg, varName, 'writeThrough');
+    addProperty(res, cache, varName, 'loadPreviousValue');
+    addProperty(res, cache, varName, 'readThrough');
+    addProperty(res, cache, varName, 'writeThrough');
 
     res.needEmptyLine = true;
     
-    addProperty(res, cacheCfg, varName, 'invalidate');
-    addProperty(res, cacheCfg, varName, 'defaultLockTimeout');
-    addProperty(res, cacheCfg, varName, 'transactionManagerLookupClassName');
+    addProperty(res, cache, varName, 'invalidate');
+    addProperty(res, cache, varName, 'defaultLockTimeout');
+    addProperty(res, cache, varName, 'transactionManagerLookupClassName');
     
     res.needEmptyLine = true;
     
-    addProperty(res, cacheCfg, varName, 'writeBehindEnabled');
-    addProperty(res, cacheCfg, varName, 'writeBehindBatchSize');
-    addProperty(res, cacheCfg, varName, 'writeBehindFlushSize');
-    addProperty(res, cacheCfg, varName, 'writeBehindFlushFrequency');
-    addProperty(res, cacheCfg, varName, 'writeBehindFlushThreadCount');
+    addProperty(res, cache, varName, 'writeBehindEnabled');
+    addProperty(res, cache, varName, 'writeBehindBatchSize');
+    addProperty(res, cache, varName, 'writeBehindFlushSize');
+    addProperty(res, cache, varName, 'writeBehindFlushFrequency');
+    addProperty(res, cache, varName, 'writeBehindFlushThreadCount');
     
     res.needEmptyLine = true;
 
-    addProperty(res, cacheCfg, varName, 'statisticsEnabled');
-    addProperty(res, cacheCfg, varName, 'managementEnabled');
+    addProperty(res, cache, varName, 'statisticsEnabled');
+    addProperty(res, cache, varName, 'managementEnabled');
+
+    res.needEmptyLine = true;
+
+    addProperty(res, cache, varName, 'maxConcurrentAsyncOperations');
 
     res.needEmptyLine = true;
 
-    addProperty(res, cacheCfg, varName, 'maxConcurrentAsyncOperations');
+    // Generate cache type metadata configs.
+    if ((cache.queryMetadata && cache.queryMetadata.length > 0) ||
+        (cache.storeMetadata && cache.storeMetadata.length > 0)) {
+        res.emptyLineIfNeeded();
+
+        var varCacheTypeMetadata = varName + 'TypeMetadata';
+
+        res.line('Collection ' + varCacheTypeMetadata + ' = new ArrayList();');
+        res.line();
+
+        var metaNames = [];
+
+        if (cache.queryMetadata && cache.queryMetadata.length > 0) {
+            _.forEach(cache.queryMetadata, function (meta) {
+                if (!_.contains(metaNames, meta.name)) {
+                    metaNames.push(meta.name);
+
+                    generateCacheTypeMetadataConfiguration(res, meta, varCacheTypeMetadata);
+                }
+            });
+        }
+
+        if (cache.storeMetadata && cache.storeMetadata.length > 0) {
+            _.forEach(cache.storeMetadata, function (meta) {
+                if (!_.contains(metaNames, meta.name)) {
+                    metaNames.push(meta.name);
+
+                    generateCacheTypeMetadataConfiguration(meta, res);
+                }
+            });
+        }
+
+        res.line(varName + '.setCacheTypeMetadata(' + varCacheTypeMetadata + ');');
+    }
     
     return res;
 }

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/cb2ecb53/modules/web-control-center/src/main/js/routes/generator/xml.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/routes/generator/xml.js b/modules/web-control-center/src/main/js/routes/generator/xml.js
index dbb6935..079f268 100644
--- a/modules/web-control-center/src/main/js/routes/generator/xml.js
+++ b/modules/web-control-center/src/main/js/routes/generator/xml.js
@@ -274,7 +274,7 @@ exports.generateClusterConfiguration = function(cluster, clientNearConfiguration
 
             var cache = cluster.caches[i];
 
-            generateCacheConfiguration(cache, res);
+            generateCacheConfiguration(res, cache);
         }
 
         res.endBlock('</list>');
@@ -419,35 +419,35 @@ function addCacheTypeMetadataGroups(res, meta) {
     }
 }
 
-function generateCacheTypeMetadataConfiguration(metaCfg, res) {
+function generateCacheTypeMetadataConfiguration(res, meta) {
     if (!res)
         res = generatorUtils.builder();
 
     res.startBlock('<bean class="org.apache.ignite.cache.CacheTypeMetadata">');
 
-    addProperty(res, metaCfg, 'databaseSchema');
-    addProperty(res, metaCfg, 'databaseTable');
+    addProperty(res, meta, 'databaseSchema');
+    addProperty(res, meta, 'databaseTable');
 
-    addProperty(res, metaCfg, 'keyType');
-    addProperty(res, metaCfg, 'valueType');
+    addProperty(res, meta, 'keyType');
+    addProperty(res, meta, 'valueType');
 
-    addCacheTypeMetadataDatabaseFields(res, metaCfg, 'keyFields');
-    addCacheTypeMetadataDatabaseFields(res, metaCfg, 'valueFields');
+    addCacheTypeMetadataDatabaseFields(res, meta, 'keyFields');
+    addCacheTypeMetadataDatabaseFields(res, meta, 'valueFields');
 
-    addCacheTypeMetadataQueryFields(res, metaCfg, 'queryFields');
-    addCacheTypeMetadataQueryFields(res, metaCfg, 'ascendingFields');
-    addCacheTypeMetadataQueryFields(res, metaCfg, 'descendingFields');
+    addCacheTypeMetadataQueryFields(res, meta, 'queryFields');
+    addCacheTypeMetadataQueryFields(res, meta, 'ascendingFields');
+    addCacheTypeMetadataQueryFields(res, meta, 'descendingFields');
 
-    addListProperty(res, metaCfg, 'textFields');
+    addListProperty(res, meta, 'textFields');
 
-    addCacheTypeMetadataGroups(res, metaCfg);
+    addCacheTypeMetadataGroups(res, meta);
 
     res.endBlock('</bean>');
 
     return res;
 }
 
-function generateCacheConfiguration(cacheCfg, res) {
+function generateCacheConfiguration(res, cacheCfg) {
     if (!res)
         res = generatorUtils.builder();
 
@@ -590,7 +590,7 @@ function generateCacheConfiguration(cacheCfg, res) {
                 if (!_.contains(metaNames, meta.name)) {
                     metaNames.push(meta.name);
 
-                    generateCacheTypeMetadataConfiguration(meta, res);
+                    generateCacheTypeMetadataConfiguration(res, meta);
                 }
             });
         }
@@ -600,7 +600,7 @@ function generateCacheConfiguration(cacheCfg, res) {
                 if (!_.contains(metaNames, meta.name)) {
                     metaNames.push(meta.name);
 
-                    generateCacheTypeMetadataConfiguration(meta, res);
+                    generateCacheTypeMetadataConfiguration(res, meta);
                 }
             });
         }
@@ -614,8 +614,6 @@ function generateCacheConfiguration(cacheCfg, res) {
     return res;
 }
 
-exports.generateCacheConfiguration = generateCacheConfiguration;
-
 function addElement(res, tag, attr1, val1, attr2, val2) {
     var elem = '<' + tag;
 


[05/41] incubator-ignite git commit: Merge branch 'ignite-961' of https://git-wip-us.apache.org/repos/asf/incubator-ignite into ignite-1121

Posted by an...@apache.org.
Merge branch 'ignite-961' of https://git-wip-us.apache.org/repos/asf/incubator-ignite into ignite-1121


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

Branch: refs/heads/ignite-1121
Commit: 34dbdcf34bca1d4d0291c9f4de814eaf0d0e5dcb
Parents: f965f6b e051674
Author: Andrey <an...@gridgain.com>
Authored: Mon Jul 27 10:53:27 2015 +0700
Committer: Andrey <an...@gridgain.com>
Committed: Mon Jul 27 10:53:27 2015 +0700

----------------------------------------------------------------------
 modules/json/pom.xml | 6 ------
 1 file changed, 6 deletions(-)
----------------------------------------------------------------------



[15/41] incubator-ignite git commit: IGNITE-843 Minor cleanup.

Posted by an...@apache.org.
IGNITE-843 Minor cleanup.


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

Branch: refs/heads/ignite-1121
Commit: ce7ab19b3e10ba90df298dccc4bf714e69838709
Parents: 8af110a
Author: AKuznetsov <ak...@gridgain.com>
Authored: Tue Jul 28 08:22:27 2015 +0700
Committer: AKuznetsov <ak...@gridgain.com>
Committed: Tue Jul 28 08:22:27 2015 +0700

----------------------------------------------------------------------
 modules/web-control-center/src/main/js/views/login.jade         | 2 +-
 modules/web-control-center/src/main/js/views/sql/sql.jade       | 2 +-
 modules/web-control-center/src/main/js/views/templates/tab.jade | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/ce7ab19b/modules/web-control-center/src/main/js/views/login.jade
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/views/login.jade b/modules/web-control-center/src/main/js/views/login.jade
index 7cce3f6..6b8646f 100644
--- a/modules/web-control-center/src/main/js/views/login.jade
+++ b/modules/web-control-center/src/main/js/views/login.jade
@@ -45,7 +45,7 @@ mixin lbl(txt)
                         .details-row(ng-show='action == "register"')
                             +lbl('Confirm:')
                             .col-sm-9.input-tip.has-feedback
-                                input.form-control(type='password', ng-model='user_info.confirm', match="user_info.password" placeholder='Confirm password', required, ng-keyup='$event.keyCode == 13 ? auth(action, user_info) : null')
+                                input.form-control(type='password', ng-model='user_info.confirm', match='user_info.password' placeholder='Confirm password', required, ng-keyup='$event.keyCode == 13 ? auth(action, user_info) : null')
 
             .modal-footer
                 a.show-signup.ng-hide(ng-show='action != "login"', ng-click='action = "login";') log in

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/ce7ab19b/modules/web-control-center/src/main/js/views/sql/sql.jade
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/views/sql/sql.jade b/modules/web-control-center/src/main/js/views/sql/sql.jade
index 1e625ff..97d34de 100644
--- a/modules/web-control-center/src/main/js/views/sql/sql.jade
+++ b/modules/web-control-center/src/main/js/views/sql/sql.jade
@@ -82,4 +82,4 @@ block container
                                     //    td(colspan='{{#{tab}.cols.length}}')
                                     //        .loading-indicator
                                     tr(ng-repeat='row in rows')
-                                        td(ng-repeat="column in #{tab}.cols") {{row[column]}}
\ No newline at end of file
+                                        td(ng-repeat='column in #{tab}.cols') {{row[column]}}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/ce7ab19b/modules/web-control-center/src/main/js/views/templates/tab.jade
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/views/templates/tab.jade b/modules/web-control-center/src/main/js/views/templates/tab.jade
index 518c870..9bf8c1d 100644
--- a/modules/web-control-center/src/main/js/views/templates/tab.jade
+++ b/modules/web-control-center/src/main/js/views/templates/tab.jade
@@ -15,7 +15,7 @@
     limitations under the License.
 
 ul.nav(ng-class='$navClass', role='tablist')
-    li(role='presentation', ng-repeat='$pane in $panes track by $index', ng-class="[ $isActive($pane, $index) ? $activeClass : '', $pane.disabled ? 'disabled' : '' ]")
+    li(role='presentation', ng-repeat='$pane in $panes track by $index', ng-class='[ $isActive($pane, $index) ? $activeClass : "", $pane.disabled ? "disabled" : "" ]')
         a(ng-if='$index == 0' role='tab', data-toggle='tab', ng-click='!$pane.disabled && $setActive($pane.name || $index)', data-index='{{ $index }}', aria-controls='$pane.title') {{$pane.title}}
             i.fa.fa-remove(ng-click='removeTab($index)' ng-if='$index > 0' style='margin-left: 5px')
         a(ng-if='$index > 0' role='tab', data-toggle='tab', ng-click='!$pane.disabled && $setActive($pane.name || $index)', data-index='{{ $index }}', aria-controls='$pane.title') {{$pane.title}}: {{$index}}


[11/41] incubator-ignite git commit: Merge branch 'master' of https://git-wip-us.apache.org/repos/asf/incubator-ignite

Posted by an...@apache.org.
Merge branch 'master' of https://git-wip-us.apache.org/repos/asf/incubator-ignite


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

Branch: refs/heads/ignite-1121
Commit: a12775621f85ea6e203761b116a06bf79ea12b13
Parents: 201e208 5304e6e
Author: ivasilinets <iv...@gridgain.com>
Authored: Mon Jul 27 13:59:14 2015 +0300
Committer: ivasilinets <iv...@gridgain.com>
Committed: Mon Jul 27 13:59:14 2015 +0300

----------------------------------------------------------------------
 modules/yardstick/config/benchmark.properties   |  6 +-
 .../yardstick/IgniteBenchmarkArguments.java     | 22 +++++++
 .../yardstick/cache/IgnitePutAllBenchmark.java  | 67 +++++++++++++++++++
 .../cache/IgnitePutAllTxBenchmark.java          | 68 ++++++++++++++++++++
 4 files changed, 162 insertions(+), 1 deletion(-)
----------------------------------------------------------------------



[13/41] incubator-ignite git commit: Merge remote-tracking branch 'remotes/origin/master' into ignite-961

Posted by an...@apache.org.
Merge remote-tracking branch 'remotes/origin/master' into ignite-961


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

Branch: refs/heads/ignite-1121
Commit: 63e642750f87eeb0d62f121017ba40446a4c7b72
Parents: 70a8b2f a127756
Author: ivasilinets <iv...@gridgain.com>
Authored: Mon Jul 27 17:57:08 2015 +0300
Committer: ivasilinets <iv...@gridgain.com>
Committed: Mon Jul 27 17:57:08 2015 +0300

----------------------------------------------------------------------
 .../handlers/query/QueryCommandHandler.java     |  4 ++
 .../TcpDiscoveryIpFinderAbstractSelfTest.java   |  2 +-
 .../gce/TcpDiscoveryGoogleStorageIpFinder.java  | 18 ++++++
 ...pDiscoveryGoogleStorageIpFinderSelfTest.java | 29 ++++++++-
 modules/yardstick/config/benchmark.properties   |  6 +-
 .../yardstick/IgniteBenchmarkArguments.java     | 22 +++++++
 .../yardstick/cache/IgnitePutAllBenchmark.java  | 67 +++++++++++++++++++
 .../cache/IgnitePutAllTxBenchmark.java          | 68 ++++++++++++++++++++
 8 files changed, 213 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/63e64275/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/query/QueryCommandHandler.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/query/QueryCommandHandler.java
index 35fbcef,59f95c9..d4e101a
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/query/QueryCommandHandler.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/query/QueryCommandHandler.java
@@@ -146,12 -146,12 +146,16 @@@ public class QueryCommandHandler extend
  
                  qryCurs.put(qryId, new IgniteBiTuple<>(qryCur, cur));
  
 -                CacheQueryResult res = createQueryResult(qryCurs, cur, req, qryId);
 +                CacheQueryResult res = createQueryResult(qryCurs, cur, req, qryId, ctx);
 +
 +                List<GridQueryFieldMetadata> fieldsMeta = ((QueryCursorImpl) qryCur).fieldsMeta();
 +
 +                res.setFieldsMetadata(convertMetadata(fieldsMeta));
  
+                 List<GridQueryFieldMetadata> fieldsMeta = ((QueryCursorImpl<?>) qryCur).fieldsMeta();
+ 
+                 res.setFieldsMetadata(convertMetadata(fieldsMeta));
+ 
                  return new GridRestResponse(res);
              }
              catch (Exception e) {


[18/41] incubator-ignite git commit: Merge branch 'ignite-961' of https://git-wip-us.apache.org/repos/asf/incubator-ignite into ignite-1121

Posted by an...@apache.org.
Merge branch 'ignite-961' of https://git-wip-us.apache.org/repos/asf/incubator-ignite into ignite-1121


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

Branch: refs/heads/ignite-1121
Commit: c51381ec46785bf7a599c336001badcd70344bdf
Parents: 49bf1e2 216d4ff
Author: Andrey <an...@gridgain.com>
Authored: Tue Jul 28 11:02:22 2015 +0700
Committer: Andrey <an...@gridgain.com>
Committed: Tue Jul 28 11:02:22 2015 +0700

----------------------------------------------------------------------
 .../TcpDiscoveryIpFinderAbstractSelfTest.java   |  2 +-
 .../gce/TcpDiscoveryGoogleStorageIpFinder.java  | 18 ++++++
 ...pDiscoveryGoogleStorageIpFinderSelfTest.java | 29 ++++++++-
 modules/nodejs/src/main/js/cache.js             | 30 +++++++--
 .../ignite/internal/NodeJsSqlQuerySelfTest.java |  9 +++
 modules/nodejs/src/test/js/test-query.js        | 53 ++++++++++++++-
 modules/yardstick/config/benchmark.properties   |  6 +-
 .../yardstick/IgniteBenchmarkArguments.java     | 22 +++++++
 .../yardstick/cache/IgnitePutAllBenchmark.java  | 67 +++++++++++++++++++
 .../cache/IgnitePutAllTxBenchmark.java          | 68 ++++++++++++++++++++
 10 files changed, 296 insertions(+), 8 deletions(-)
----------------------------------------------------------------------



[23/41] incubator-ignite git commit: Merge remote-tracking branch 'origin/ignite-1121' into ignite-1121

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


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

Branch: refs/heads/ignite-1121
Commit: 301ac429889526b33bacfc00a3ba2117560f518e
Parents: c51381e 666d44c
Author: Andrey <an...@gridgain.com>
Authored: Wed Jul 29 08:43:24 2015 +0700
Committer: Andrey <an...@gridgain.com>
Committed: Wed Jul 29 08:43:24 2015 +0700

----------------------------------------------------------------------
 modules/control-center-agent/README.txt         | 20 +++++++++++++++
 .../java/org/apache/ignite/agent/Agent.java     | 12 ++++-----
 .../org/apache/ignite/agent/AgentLauncher.java  |  4 +--
 .../src/main/resources/config.properties        |  2 --
 .../main/resources/default.config.properties    | 26 ++++++++++++++++++++
 .../src/main/resources/logging.properties       | 15 +++++++++++
 6 files changed, 69 insertions(+), 10 deletions(-)
----------------------------------------------------------------------



[21/41] incubator-ignite git commit: IGNITE-843 Added support for ng-enter && ng-escape directives and use them in tables (commit edit by enter and cancel edit by esc).

Posted by an...@apache.org.
IGNITE-843 Added support for ng-enter && ng-escape directives and use them in tables (commit edit by enter and cancel edit by esc).


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

Branch: refs/heads/ignite-1121
Commit: b90a6d73b91b4d7c36344f532caf74bf7ce336da
Parents: 9018cc4
Author: AKuznetsov <ak...@gridgain.com>
Authored: Tue Jul 28 22:40:42 2015 +0700
Committer: AKuznetsov <ak...@gridgain.com>
Committed: Tue Jul 28 22:40:42 2015 +0700

----------------------------------------------------------------------
 .../main/js/controllers/caches-controller.js    |  1 +
 .../main/js/controllers/clusters-controller.js  |  1 +
 .../src/main/js/controllers/common-module.js    | 30 ++++++++++++++++++++
 .../main/js/controllers/metadata-controller.js  |  1 +
 .../main/js/views/configuration/summary.jade    |  2 +-
 .../src/main/js/views/includes/controls.jade    | 28 +++++++++---------
 .../src/main/js/views/login.jade                | 14 ++++-----
 .../src/main/js/views/settings/profile.jade     |  4 +--
 .../src/main/js/views/templates/layout.jade     |  2 +-
 .../src/main/js/views/templates/select.jade     |  8 +++---
 .../src/main/js/views/templates/tab.jade        |  8 +++---
 11 files changed, 66 insertions(+), 33 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/b90a6d73/modules/web-control-center/src/main/js/controllers/caches-controller.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/controllers/caches-controller.js b/modules/web-control-center/src/main/js/controllers/caches-controller.js
index 0cebc16..e995233 100644
--- a/modules/web-control-center/src/main/js/controllers/caches-controller.js
+++ b/modules/web-control-center/src/main/js/controllers/caches-controller.js
@@ -20,6 +20,7 @@ controlCenterModule.controller('cachesController', ['$scope', '$http', '$common'
         $scope.getModel = $common.getModel;
         $scope.javaBuildInTypes = $common.javaBuildInTypes;
 
+        $scope.tableReset = $table.tableReset;
         $scope.tableNewItem = $table.tableNewItem;
         $scope.tableNewItemActive = $table.tableNewItemActive;
         $scope.tableEditing = $table.tableEditing;

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/b90a6d73/modules/web-control-center/src/main/js/controllers/clusters-controller.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/controllers/clusters-controller.js b/modules/web-control-center/src/main/js/controllers/clusters-controller.js
index 41215b0..0b18868 100644
--- a/modules/web-control-center/src/main/js/controllers/clusters-controller.js
+++ b/modules/web-control-center/src/main/js/controllers/clusters-controller.js
@@ -19,6 +19,7 @@ controlCenterModule.controller('clustersController', ['$scope', '$http', '$commo
         $scope.joinTip = $common.joinTip;
         $scope.getModel = $common.getModel;
 
+        $scope.tableReset = $table.tableReset;
         $scope.tableNewItem = $table.tableNewItem;
         $scope.tableNewItemActive = $table.tableNewItemActive;
         $scope.tableEditing = $table.tableEditing;

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/b90a6d73/modules/web-control-center/src/main/js/controllers/common-module.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/controllers/common-module.js b/modules/web-control-center/src/main/js/controllers/common-module.js
index d44b895..8f31397 100644
--- a/modules/web-control-center/src/main/js/controllers/common-module.js
+++ b/modules/web-control-center/src/main/js/controllers/common-module.js
@@ -376,6 +376,36 @@ controlCenterModule.directive('match', function ($parse) {
     };
 });
 
+// Directive to bind ENTER key press with some user action.
+controlCenterModule.directive('ngEnter', function() {
+    return function(scope, element, attrs) {
+        element.bind('keydown keypress', function(event) {
+            if (event.which === 13) {
+                scope.$apply(function() {
+                    scope.$eval(attrs.ngEnter);
+                });
+
+                event.preventDefault();
+            }
+        });
+    };
+});
+
+// Directive to bind ESC key press with some user action.
+controlCenterModule.directive('ngEscape', function() {
+    return function(scope, element, attrs) {
+        element.bind('keydown keyup', function(event) {
+            if (event.which === 27) {
+                scope.$apply(function() {
+                    scope.$eval(attrs.ngEscape);
+                });
+
+                event.preventDefault();
+            }
+        });
+    };
+});
+
 // Navigation bar controller.
 controlCenterModule.controller('activeLink', [
     '$scope', function ($scope) {

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/b90a6d73/modules/web-control-center/src/main/js/controllers/metadata-controller.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/controllers/metadata-controller.js b/modules/web-control-center/src/main/js/controllers/metadata-controller.js
index db10ddc..c8fad8d 100644
--- a/modules/web-control-center/src/main/js/controllers/metadata-controller.js
+++ b/modules/web-control-center/src/main/js/controllers/metadata-controller.js
@@ -20,6 +20,7 @@ controlCenterModule.controller('metadataController', ['$scope', '$http', '$commo
         $scope.getModel = $common.getModel;
         $scope.javaBuildInTypes = $common.javaBuildInTypes;
 
+        $scope.tableReset = $table.tableReset;
         $scope.tableNewItem = $table.tableNewItem;
         $scope.tableNewItemActive = $table.tableNewItemActive;
         $scope.tableEditing = $table.tableEditing;

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/b90a6d73/modules/web-control-center/src/main/js/views/configuration/summary.jade
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/views/configuration/summary.jade b/modules/web-control-center/src/main/js/views/configuration/summary.jade
index be1cf77..ba63343 100644
--- a/modules/web-control-center/src/main/js/views/configuration/summary.jade
+++ b/modules/web-control-center/src/main/js/views/configuration/summary.jade
@@ -86,7 +86,7 @@ block content
                                     .col-sm-2
                                         label(for='os') Operation System:
                                     .col-sm-4
-                                        input#os.form-control(type='text', ng-model='configServer.os' placeholder='debian:8' data-min-length='0' data-html='1' data-auto-select='true' data-animation='am-flip-x' bs-typeahead bs-options='os for os in oss')
+                                        input#os.form-control(type='text' ng-model='configServer.os' placeholder='debian:8' data-min-length='0' data-html='1' data-auto-select='true' data-animation='am-flip-x' bs-typeahead bs-options='os for os in oss')
                                 div(ui-ace='{ onLoad: aceInit, mode: "dockerfile" }' ng-model='dockerServer')
             .padding-dflt(bs-collapse data-start-collapsed='false')
                 .panel.panel-default

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/b90a6d73/modules/web-control-center/src/main/js/views/includes/controls.jade
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/views/includes/controls.jade b/modules/web-control-center/src/main/js/views/includes/controls.jade
index 5bca8fc..94cdda4 100644
--- a/modules/web-control-center/src/main/js/views/includes/controls.jade
+++ b/modules/web-control-center/src/main/js/views/includes/controls.jade
@@ -55,15 +55,15 @@ mixin btn-down(show, click)
 mixin table-pair-edit(keyModel, valModel, keyPlaceholder, valPlaceholder, keyJavaBuildInTypes, valueJavaBuildInTypes)
     .col-sm-6(style='float: right')
         if valueJavaBuildInTypes
-            input.form-control(type='text' ng-model=valModel placeholder=valPlaceholder bs-typeahead data-min-length='1' bs-options='javaType for javaType in javaBuildInTypes')
+            input.form-control(type='text' ng-model=valModel placeholder=valPlaceholder bs-typeahead data-min-length='1' bs-options='javaType for javaType in javaBuildInTypes' ng-escape='tableReset()')
         else
-            input.form-control(type='text' ng-model=valModel placeholder=valPlaceholder)
+            input.form-control(type='text' ng-model=valModel placeholder=valPlaceholder ng-escape='tableReset()')
     label.fieldSep /
     .input-tip
         if keyJavaBuildInTypes
-            input.form-control(type='text' ng-model=keyModel placeholder=keyPlaceholder bs-typeahead data-min-length='1' bs-options='javaType for javaType in javaBuildInTypes')
+            input.form-control(type='text' ng-model=keyModel placeholder=keyPlaceholder bs-typeahead data-min-length='1' bs-options='javaType for javaType in javaBuildInTypes' ng-escape='tableReset()')
         else
-            input.form-control(type='text' ng-model=keyModel placeholder=keyPlaceholder)
+            input.form-control(type='text' ng-model=keyModel placeholder=keyPlaceholder ng-escape='tableReset()')
 
 mixin table-pair(header, tblMdl, keyFld, valFld, keyPlaceholder, valPlaceholder, keyJavaBuildInTypes, valueJavaBuildInTypes)
     .col-sm-6
@@ -147,7 +147,7 @@ mixin details-row
                                 label.labelField {{$index + 1}})
                                 +btn-save('tableSimpleSaveVisible(curValue)', 'tableSimpleSave(tableSimpleValid, backupItem, detail, curValue, $index)')
                                 .input-tip.form-group.has-feedback
-                                    input.form-control(name='{{detail.model}}.edit' type='text' ng-model='curValue' placeholder='{{::detail.placeholder}}')&attributes(customValidators)
+                                    input.form-control(name='{{detail.model}}.edit' type='text' ng-model='curValue' placeholder='{{::detail.placeholder}}' ng-escape='tableReset()')&attributes(customValidators)
                                     +ico-exclamation('{{detail.model}}.edit', 'ipaddress', 'Invalid address, see help for format description.')
             button.btn.btn-primary.fieldButton(ng-disabled='!newValue' ng-click='tableSimpleSave(tableSimpleValid, backupItem, detail, newValue, -1)') Add
             +tipField('detail.tip')
@@ -160,23 +160,23 @@ mixin table-db-field-edit(databaseName, databaseType, javaName, javaType)
         button.form-control(ng-model=javaType bs-select data-placeholder='Java type' bs-options='item.value as item.label for item in {{javaTypes}}')
     label.fieldSep /
     div(style='width: 20%; float: right')
-        input.form-control(type='text' ng-model=javaName placeholder='Java name')
+        input.form-control(type='text' ng-model=javaName placeholder='Java name' ng-escape='tableReset()')
     label.fieldSep /
     div(style='width: 22%; float: right')
         button.form-control(ng-model=databaseType bs-select data-placeholder='JDBC type' bs-options='item.value as item.label for item in {{jdbcTypes}}')
     label.fieldSep /
     .input-tip
-        input.form-control(type='text' ng-model=databaseName placeholder='DB name')
+        input.form-control(type='text' ng-model=databaseName placeholder='DB name' ng-escape='tableReset()')
 
 mixin table-group-item-edit(fieldName, className, direction)
     div(style='width: 15%; float: right')
         button.form-control(ng-model=direction bs-select data-placeholder='Sort' bs-options='item.value as item.label for item in {{sortDirections}}')
     label.fieldSep /
     div(style='width: 38%; float: right')
-        input.form-control(type='text' ng-model=className placeholder='Class name' bs-typeahead data-min-length='1' bs-options='javaType for javaType in javaBuildInTypes')
+        input.form-control(type='text' ng-model=className placeholder='Class name' bs-typeahead data-min-length='1' bs-options='javaType for javaType in javaBuildInTypes' ng-escape='tableReset()')
     label.fieldSep /
     .input-tip
-        input.form-control(type='text' ng-model=fieldName placeholder='Field name')
+        input.form-control(type='text' ng-model=fieldName placeholder='Field name' ng-escape='tableReset()')
 
 mixin form-row
     +form-row-custom(['col-sm-2'], ['col-sm-4'])
@@ -268,13 +268,13 @@ mixin form-row-custom(lblClasses, fieldClasses)
                                             label.labelField {{$index + 1}})
                                             +btn-save('tableSimpleSaveVisible(curValue)', 'tableSimpleSave(tableSimpleValid, backupItem, field, curValue, $index)')
                                             .input-tip
-                                                input.form-control(type='text' ng-model='curValue' placeholder='{{::field.placeholder}}')
+                                                input.form-control(type='text' ng-model='curValue' placeholder='{{::field.placeholder}}' ng-enter='tableSimpleSaveVisible(curValue) && tableSimpleSave(tableSimpleValid, backupItem, field, curValue, $index)' ng-escape='tableReset()')
                             tfoot(ng-show='tableNewItemActive(field)')
                                 tr
                                     td.col-sm-12
                                         +btn-save('tableSimpleSaveVisible(newValue)', 'tableSimpleSave(tableSimpleValid, backupItem, field, newValue, -1)')
                                         .input-tip
-                                            input.form-control(type='text' ng-model='newValue' placeholder='{{::field.placeholder}}')
+                                            input.form-control(type='text' ng-model='newValue' placeholder='{{::field.placeholder}}' ng-enter='tableSimpleSaveVisible(newValue) && tableSimpleSave(tableSimpleValid, backupItem, field, newValue, -1)' ng-escape='tableReset()')
         div(ng-switch-when='indexedTypes')
             +table-pair('Index key-value type pairs', fieldMdl, 'keyClass', 'valueClass', 'Key class full name', 'Value class full name', true, false)
         div(ng-switch-when='queryFields' ng-hide=fieldHide)
@@ -311,7 +311,7 @@ mixin form-row-custom(lblClasses, fieldClasses)
             .col-sm-12(ng-show='(#{fieldMdl} && #{fieldMdl}.length > 0) || tableNewItemActive(field)')
                 .col-sm-6
                     .table-details
-                        table.links-edit.col-sm-12(st-table=fieldMdl ng-init='newDirection = "ASC"')
+                        table.links-edit.col-sm-12(st-table=fieldMdl ng-init='newDirection = false')
                             tbody
                                 tr(ng-repeat='group in #{fieldMdl}')
                                     td.col-sm-12
@@ -324,7 +324,7 @@ mixin form-row-custom(lblClasses, fieldClasses)
                                                 label.labelField {{$index + 1}})
                                                 +btn-save('tableGroupSaveVisible(curGroupName)', 'tableGroupSave(curGroupName, $index)')
                                                 .input-tip
-                                                    input.form-control(type='text' ng-model='curGroupName' placeholder='Index name')
+                                                    input.form-control(type='text' ng-model='curGroupName' placeholder='Index name' ng-enter='tableGroupSaveVisible(curGroupName) && tableGroupSave(curGroupName, $index)' ng-escape='tableReset()')
                                             div
                                                 table.links-edit.col-sm-12(st-table='group.fields' ng-init='groupIndex = $index')
                                                     tr(ng-repeat='groupItem in group.fields')
@@ -345,4 +345,4 @@ mixin form-row-custom(lblClasses, fieldClasses)
                                     td.col-sm-12
                                         +btn-save('tableGroupSaveVisible(newGroupName)', 'tableGroupSave(newGroupName, -1)')
                                         .input-tip
-                                            input.form-control(type='text' ng-model='newGroupName' placeholder='Group name')
\ No newline at end of file
+                                            input.form-control(type='text' ng-model='newGroupName' placeholder='Group name' ng-enter='tableGroupSaveVisible(newGroupName) && tableGroupSave(newGroupName, -1)' ng-escape='tableReset()')
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/b90a6d73/modules/web-control-center/src/main/js/views/login.jade
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/views/login.jade b/modules/web-control-center/src/main/js/views/login.jade
index 6b8646f..a580c01 100644
--- a/modules/web-control-center/src/main/js/views/login.jade
+++ b/modules/web-control-center/src/main/js/views/login.jade
@@ -22,7 +22,7 @@ mixin lbl(txt)
         .modal-content
             .modal-header.header
                 div(id='errors-container')
-                button.close(type='button', ng-click='$hide()', aria-hidden='true') &times;
+                button.close(type='button' ng-click='$hide()' aria-hidden='true') &times;
                 h1.navbar-brand
                     a(href='/') Apache Ignite Web Configurator
                 h4.modal-title(style='padding-right: 55px') Authentication
@@ -33,23 +33,23 @@ mixin lbl(txt)
                         .details-row(ng-show='action == "register"')
                             +lbl('Full Name:')
                             .col-sm-9
-                                input.form-control(type='text', ng-model='user_info.username', placeholder='John Smith', focus-me='action=="register"', ng-required='action=="register"')
+                                input.form-control(type='text' ng-model='user_info.username' placeholder='John Smith' focus-me='action=="register"' ng-required='action=="register"')
                         .details-row
                             +lbl('Email:')
                             .col-sm-9
-                                input.form-control(type='email', ng-model='user_info.email', placeholder='you@domain.com', focus-me='action=="login"', required)
+                                input.form-control(type='email' ng-model='user_info.email' placeholder='you@domain.com' focus-me='action=="login"' required)
                         .details-row
                             +lbl('Password:')
                             .col-sm-9
-                                input.form-control(type='password', ng-model='user_info.password', placeholder='Password', required, ng-keyup='action == "login" && $event.keyCode == 13 ? auth(action, user_info) : null')
+                                input.form-control(type='password' ng-model='user_info.password' placeholder='Password' required ng-enter='action == "login" && auth(action, user_info)')
                         .details-row(ng-show='action == "register"')
                             +lbl('Confirm:')
                             .col-sm-9.input-tip.has-feedback
-                                input.form-control(type='password', ng-model='user_info.confirm', match='user_info.password' placeholder='Confirm password', required, ng-keyup='$event.keyCode == 13 ? auth(action, user_info) : null')
+                                input.form-control(type='password' ng-model='user_info.confirm' match='user_info.password' placeholder='Confirm password' required ng-enter='auth(action, user_info)')
 
             .modal-footer
-                a.show-signup.ng-hide(ng-show='action != "login"', ng-click='action = "login";') log in
-                a.show-signup(ng-show='action != "register"', ng-click='action = "register"') sign up
+                a.show-signup.ng-hide(ng-show='action != "login"' ng-click='action = "login";') log in
+                a.show-signup(ng-show='action != "register"' ng-click='action = "register"') sign up
                 | &nbsp;or&nbsp;
                 button.btn.btn-primary(ng-show='action == "login"' ng-click='auth(action, user_info)') Log In
                 button.btn.btn-primary(ng-show='action == "register"' ng-disabled='loginForm.$invalid || user_info.password != user_info.confirm' ng-click='auth(action, user_info)') Sign Up

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/b90a6d73/modules/web-control-center/src/main/js/views/settings/profile.jade
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/views/settings/profile.jade b/modules/web-control-center/src/main/js/views/settings/profile.jade
index 96f06c5..6ddcafa 100644
--- a/modules/web-control-center/src/main/js/views/settings/profile.jade
+++ b/modules/web-control-center/src/main/js/views/settings/profile.jade
@@ -48,11 +48,11 @@ block container
                             .details-row
                                 +lbl('New password:')
                                 .col-sm-4
-                                    input.form-control(type='password', ng-model='profileUser.newPassword' placeholder='New password' ng-required='profileUser.changePassword')
+                                    input.form-control(type='password' ng-model='profileUser.newPassword' placeholder='New password' ng-required='profileUser.changePassword')
                             .details-row
                                 +lbl('Confirm:')
                                 .col-sm-4
-                                    input.form-control(type='password', ng-model='profileUser.confirmPassword' match='profileUser.newPassword' placeholder='Confirm new password' ng-required='profileUser.changePassword')
+                                    input.form-control(type='password' ng-model='profileUser.confirmPassword' match='profileUser.newPassword' placeholder='Confirm new password' ng-required='profileUser.changePassword')
                     .col-sm-12.details-row
                         button.btn.btn-primary(ng-disabled='profileForm.$invalid' ng-click='saveUser()') Save
 

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/b90a6d73/modules/web-control-center/src/main/js/views/templates/layout.jade
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/views/templates/layout.jade b/modules/web-control-center/src/main/js/views/templates/layout.jade
index 8fbcd7e..71d8936 100644
--- a/modules/web-control-center/src/main/js/views/templates/layout.jade
+++ b/modules/web-control-center/src/main/js/views/templates/layout.jade
@@ -15,7 +15,7 @@
     limitations under the License.
 
 doctype html
-html(ng-app='ignite-web-control-center', ng-init='user = #{JSON.stringify(user)}; becomeUsed = #{becomeUsed}')
+html(ng-app='ignite-web-control-center' ng-init='user = #{JSON.stringify(user)}; becomeUsed = #{becomeUsed}')
     head
         title= title
 

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/b90a6d73/modules/web-control-center/src/main/js/views/templates/select.jade
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/views/templates/select.jade b/modules/web-control-center/src/main/js/views/templates/select.jade
index 10c1946..b219f13 100644
--- a/modules/web-control-center/src/main/js/views/templates/select.jade
+++ b/modules/web-control-center/src/main/js/views/templates/select.jade
@@ -14,11 +14,11 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 
-ul.select.dropdown-menu(tabindex='-1', ng-show='$isVisible()', role='select')
-    li(role='presentation', ng-repeat='match in $matches')
+ul.select.dropdown-menu(tabindex='-1' ng-show='$isVisible()' role='select')
+    li(role='presentation' ng-repeat='match in $matches')
         hr(ng-if='match.value == undefined' style='margin: 5px 0')
-        a(style='cursor: default; padding: 3px 6px;', role='menuitem', tabindex='-1', ng-class='{active: $isActive($index)}' ng-click='$select($index, $event)')
-            i(class='{{$iconCheckmark}}', ng-if='$isActive($index)' ng-class='{active: $isActive($index)}' style='color: #ec1c24; margin-left: 15px; line-height: 20px; float: right;background-color: transparent;')
+        a(style='cursor: default; padding: 3px 6px;' role='menuitem' tabindex='-1' ng-class='{active: $isActive($index)}' ng-click='$select($index, $event)')
+            i(class='{{$iconCheckmark}}' ng-if='$isActive($index)' ng-class='{active: $isActive($index)}' style='color: #ec1c24; margin-left: 15px; line-height: 20px; float: right;background-color: transparent;')
             span(ng-bind='match.label')
     li(ng-if='$showAllNoneButtons || ($isMultiple && $matches.length > 5)')
         hr(style='margin: 5px 0')

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/b90a6d73/modules/web-control-center/src/main/js/views/templates/tab.jade
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/views/templates/tab.jade b/modules/web-control-center/src/main/js/views/templates/tab.jade
index 9bf8c1d..6c7afc5 100644
--- a/modules/web-control-center/src/main/js/views/templates/tab.jade
+++ b/modules/web-control-center/src/main/js/views/templates/tab.jade
@@ -15,12 +15,12 @@
     limitations under the License.
 
 ul.nav(ng-class='$navClass', role='tablist')
-    li(role='presentation', ng-repeat='$pane in $panes track by $index', ng-class='[ $isActive($pane, $index) ? $activeClass : "", $pane.disabled ? "disabled" : "" ]')
-        a(ng-if='$index == 0' role='tab', data-toggle='tab', ng-click='!$pane.disabled && $setActive($pane.name || $index)', data-index='{{ $index }}', aria-controls='$pane.title') {{$pane.title}}
+    li(role='presentation' ng-repeat='$pane in $panes track by $index' ng-class='[ $isActive($pane, $index) ? $activeClass : "", $pane.disabled ? "disabled" : "" ]')
+        a(ng-if='$index == 0' role='tab' data-toggle='tab' ng-click='!$pane.disabled && $setActive($pane.name || $index)' data-index='{{ $index }}' aria-controls='$pane.title') {{$pane.title}}
             i.fa.fa-remove(ng-click='removeTab($index)' ng-if='$index > 0' style='margin-left: 5px')
-        a(ng-if='$index > 0' role='tab', data-toggle='tab', ng-click='!$pane.disabled && $setActive($pane.name || $index)', data-index='{{ $index }}', aria-controls='$pane.title') {{$pane.title}}: {{$index}}
+        a(ng-if='$index > 0' role='tab' data-toggle='tab' ng-click='!$pane.disabled && $setActive($pane.name || $index)' data-index='{{ $index }}' aria-controls='$pane.title') {{$pane.title}}: {{$index}}
             i.fa.fa-remove(ng-click='removeTab($index)' style='margin-left: 5px')
     li.pull-right(bs-tooltip data-title='Add new query')
-        a(role='tab', data-toggle='tab' ng-click='addTab()')
+        a(role='tab' data-toggle='tab' ng-click='addTab()')
             i.fa.fa-plus
 .tab-content(ng-transclude)


[40/41] incubator-ignite git commit: Merge remote-tracking branch 'origin/ignite-1121' into ignite-1121

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


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

Branch: refs/heads/ignite-1121
Commit: 6ecf62636f60d54b1143d27b715afa2b20de9278
Parents: 6b62175 1ff248c
Author: Andrey <an...@gridgain.com>
Authored: Fri Jul 31 08:50:55 2015 +0700
Committer: Andrey <an...@gridgain.com>
Committed: Fri Jul 31 08:50:55 2015 +0700

----------------------------------------------------------------------
 modules/control-center-agent/src/bin/agent.bat | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)
----------------------------------------------------------------------



[07/41] incubator-ignite git commit: removing Google Compute Engine buckets on test finish

Posted by an...@apache.org.
removing Google Compute Engine buckets on test finish


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

Branch: refs/heads/ignite-1121
Commit: f22de3ea35b1506c8bcf4d2f7bb6d423a0b3225d
Parents: 9bfc184
Author: Denis Magda <dm...@gridgain.com>
Authored: Mon Jul 27 11:06:30 2015 +0300
Committer: Denis Magda <dm...@gridgain.com>
Committed: Mon Jul 27 11:06:30 2015 +0300

----------------------------------------------------------------------
 .../TcpDiscoveryIpFinderAbstractSelfTest.java   |  2 +-
 .../gce/TcpDiscoveryGoogleStorageIpFinder.java  | 18 ++++++++++++
 ...pDiscoveryGoogleStorageIpFinderSelfTest.java | 29 +++++++++++++++++++-
 3 files changed, 47 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/f22de3ea/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/ipfinder/TcpDiscoveryIpFinderAbstractSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/ipfinder/TcpDiscoveryIpFinderAbstractSelfTest.java b/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/ipfinder/TcpDiscoveryIpFinderAbstractSelfTest.java
index b5b8c63..ba660b8 100644
--- a/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/ipfinder/TcpDiscoveryIpFinderAbstractSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/ipfinder/TcpDiscoveryIpFinderAbstractSelfTest.java
@@ -31,7 +31,7 @@ import java.util.*;
 public abstract class TcpDiscoveryIpFinderAbstractSelfTest<T extends TcpDiscoveryIpFinder>
     extends GridCommonAbstractTest {
     /** */
-    private T finder;
+    protected T finder;
 
     /**
      * Constructor.

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/f22de3ea/modules/gce/src/main/java/org/apache/ignite/spi/discovery/tcp/ipfinder/gce/TcpDiscoveryGoogleStorageIpFinder.java
----------------------------------------------------------------------
diff --git a/modules/gce/src/main/java/org/apache/ignite/spi/discovery/tcp/ipfinder/gce/TcpDiscoveryGoogleStorageIpFinder.java b/modules/gce/src/main/java/org/apache/ignite/spi/discovery/tcp/ipfinder/gce/TcpDiscoveryGoogleStorageIpFinder.java
index 48991e8..c2b1a91 100644
--- a/modules/gce/src/main/java/org/apache/ignite/spi/discovery/tcp/ipfinder/gce/TcpDiscoveryGoogleStorageIpFinder.java
+++ b/modules/gce/src/main/java/org/apache/ignite/spi/discovery/tcp/ipfinder/gce/TcpDiscoveryGoogleStorageIpFinder.java
@@ -380,4 +380,22 @@ public class TcpDiscoveryGoogleStorageIpFinder extends TcpDiscoveryIpFinderAdapt
 
         return new InetSocketAddress(res[0], port);
     }
+
+    /**
+     * Used by TEST SUITES only. Called through reflection.
+     *
+     * @param bucketName Bucket to delete.
+     */
+    private void removeBucket(String bucketName) {
+        init();
+
+        try {
+            Storage.Buckets.Delete deleteBucket = storage.buckets().delete(bucketName);
+
+            deleteBucket.execute();
+        }
+        catch (Exception e) {
+            throw new IgniteSpiException("Failed to remove the bucket: " + bucketName, e);
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/f22de3ea/modules/gce/src/test/java/org/apache/ignite/spi/discovery/tcp/ipfinder/gce/TcpDiscoveryGoogleStorageIpFinderSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/gce/src/test/java/org/apache/ignite/spi/discovery/tcp/ipfinder/gce/TcpDiscoveryGoogleStorageIpFinderSelfTest.java b/modules/gce/src/test/java/org/apache/ignite/spi/discovery/tcp/ipfinder/gce/TcpDiscoveryGoogleStorageIpFinderSelfTest.java
index 2fa0d43..f8929cc 100644
--- a/modules/gce/src/test/java/org/apache/ignite/spi/discovery/tcp/ipfinder/gce/TcpDiscoveryGoogleStorageIpFinderSelfTest.java
+++ b/modules/gce/src/test/java/org/apache/ignite/spi/discovery/tcp/ipfinder/gce/TcpDiscoveryGoogleStorageIpFinderSelfTest.java
@@ -21,6 +21,7 @@ import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.spi.discovery.tcp.ipfinder.*;
 import org.apache.ignite.testsuites.*;
 
+import java.lang.reflect.*;
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.util.Collection;
@@ -30,6 +31,9 @@ import java.util.Collection;
  */
 public class TcpDiscoveryGoogleStorageIpFinderSelfTest
     extends TcpDiscoveryIpFinderAbstractSelfTest<TcpDiscoveryGoogleStorageIpFinder> {
+    /** Bucket name. */
+    private static String bucketName;
+
     /**
      * Constructor.
      *
@@ -40,6 +44,29 @@ public class TcpDiscoveryGoogleStorageIpFinderSelfTest
     }
 
     /** {@inheritDoc} */
+    @Override protected void beforeTestsStarted() throws Exception {
+        bucketName = "ip-finder-test-bucket-" + InetAddress.getLocalHost().getAddress()[3];
+
+        super.beforeTestsStarted();
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void afterTestsStopped() throws Exception {
+        try {
+            Method method = TcpDiscoveryGoogleStorageIpFinder.class.getDeclaredMethod("removeBucket", String.class);
+
+            method.setAccessible(true);
+
+            method.invoke(finder, bucketName);
+        }
+        catch (Exception e) {
+            log.warning("Failed to remove bucket on GCE [bucketName=" + bucketName + ", mes=" + e.getMessage() + ']');
+        }
+
+        super.afterTestsStopped();
+    }
+
+    /** {@inheritDoc} */
     @Override protected TcpDiscoveryGoogleStorageIpFinder ipFinder() throws Exception {
         TcpDiscoveryGoogleStorageIpFinder finder = new TcpDiscoveryGoogleStorageIpFinder();
 
@@ -52,7 +79,7 @@ public class TcpDiscoveryGoogleStorageIpFinderSelfTest
         finder.setProjectName(IgniteGCETestSuite.getProjectName());
 
         // Bucket name must be unique across the whole GCE platform.
-        finder.setBucketName("ip-finder-test-bucket-" + InetAddress.getLocalHost().getAddress()[3]);
+        finder.setBucketName(bucketName);
 
         for (int i = 0; i < 5; i++) {
             Collection<InetSocketAddress> addrs = finder.getRegisteredAddresses();


[06/41] incubator-ignite git commit: Merge branch 'ignite-961' of https://git-wip-us.apache.org/repos/asf/incubator-ignite into ignite-1121

Posted by an...@apache.org.
Merge branch 'ignite-961' of https://git-wip-us.apache.org/repos/asf/incubator-ignite into ignite-1121


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

Branch: refs/heads/ignite-1121
Commit: fcfda9ae7ffdd955a60ce7d57121095e9c0c93fb
Parents: 34dbdcf 4475be8
Author: Andrey <an...@gridgain.com>
Authored: Mon Jul 27 14:20:00 2015 +0700
Committer: Andrey <an...@gridgain.com>
Committed: Mon Jul 27 14:20:00 2015 +0700

----------------------------------------------------------------------
 modules/nodejs/src/main/js/sql-fields-query.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------



[24/41] incubator-ignite git commit: Merge branch 'ignite-843' of https://git-wip-us.apache.org/repos/asf/incubator-ignite into ignite-1121

Posted by an...@apache.org.
Merge branch 'ignite-843' of https://git-wip-us.apache.org/repos/asf/incubator-ignite into ignite-1121


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

Branch: refs/heads/ignite-1121
Commit: f621c3ef7d7569aa1c9e4a2109c05aafb0bd6cf0
Parents: 301ac42 2e4daaa
Author: Andrey <an...@gridgain.com>
Authored: Wed Jul 29 08:50:20 2015 +0700
Committer: Andrey <an...@gridgain.com>
Committed: Wed Jul 29 08:50:20 2015 +0700

----------------------------------------------------------------------
 .../main/js/controllers/caches-controller.js    |  1 +
 .../main/js/controllers/clusters-controller.js  |  1 +
 .../src/main/js/controllers/common-module.js    | 59 ++++++++++++
 .../main/js/controllers/metadata-controller.js  |  5 +-
 .../src/main/js/controllers/models/caches.json  |  7 +-
 .../main/js/controllers/models/clusters.json    | 20 ++--
 .../main/js/controllers/models/metadata.json    | 14 ++-
 modules/web-control-center/src/main/js/db.js    |  2 +-
 .../src/main/js/routes/generator/common.js      | 11 ++-
 .../src/main/js/routes/generator/xml.js         | 93 +++++++++++++------
 .../src/main/js/views/configuration/caches.jade |  4 +-
 .../main/js/views/configuration/clusters.jade   |  4 +-
 .../main/js/views/configuration/metadata.jade   |  4 +-
 .../main/js/views/configuration/summary.jade    |  2 +-
 .../src/main/js/views/includes/controls.jade    | 96 ++++++++++----------
 .../src/main/js/views/login.jade                | 14 +--
 .../src/main/js/views/settings/profile.jade     |  4 +-
 .../src/main/js/views/templates/layout.jade     |  2 +-
 .../src/main/js/views/templates/select.jade     |  8 +-
 .../src/main/js/views/templates/tab.jade        |  8 +-
 20 files changed, 237 insertions(+), 122 deletions(-)
----------------------------------------------------------------------



[08/41] incubator-ignite git commit: Merge branch 'ignite-961' of https://git-wip-us.apache.org/repos/asf/incubator-ignite into ignite-1121

Posted by an...@apache.org.
Merge branch 'ignite-961' of https://git-wip-us.apache.org/repos/asf/incubator-ignite into ignite-1121


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

Branch: refs/heads/ignite-1121
Commit: 0ff3504e64166a5b29397ebd6b7161220b112ef6
Parents: fcfda9a 9289dab
Author: Andrey <an...@gridgain.com>
Authored: Mon Jul 27 16:49:36 2015 +0700
Committer: Andrey <an...@gridgain.com>
Committed: Mon Jul 27 16:49:36 2015 +0700

----------------------------------------------------------------------
 RELEASE_NOTES.txt                               |   5 +
 assembly/release-base.xml                       |   5 +
 config/ignite-log4j2.xml                        |  81 +++
 config/ignite-log4j2.xml~                       |  65 +++
 examples/config/example-ignite.xml              |   2 +-
 modules/clients/README.txt                      |  16 +
 modules/clients/readme.md                       |  32 --
 modules/clients/readme.pdf                      | Bin 47887 -> 0 bytes
 .../JettyRestProcessorAbstractSelfTest.java     |  39 +-
 .../rest/protocols/tcp/MockNioSession.java      |  15 -
 .../src/main/java/org/apache/ignite/Ignite.java |   2 +-
 .../configuration/ConnectorConfiguration.java   |  32 ++
 .../configuration/IgniteConfiguration.java      |  63 ++-
 .../apache/ignite/internal/IgniteKernal.java    |  49 +-
 .../GridClientConnectionManagerAdapter.java     |   2 +-
 .../client/router/impl/GridTcpRouterImpl.java   |   2 +-
 .../client/ssl/GridSslBasicContextFactory.java  |   3 +
 .../client/ssl/GridSslContextFactory.java       |   5 +-
 .../discovery/GridDiscoveryManager.java         |   7 +-
 .../cache/CacheEvictableEntryImpl.java          |   2 +-
 .../processors/cache/GridCacheAdapter.java      |  13 +-
 .../processors/cache/GridCacheEntryEx.java      |  32 +-
 .../cache/GridCacheEvictionManager.java         |  12 +-
 .../processors/cache/GridCacheMapEntry.java     | 208 +------
 .../processors/cache/GridCacheUtils.java        |  18 +-
 .../extras/GridCacheAttributesEntryExtras.java  |  37 +-
 .../GridCacheAttributesMvccEntryExtras.java     |  35 +-
 ...dCacheAttributesMvccObsoleteEntryExtras.java |  35 +-
 ...cheAttributesMvccObsoleteTtlEntryExtras.java |  35 +-
 .../GridCacheAttributesMvccTtlEntryExtras.java  |  35 +-
 .../GridCacheAttributesObsoleteEntryExtras.java |  36 +-
 ...idCacheAttributesObsoleteTtlEntryExtras.java |  36 +-
 .../GridCacheAttributesTtlEntryExtras.java      |  36 +-
 .../cache/extras/GridCacheEntryExtras.java      |  14 -
 .../extras/GridCacheEntryExtrasAdapter.java     |   8 -
 .../cache/extras/GridCacheMvccEntryExtras.java  |   8 -
 .../GridCacheMvccObsoleteEntryExtras.java       |   8 -
 .../GridCacheMvccObsoleteTtlEntryExtras.java    |   9 -
 .../extras/GridCacheMvccTtlEntryExtras.java     |   8 -
 .../extras/GridCacheObsoleteEntryExtras.java    |   8 -
 .../extras/GridCacheObsoleteTtlEntryExtras.java |   9 -
 .../cache/extras/GridCacheTtlEntryExtras.java   |   8 -
 .../store/GridCacheStoreManagerAdapter.java     |   2 +-
 .../cache/transactions/IgniteInternalTx.java    |  16 +-
 .../cache/transactions/IgniteTxAdapter.java     |   6 +-
 .../processors/rest/GridRestProcessor.java      |   8 +
 .../query/CacheQueryFieldsMetaResult.java       | 133 +++++
 .../rest/handlers/query/CacheQueryResult.java   |  19 +
 .../handlers/query/QueryCommandHandler.java     |  21 +
 .../rest/protocols/tcp/GridTcpRestProtocol.java |  20 +-
 .../processors/task/GridTaskProcessor.java      |   3 +-
 .../util/lang/GridMetadataAwareAdapter.java     | 296 +++++-----
 .../ignite/internal/util/nio/GridNioServer.java |  28 +-
 .../util/nio/GridNioSessionMetaKey.java         |   5 +-
 .../util/nio/ssl/BlockingSslHandler.java        | 519 ++++++++++++++++++
 .../internal/util/nio/ssl/GridNioSslFilter.java |  53 +-
 .../util/nio/ssl/GridNioSslHandler.java         |  79 ++-
 .../org/apache/ignite/spi/IgniteSpiAdapter.java |  58 ++
 .../spi/IgniteSpiOperationTimeoutException.java |  43 ++
 .../spi/IgniteSpiOperationTimeoutHelper.java    | 102 ++++
 .../communication/tcp/TcpCommunicationSpi.java  | 294 ++++++++--
 .../ignite/spi/discovery/tcp/ClientImpl.java    |  52 +-
 .../ignite/spi/discovery/tcp/ServerImpl.java    | 529 +++++++++++-------
 .../spi/discovery/tcp/TcpDiscoveryImpl.java     |  11 +-
 .../spi/discovery/tcp/TcpDiscoverySpi.java      | 169 ++++--
 .../tcp/internal/TcpDiscoveryNode.java          |  21 +
 .../TcpDiscoveryConnectionCheckMessage.java     |  64 +++
 .../apache/ignite/ssl/SslContextFactory.java    | 458 ++++++++++++++++
 .../org/apache/ignite/ssl/package-info.java     |  22 +
 modules/core/src/test/config/log4j2-test.xml    |  57 ++
 modules/core/src/test/config/log4j2-test.xml~   |  63 +++
 .../src/test/config/log4j2-verbose-test.xml     |  48 ++
 .../IgniteClientReconnectAbstractTest.java      |   4 +-
 .../IgniteTopologyPrintFormatSelfTest.java      |   6 +-
 .../CacheGetFutureHangsSelfTest.java            | 214 ++++++++
 .../cache/eviction/GridCacheMockEntry.java      |  12 +-
 .../internal/util/nio/GridNioSslSelfTest.java   |   2 +-
 .../nio/impl/GridNioFilterChainSelfTest.java    |  15 -
 .../GridMetadataAwareAdapterLoadSelfTest.java   | 135 +++++
 .../lang/GridMetadataAwareAdapterSelfTest.java  |  58 +-
 .../GridAbstractCommunicationSelfTest.java      |  13 +
 .../GridTcpCommunicationSpiAbstractTest.java    |   2 +-
 ...dTcpCommunicationSpiRecoveryAckSelfTest.java |   3 +-
 ...tionSpiRecoveryFailureDetectionSelfTest.java |  54 ++
 ...GridTcpCommunicationSpiRecoverySelfTest.java |  23 +-
 .../tcp/GridTcpCommunicationSpiSslSelfTest.java |  38 ++
 ...unicationSpiTcpFailureDetectionSelfTest.java |  75 +++
 .../tcp/IgniteCacheSslStartStopSelfTest.java    |  46 ++
 .../discovery/AbstractDiscoverySelfTest.java    |  36 +-
 ...lientDiscoverySpiFailureTimeoutSelfTest.java | 205 +++++++
 .../tcp/TcpClientDiscoverySpiSelfTest.java      | 116 ++--
 .../tcp/TcpDiscoverySpiConfigSelfTest.java      |   1 +
 .../TcpDiscoverySpiFailureTimeoutSelfTest.java  | 402 ++++++++++++++
 .../tcp/TcpDiscoverySpiSslSelfTest.java         |  28 +
 .../discovery/tcp/TcpDiscoverySslSelfTest.java  |  42 ++
 .../ignite/testframework/GridTestUtils.java     |  20 +
 .../ignite/testframework/junits/IgniteMock.java |  13 +
 .../IgniteCacheFailoverTestSuite.java           |   4 +-
 .../IgniteSpiCommunicationSelfTestSuite.java    |   3 +
 .../IgniteSpiDiscoverySelfTestSuite.java        |   5 +
 modules/hadoop/docs/HADOOP_README.txt           | 122 +++++
 modules/hadoop/docs/hadoop_readme.md            | 135 -----
 modules/hadoop/docs/hadoop_readme.pdf           | Bin 82219 -> 0 bytes
 modules/log4j/README.txt                        |   2 +-
 .../apache/ignite/logger/log4j/Log4JLogger.java |   2 +-
 modules/log4j2/README.txt                       |  32 ++
 modules/log4j2/licenses/apache-2.0.txt          | 202 +++++++
 modules/log4j2/pom.xml                          |  63 +++
 modules/log4j2/pom.xml~                         |  45 ++
 .../ignite/logger/log4j2/Log4J2Logger.java      | 486 +++++++++++++++++
 .../ignite/logger/log4j2/Log4J2Logger.java~     | 542 +++++++++++++++++++
 .../ignite/logger/log4j2/Log4j2FileAware.java   |  35 ++
 .../ignite/logger/log4j2/Log4j2FileAware.java~  |  33 ++
 .../ignite/logger/log4j2/Log4jFileAware.java~   |  13 +
 .../ignite/logger/log4j2/package-info.java      |  22 +
 .../log4j2/GridLog4j2CorrectFileNameTest.java   |  95 ++++
 .../log4j2/GridLog4j2CorrectFileNameTest.java~  |  95 ++++
 .../log4j2/GridLog4j2InitializedTest.java       |  79 +++
 .../log4j2/GridLog4j2InitializedTest.java~      |  79 +++
 .../log4j2/GridLog4j2LoggingFileTest.java       |  72 +++
 .../log4j2/GridLog4j2LoggingFileTest.java~      |  74 +++
 .../logger/log4j2/Log4j2LoggerSelfTest.java     | 174 ++++++
 .../log4j2/Log4j2LoggerVerboseModeSelfTest.java | 117 ++++
 .../ignite/logger/log4j2/package-info.java      |  22 +
 .../testsuites/IgniteLog4j2TestSuite.java       |  38 ++
 .../visor/commands/open/VisorOpenCommand.scala  |  17 +-
 .../scala/org/apache/ignite/visor/visor.scala   |   3 +
 modules/yardstick/README.md                     |  85 ---
 modules/yardstick/README.txt                    |  93 ++++
 parent/pom.xml                                  |   4 +-
 pom.xml                                         |   1 +
 131 files changed, 7137 insertions(+), 1494 deletions(-)
----------------------------------------------------------------------



[32/41] incubator-ignite git commit: # ignite-843 Rename

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/control-center-web/src/main/js/views/includes/controls.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/views/includes/controls.jade b/modules/control-center-web/src/main/js/views/includes/controls.jade
new file mode 100644
index 0000000..e9fe71b
--- /dev/null
+++ b/modules/control-center-web/src/main/js/views/includes/controls.jade
@@ -0,0 +1,350 @@
+//-
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+
+mixin block-callout(titleWorkflow, contentWorkflow, whatsNextWorkflow, whatsNextContent)
+    .block-callout-parent.block-callout-border.margin-bottom-dflt
+        .block-callout
+            i.fa.fa-check-square
+            label #{titleWorkflow}
+            p(ng-bind-html=contentWorkflow)
+        .block-callout
+            i.fa.fa-check-square
+            label #{whatsNextWorkflow}
+            p(ng-bind-html=whatsNextContent)
+
+
+mixin tipField(lines)
+    i.tipField.fa.fa-question-circle(ng-if=lines bs-tooltip='joinTip(#{lines})' type='button')
+    i.tipField.fa.fa-question-circle.blank(ng-if='!#{lines}')
+
+mixin tipLabel(lines)
+    i.tipLabel.fa.fa-question-circle(ng-if=lines bs-tooltip='joinTip(#{lines})' type='button')
+    i.tipLabel.fa.fa-question-circle.blank(ng-if='!#{lines}')
+
+mixin ico-exclamation(mdl, err, msg)
+    i.fa.fa-exclamation-triangle.form-control-feedback(ng-show='inputForm["#{mdl}"].$error.#{err}' bs-tooltip data-title='#{msg}' type='button')
+
+mixin btn-save(show, click)
+    i.tipField.fa.fa-floppy-o(ng-show=show ng-click=click bs-tooltip data-title='Save item')
+
+mixin btn-add(click, tip, focusId)
+    i.tipField.fa.fa-plus(ng-click=click bs-tooltip=tip event-focus='click' event-focus-id=focusId)
+
+mixin btn-remove(click, tip)
+    i.tipField.fa.fa-remove(ng-click=click bs-tooltip=tip data-trigger='hover')
+
+mixin btn-up(show, click)
+    i.tipField.fa.fa-arrow-up(ng-show=show ng-click=click bs-tooltip data-title='Move item up')
+
+mixin btn-down(show, click)
+    i.tipField.fa.fa-arrow-down(ng-show=show ng-click=click bs-tooltip data-title='Move item down')
+
+mixin table-pair-edit(keyModel, valModel, keyPlaceholder, valPlaceholder, keyJavaBuildInTypes, valueJavaBuildInTypes, focusId)
+    .col-sm-6(style='float: right')
+        if valueJavaBuildInTypes
+            input.form-control(type='text' ng-model=valModel placeholder=valPlaceholder bs-typeahead data-min-length='1' bs-options='javaType for javaType in javaBuildInTypes' ng-escape='tableReset()')
+        else
+            input.form-control(type='text' ng-model=valModel placeholder=valPlaceholder ng-escape='tableReset()')
+    label.fieldSep /
+    .input-tip
+        if keyJavaBuildInTypes
+            input.form-control(id=focusId type='text' ng-model=keyModel placeholder=keyPlaceholder bs-typeahead data-min-length='1' bs-options='javaType for javaType in javaBuildInTypes' ng-escape='tableReset()')
+        else
+            input.form-control(id=focusId type='text' ng-model=keyModel placeholder=keyPlaceholder ng-escape='tableReset()')
+
+mixin table-pair(header, tblMdl, keyFld, valFld, keyPlaceholder, valPlaceholder, keyJavaBuildInTypes, valueJavaBuildInTypes)
+    .col-sm-6
+        label.table-header #{header}:
+        +tipLabel('field.tip')
+        +btn-add('tableNewItem(field)', 'field.addTip', '{{::field.focusNewItemId}}')
+        .table-details(ng-show='(#{tblMdl} && #{tblMdl}.length > 0) || tableNewItemActive(field)')
+            table.links-edit.col-sm-12(st-table=tblMdl)
+                tbody
+                    tr(ng-repeat='item in #{tblMdl}')
+                        td.col-sm-12
+                            div(ng-show='!tableEditing(field, $index)')
+                                a.labelFormField(event-focus='click' event-focus-id='{{::field.focusCurItemId}}' ng-click='curPair = tableStartEdit(backupItem, field, $index); curKey = curPair.#{keyFld}; curValue = curPair.#{valFld}') {{$index + 1}}) {{item.#{keyFld}}} / {{item.#{valFld}}}
+                                +btn-remove('tableRemove(backupItem, field, $index)', 'field.removeTip')
+                            div(ng-if='tableEditing(field, $index)')
+                                label.labelField {{$index + 1}})
+                                +btn-save('tablePairSaveVisible(curKey, curValue)', 'tablePairSave(tablePairValid, backupItem, field, curKey, curValue, $index)')
+                                +table-pair-edit('curKey', 'curValue', keyPlaceholder, valPlaceholder, keyJavaBuildInTypes, valueJavaBuildInTypes, '{{::field.focusCurItemId}}')
+                tfoot(ng-show='tableNewItemActive(field)')
+                    tr
+                        td.col-sm-12
+                            +btn-save('tablePairSaveVisible(newKey, newValue)', 'tablePairSave(tablePairValid, backupItem, field, newKey, newValue, -1)')
+                            +table-pair-edit('newKey', 'newValue', keyPlaceholder, valPlaceholder, keyJavaBuildInTypes, valueJavaBuildInTypes, '{{::field.focusNewItemId}}')
+
+mixin details-row
+    - var lblDetailClasses = ['col-sm-4', 'details-label']
+
+    - var detailMdl = 'getModel(backupItem, detail)[detail.model]';
+    - var detailCommon = {'ng-model': detailMdl, 'ng-required': 'detail.required'};
+
+    - var customValidators = {'ng-attr-ipaddress': '{{detail.ipaddress}}'}
+
+    div(ng-switch='detail.type')
+        div(ng-switch-when='label')
+            label {{::detail.label}}
+        div.checkbox(ng-switch-when='check')
+            label
+                input(type='checkbox')&attributes(detailCommon)
+                |{{::detail.label}}
+                +tipLabel('detail.tip')
+        div(ng-switch-when='text')
+            label(class=lblDetailClasses ng-class='{required: detail.required}') {{::detail.label}}:
+            .col-sm-8
+                +tipField('detail.tip')
+                .input-tip
+                    input.form-control(type='text' placeholder='{{::detail.placeholder}}')&attributes(detailCommon)
+        div(ng-switch-when='number' )
+            label(class=lblDetailClasses ng-class='{required: detail.required}') {{::detail.label}}:
+            .col-sm-8
+                +tipField('detail.tip')
+                .input-tip
+                    input.form-control(name='{{detail.model}}' type='number' placeholder='{{::detail.placeholder}}' min='{{detail.min ? detail.min : 0}}' max='{{detail.max ? detail.max : Number.MAX_VALUE}}')&attributes(detailCommon)
+                    +ico-exclamation('{{detail.model}}', 'min', 'Value is less than allowable minimum.')
+                    +ico-exclamation('{{detail.model}}', 'max', 'Value is more than allowable maximum.')
+                    +ico-exclamation('{{detail.model}}', 'number', 'Invalid value. Only numbers allowed.')
+        div(ng-switch-when='dropdown')
+            label(class=lblDetailClasses ng-class='{required: detail.required}') {{::detail.label}}:
+            .col-sm-8
+                +tipField('detail.tip')
+                .input-tip
+                    button.form-control(bs-select data-placeholder='{{::detail.placeholder}}' bs-options='item.value as item.label for item in {{detail.items}}')&attributes(detailCommon)
+        div(ng-switch-when='dropdown-multiple')
+            label(class=lblDetailClasses ng-class='{required: detail.required}') {{::detail.label}}:
+            .col-sm-8
+                button.form-control(bs-select data-multiple='1' data-placeholder='{{::detail.placeholder}}' bs-options='item.value as item.label for item in {{detail.items}}')&attributes(detailCommon)
+            +tipField('detail.tip')
+        div(ng-switch-when='table-simple')&attributes(detailCommon)
+            div(ng-if='detail.label')
+                label.table-header {{::detail.label}}:
+                +tipLabel('detail.tableTip')
+            table.col-sm-12.links-edit-details(st-table='#{detailMdl}')
+                tbody
+                    tr(ng-repeat='item in #{detailMdl} track by $index')
+                        td
+                            div(ng-show='!tableEditing(detail, $index)')
+                                a.labelFormField(event-focus='click' event-focus-id='{{::detail.focusCurItemId}}' ng-click='curValue = tableStartEdit(backupItem, detail, $index)') {{$index + 1}}) {{item}}
+                                +btn-remove('tableRemove(backupItem, detail, $index)', 'detail.removeTip')
+                                +btn-down('detail.reordering && tableSimpleDownVisible(backupItem, detail, $index)', 'tableSimpleDown(backupItem, detail, $index)')
+                                +btn-up('detail.reordering && $index > 0', 'tableSimpleUp(backupItem, detail, $index)')
+                            div(ng-if='tableEditing(detail, $index)')
+                                label.labelField {{$index + 1}})
+                                +btn-save('tableSimpleSaveVisible(curValue)', 'tableSimpleSave(tableSimpleValid, backupItem, detail, curValue, $index)')
+                                .input-tip.form-group.has-feedback
+                                    input.form-control(id='{{::detail.focusCurItemId}}' name='{{detail.model}}.edit' type='text' ng-model='curValue' placeholder='{{::detail.placeholder}}' ng-escape='tableReset()')&attributes(customValidators)
+                                    +ico-exclamation('{{detail.model}}.edit', 'ipaddress', 'Invalid address, see help for format description.')
+            button.btn.btn-primary.fieldButton(ng-disabled='!newValue' ng-click='tableSimpleSave(tableSimpleValid, backupItem, detail, newValue, -1)') Add
+            +tipField('detail.tip')
+            .input-tip.form-group.has-feedback
+                input.form-control(name='{{detail.model}}' type='text' ng-model='newValue' ng-focus='tableNewItem(detail)' placeholder='{{::detail.placeholder}}')&attributes(customValidators)
+                +ico-exclamation('{{detail.model}}', 'ipaddress', 'Invalid address, see help for format description.')
+
+mixin table-db-field-edit(databaseName, databaseType, javaName, javaType)
+    div(style='width: 22%; float: right')
+        button.form-control(ng-model=javaType bs-select data-placeholder='Java type' bs-options='item.value as item.label for item in {{javaTypes}}')
+    label.fieldSep /
+    div(style='width: 20%; float: right')
+        input.form-control(type='text' ng-model=javaName placeholder='Java name' ng-escape='tableReset()')
+    label.fieldSep /
+    div(style='width: 22%; float: right')
+        button.form-control(ng-model=databaseType bs-select data-placeholder='JDBC type' bs-options='item.value as item.label for item in {{jdbcTypes}}')
+    label.fieldSep /
+    .input-tip
+        input.form-control(type='text' ng-model=databaseName placeholder='DB name' ng-escape='tableReset()')
+
+mixin table-group-item-edit(fieldName, className, direction, focusId)
+    div(style='width: 15%; float: right')
+        button.form-control(ng-model=direction bs-select data-placeholder='Sort' bs-options='item.value as item.label for item in {{sortDirections}}')
+    label.fieldSep /
+    div(style='width: 38%; float: right')
+        input.form-control(type='text' ng-model=className placeholder='Class name' bs-typeahead data-min-length='1' bs-options='javaType for javaType in javaBuildInTypes' ng-escape='tableReset()')
+    label.fieldSep /
+    .input-tip
+        input.form-control(id=focusId type='text' ng-model=fieldName placeholder='Field name' ng-escape='tableReset()')
+
+mixin form-row
+    +form-row-custom(['col-sm-2'], ['col-sm-4'])
+
+mixin form-row-custom(lblClasses, fieldClasses)
+    - var fieldMdl = 'getModel(backupItem, field)[field.model]';
+    - var fieldCommon = {'ng-model': fieldMdl, 'ng-required': 'field.required || required(field)'};
+    - var fieldRequiredClass = '{true: "required"}[field.required || required(field)]'
+    - var fieldHide = '{{field.hide}}'
+
+    div(ng-switch='field.type')
+        div.col-sm-6(ng-switch-when='label')
+            label {{::field.label}}
+        div.checkbox.col-sm-6(ng-switch-when='check' ng-hide=fieldHide)
+            label
+                input(type='checkbox')&attributes(fieldCommon)
+                | {{::field.label}}
+                +tipLabel('field.tip')
+        div(ng-switch-when='text' ng-hide=fieldHide)
+            label(class=lblClasses ng-class=fieldRequiredClass) {{::field.label}}:
+            div(class=fieldClasses)
+                +tipField('field.tip')
+                .input-tip
+                    input.form-control(id='{{::field.id}}' type='text' placeholder='{{::field.placeholder}}')&attributes(fieldCommon)
+        div(ng-switch-when='withJavaBuildInTypes' ng-hide=fieldHide)
+            label(class=lblClasses ng-class=fieldRequiredClass) {{::field.label}}:
+            div(class=fieldClasses)
+                +tipField('field.tip')
+                .input-tip
+                    input.form-control(type='text' placeholder='{{::field.placeholder}}' bs-typeahead data-min-length='1' bs-options='javaType for javaType in javaBuildInTypes')&attributes(fieldCommon)
+        div(ng-switch-when='password' ng-hide=fieldHide)
+            label(class=lblClasses ng-class=fieldRequiredClass) {{::field.label}}:
+            div(class=fieldClasses)
+                +tipField('field.tip')
+                .input-tip
+                    input.form-control(type='password' placeholder='{{::field.placeholder}}')&attributes(fieldCommon)
+        div(ng-switch-when='number' ng-hide=fieldHide)
+            label(class=lblClasses ng-class=fieldRequiredClass) {{::field.label}}:
+            div(class=fieldClasses)
+                +tipField('field.tip')
+                .input-tip
+                    input.form-control(name='{{field.model}}' type='number' placeholder='{{::field.placeholder}}' min='{{field.min ? field.min : 0}}' max='{{field.max ? field.max : Number.MAX_VALUE}}')&attributes(fieldCommon)
+                    +ico-exclamation('{{field.model}}', 'min', 'Value is less than allowable minimum.')
+                    +ico-exclamation('{{field.model}}', 'max', 'Value is more than allowable maximum.')
+                    +ico-exclamation('{{field.model}}', 'number', 'Invalid value. Only numbers allowed.')
+        div(ng-switch-when='dropdown' ng-hide=fieldHide)
+            label(class=lblClasses ng-class=fieldRequiredClass) {{::field.label}}:
+            div(class=fieldClasses)
+                +tipField('field.tip')
+                .input-tip
+                    button.form-control(bs-select data-placeholder='{{::field.placeholder}}' bs-options='item.value as item.label for item in {{field.items}}')&attributes(fieldCommon)
+        div(ng-switch-when='dropdown-multiple' ng-hide=fieldHide)
+            label(class=lblClasses ng-class=fieldRequiredClass) {{::field.label}}:
+            div(class=fieldClasses)
+                +tipField('field.tip')
+                .input-tip
+                    button.form-control(bs-select ng-disabled='{{field.items}}.length == 0' data-multiple='1' data-placeholder='{{::field.placeholder}}' bs-options='item.value as item.label for item in {{field.items}}')&attributes(fieldCommon)
+            a.customize(ng-show='field.addLink' ng-href='{{field.addLink.ref}}') {{field.addLink.label}}
+        div(ng-switch-when='dropdown-details' ng-hide=fieldHide)
+            - var expanded = 'field.details[' + fieldMdl + '].expanded'
+
+            label(class=lblClasses ng-class=fieldRequiredClass) {{::field.label}}:
+            div(class=fieldClasses)
+                +tipField('field.tip')
+                .input-tip
+                    button.form-control(bs-select data-placeholder='{{::field.placeholder}}' bs-options='item.value as item.label for item in {{field.items}}')&attributes(fieldCommon)
+            a.customize(ng-show='#{fieldMdl} && field.details[#{fieldMdl}].fields' ng-click='#{expanded} = !#{expanded}') {{#{expanded} ? "Hide settings" : "Show settings"}}
+            .col-sm-6.panel-details(ng-show='#{expanded} && #{fieldMdl}')
+                .details-row(ng-repeat='detail in field.details[#{fieldMdl}].fields')
+                    +details-row
+        div(ng-switch-when='table-simple' ng-hide=fieldHide)&attributes(fieldCommon)
+            .col-sm-6
+                label.table-header {{::field.label}}:
+                +tipLabel('field.tableTip')
+                +btn-add('tableNewItem(field)', 'field.addTip', '{{::field.focusNewItemId}}')
+            .col-sm-12(ng-show='(#{fieldMdl} && #{fieldMdl}.length > 0) || tableNewItemActive(field)')
+                .col-sm-6
+                    .table-details
+                        table.links-edit.col-sm-12(st-table='#{fieldMdl}')
+                            tbody
+                                tr(ng-repeat='item in #{fieldMdl} track by $index')
+                                    td.col-sm-12
+                                        div(ng-show='!tableEditing(field, $index)')
+                                            a.labelFormField(event-focus='click' event-focus-id='{{::field.focusCurItemId}}' ng-click='curValue = tableStartEdit(backupItem, field, $index)') {{$index + 1}}) {{item | compact}}
+                                            +btn-remove('tableRemove(backupItem, field, $index)', 'field.removeTip')
+                                            +btn-down('field.reordering && tableSimpleDownVisible(backupItem, field, $index)', 'tableSimpleDown(backupItem, field, $index)')
+                                            +btn-up('field.reordering && $index > 0', 'tableSimpleUp(backupItem, field, $index)')
+                                        div(ng-if='tableEditing(field, $index)')
+                                            label.labelField {{$index + 1}})
+                                            +btn-save('tableSimpleSaveVisible(curValue)', 'tableSimpleSave(tableSimpleValid, backupItem, field, curValue, $index)')
+                                            .input-tip
+                                                input.form-control(id='{{::field.focusCurItemId}}' type='text' ng-model='curValue' placeholder='{{::field.placeholder}}' ng-enter='tableSimpleSaveVisible(curValue) && tableSimpleSave(tableSimpleValid, backupItem, field, curValue, $index)' ng-escape='tableReset()')
+                            tfoot(ng-show='tableNewItemActive(field)')
+                                tr
+                                    td.col-sm-12
+                                        +btn-save('tableSimpleSaveVisible(newValue)', 'tableSimpleSave(tableSimpleValid, backupItem, field, newValue, -1)')
+                                        .input-tip
+                                            input.form-control(id='{{::field.focusNewItemId}}' type='text' ng-model='newValue' placeholder='{{::field.placeholder}}' ng-enter='tableSimpleSaveVisible(newValue) && tableSimpleSave(tableSimpleValid, backupItem, field, newValue, -1)' ng-escape='tableReset()')
+        div(ng-switch-when='indexedTypes')
+            +table-pair('Index key-value type pairs', fieldMdl, 'keyClass', 'valueClass', 'Key class full name', 'Value class full name', true, false)
+        div(ng-switch-when='queryFields' ng-hide=fieldHide)
+            +table-pair('{{::field.label}}', fieldMdl, 'name', 'className', 'Field name', 'Field class full name', false, true)
+        div(ng-switch-when='dbFields' ng-hide=fieldHide)
+            .col-sm-6
+                label.table-header {{::field.label}}:
+                +tipLabel('field.tip')
+                +btn-add('tableNewItem(field)', 'field.addTip', 'field.focusNewItemId')
+            .col-sm-12(ng-show='(#{fieldMdl} && #{fieldMdl}.length > 0) || tableNewItemActive(field)')
+                .col-sm-6
+                    .table-details
+                        table.links-edit.col-sm-12(st-table=fieldMdl)
+                            tbody
+                                tr(ng-repeat='item in #{fieldMdl}')
+                                    td.col-sm-12
+                                        div(ng-show='!tableEditing(field, $index)')
+                                            a.labelFormField(ng-click='curField = tableStartEdit(backupItem, field, $index); curDatabaseName = curField.databaseName; curDatabaseType = curField.databaseType; curJavaName = curField.javaName; curJavaType = curField.javaType') {{$index + 1}}) {{item.databaseName}} / {{item.databaseType}} / {{item.javaName}} / {{item.javaType}}
+                                            +btn-remove('tableRemove(backupItem, field, $index)', 'field.removeTip')
+                                        div(ng-if='tableEditing(field, $index)')
+                                            label.labelField {{$index + 1}})
+                                            +btn-save('tableDbFieldSaveVisible(curDatabaseName, curDatabaseType, curJavaName, curJavaType)', 'tableDbFieldSave(field, curDatabaseName, curDatabaseType, curJavaName, curJavaType, $index)')
+                                            +table-db-field-edit('curDatabaseName', 'curDatabaseType', 'curJavaName', 'curJavaType')
+                            tfoot(ng-show='tableNewItemActive(field)')
+                                tr
+                                    td.col-sm-12
+                                        +btn-save('tableDbFieldSaveVisible(newDatabaseName, newDatabaseType, newJavaName, newJavaType)', 'tableDbFieldSave(field, newDatabaseName, newDatabaseType, newJavaName, newJavaType, -1)')
+                                        +table-db-field-edit('newDatabaseName', 'newDatabaseType', 'newJavaName', 'newJavaType')
+        div(ng-switch-when='queryGroups' ng-hide=fieldHide)
+            .col-sm-6
+                label.table-header {{::field.label}}:
+                +tipLabel('field.tip')
+                +btn-add('tableNewItem(field)', 'field.addTip', 'newGroupId')
+            .col-sm-12(ng-show='(#{fieldMdl} && #{fieldMdl}.length > 0) || tableNewItemActive(field)')
+                .col-sm-6
+                    .table-details
+                        table.links-edit.col-sm-12(st-table=fieldMdl ng-init='newDirection = false')
+                            tbody
+                                tr(ng-repeat='group in #{fieldMdl}')
+                                    td.col-sm-12
+                                        div
+                                            .col-sm-12(ng-show='!tableEditing(field, $index)')
+                                                a.labelFormField(event-focus='click' event-focus-id='curGroupId' ng-click='curGroup = tableStartEdit(backupItem, field, $index); curGroupName = curGroup.name; curFields = curGroup.fields') {{$index + 1}}) {{group.name}}
+                                                +btn-remove('tableRemove(backupItem, field, $index)', 'field.removeTip')
+                                                +btn-add('tableGroupNewItem($index)', 'field.addItemTip', 'newGroupItemId')
+                                            div(ng-if='tableEditing(field, $index)')
+                                                label.labelField {{$index + 1}})
+                                                +btn-save('tableGroupSaveVisible(curGroupName)', 'tableGroupSave(curGroupName, $index)')
+                                                .input-tip
+                                                    input#curGroupId.form-control(type='text' ng-model='curGroupName' placeholder='Index name' ng-enter='tableGroupSaveVisible(curGroupName) && tableGroupSave(curGroupName, $index)' ng-escape='tableReset()')
+                                            div
+                                                table.links-edit.col-sm-12(st-table='group.fields' ng-init='groupIndex = $index')
+                                                    tbody
+                                                        tr(ng-repeat='groupItem in group.fields')
+                                                            td
+                                                                div(ng-show='!tableGroupItemEditing(groupIndex, $index)')
+                                                                    a.labelFormField(event-focus='click' event-focus-id='curGroupItemId' ng-click='curGroupItem = tableGroupItemStartEdit(groupIndex, $index); curFieldName = curGroupItem.name; curClassName = curGroupItem.className; curDirection = curGroupItem.direction') {{$index + 1}}) {{groupItem.name}} / {{groupItem.className}} / {{groupItem.direction ? "DESC" : "ASC"}}
+                                                                    +btn-remove('tableRemoveGroupItem(group, $index)', 'field.removeItemTip')
+                                                                div(ng-if='tableGroupItemEditing(groupIndex, $index)')
+                                                                    label.labelField {{$index + 1}})
+                                                                    +btn-save('tableGroupItemSaveVisible(curFieldName, curClassName)', 'tableGroupItemSave(curFieldName, curClassName, curDirection, groupIndex, $index)')
+                                                                    +table-group-item-edit('curFieldName', 'curClassName', 'curDirection', 'curGroupItemId')
+                                                    tfoot(ng-if='tableGroupNewItemActive(groupIndex)')
+                                                        tr.col-sm-12(style='padding-left: 18px')
+                                                            td
+                                                                +btn-save('tableGroupItemSaveVisible(newFieldName, newClassName)', 'tableGroupItemSave(newFieldName, newClassName, newDirection, groupIndex, -1)')
+                                                                +table-group-item-edit('newFieldName', 'newClassName', 'newDirection', 'newGroupItemId')
+                            tfoot(ng-show='tableNewItemActive(field)')
+                                tr
+                                    td.col-sm-12
+                                        +btn-save('tableGroupSaveVisible(newGroupName)', 'tableGroupSave(newGroupName, -1)')
+                                        .input-tip
+                                            input#newGroupId.form-control(type='text' ng-model='newGroupName' placeholder='Group name' ng-enter='tableGroupSaveVisible(newGroupName) && tableGroupSave(newGroupName, -1)' ng-escape='tableReset()')
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/control-center-web/src/main/js/views/includes/footer.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/views/includes/footer.jade b/modules/control-center-web/src/main/js/views/includes/footer.jade
new file mode 100644
index 0000000..d8ff5d7
--- /dev/null
+++ b/modules/control-center-web/src/main/js/views/includes/footer.jade
@@ -0,0 +1,22 @@
+//-
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+
+.container.container-footer
+    footer
+        center
+            p Apache Ignite Control Center, version 1.0.0
+            p © 2015 The Apache Software Foundation.
+            p Apache, Apache Ignite, the Apache feather and the Apache Ignite logo are trademarks of The Apache Software Foundation.
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/control-center-web/src/main/js/views/includes/header.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/views/includes/header.jade b/modules/control-center-web/src/main/js/views/includes/header.jade
new file mode 100644
index 0000000..bfd5275
--- /dev/null
+++ b/modules/control-center-web/src/main/js/views/includes/header.jade
@@ -0,0 +1,39 @@
+//-
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+mixin header-item(active, ref, txt)
+    li
+        a(ng-class='{active: isActive("#{active}")}' href='#{ref}') #{txt}
+
+header.header(id='header')
+    .viewedUser(ng-show='becomeUsed') Currently assuming "
+        strong {{user.username}}
+        | ",&nbsp;&nbsp;
+        a(href='/admin/become') revert to your identity.
+    .container
+        h1.navbar-brand
+            a(href='/') Apache Ignite Web Configurator
+        .navbar-collapse.collapse(ng-controller='auth')
+            ul.nav.navbar-nav(ng-controller='activeLink' ng-show='user')
+                +header-item('/configuration', '/configuration/clusters', 'Configuration')
+                //+header-item('/monitoring', '/monitoring', 'Monitoring')
+                +header-item('/sql', '/sql', 'SQL')
+                //+header-item('/deploy', '/deploy', 'Deploy')
+            ul.nav.navbar-nav.pull-right
+                li(ng-if='user')
+                    a.dropdown-toggle(data-toggle='dropdown' bs-dropdown='userDropdown' data-placement='bottom-right') {{user.username}}
+                        span.caret
+                li.nav-login(ng-if='!user')
+                    a(ng-click='login()' href='#') Log In
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/control-center-web/src/main/js/views/index.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/views/index.jade b/modules/control-center-web/src/main/js/views/index.jade
new file mode 100644
index 0000000..999c4f8
--- /dev/null
+++ b/modules/control-center-web/src/main/js/views/index.jade
@@ -0,0 +1,30 @@
+//-
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+
+extends templates/layout
+
+block container
+    .row
+        .docs-content
+            div
+                p
+                    | Apache Ignite<sup>tm</sup> In-Memory Data Fabric is a high-performance,
+                    | integrated and distributed in-memory platform for computing and transacting on large-scale data
+                    | sets in real-time, orders of magnitude faster than possible with traditional disk-based or flash technologies.
+        .block-image.block-display-image
+                img(ng-src='https://www.filepicker.io/api/file/lydEeGB6Rs9hwbpcQxiw' alt='Apache Ignite stack')
+        .text-center(ng-controller='auth')
+            button.btn.btn-primary(ng-click='login()' href='#') Configure Now

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/control-center-web/src/main/js/views/login.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/views/login.jade b/modules/control-center-web/src/main/js/views/login.jade
new file mode 100644
index 0000000..a580c01
--- /dev/null
+++ b/modules/control-center-web/src/main/js/views/login.jade
@@ -0,0 +1,55 @@
+//-
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+
+mixin lbl(txt)
+    label.col-sm-3.required #{txt}
+
+.modal.center(role='dialog')
+    .modal-dialog
+        .modal-content
+            .modal-header.header
+                div(id='errors-container')
+                button.close(type='button' ng-click='$hide()' aria-hidden='true') &times;
+                h1.navbar-brand
+                    a(href='/') Apache Ignite Web Configurator
+                h4.modal-title(style='padding-right: 55px') Authentication
+                p(style='padding-right: 55px') Log in or register in order to collaborate
+            form.form-horizontal(name='loginForm')
+                .modal-body.row
+                    .col-sm-9.login.col-sm-offset-1
+                        .details-row(ng-show='action == "register"')
+                            +lbl('Full Name:')
+                            .col-sm-9
+                                input.form-control(type='text' ng-model='user_info.username' placeholder='John Smith' focus-me='action=="register"' ng-required='action=="register"')
+                        .details-row
+                            +lbl('Email:')
+                            .col-sm-9
+                                input.form-control(type='email' ng-model='user_info.email' placeholder='you@domain.com' focus-me='action=="login"' required)
+                        .details-row
+                            +lbl('Password:')
+                            .col-sm-9
+                                input.form-control(type='password' ng-model='user_info.password' placeholder='Password' required ng-enter='action == "login" && auth(action, user_info)')
+                        .details-row(ng-show='action == "register"')
+                            +lbl('Confirm:')
+                            .col-sm-9.input-tip.has-feedback
+                                input.form-control(type='password' ng-model='user_info.confirm' match='user_info.password' placeholder='Confirm password' required ng-enter='auth(action, user_info)')
+
+            .modal-footer
+                a.show-signup.ng-hide(ng-show='action != "login"' ng-click='action = "login";') log in
+                a.show-signup(ng-show='action != "register"' ng-click='action = "register"') sign up
+                | &nbsp;or&nbsp;
+                button.btn.btn-primary(ng-show='action == "login"' ng-click='auth(action, user_info)') Log In
+                button.btn.btn-primary(ng-show='action == "register"' ng-disabled='loginForm.$invalid || user_info.password != user_info.confirm' ng-click='auth(action, user_info)') Sign Up

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/control-center-web/src/main/js/views/settings/admin.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/views/settings/admin.jade b/modules/control-center-web/src/main/js/views/settings/admin.jade
new file mode 100644
index 0000000..8345bb9
--- /dev/null
+++ b/modules/control-center-web/src/main/js/views/settings/admin.jade
@@ -0,0 +1,58 @@
+//-
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+         http://www.apache.org/licenses/LICENSE-2.0
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+
+extends ../templates/layout
+
+append scripts
+    script(src='/admin-controller.js')
+
+block container
+    .row(ng-controller='adminController')
+        .docs-content
+            .docs-header
+                h1 List of registered users
+                hr
+            .docs-body
+                table.table.table-striped.admin(st-table='displayedUsers' st-safe-src='users')
+                    thead
+                        tr
+                            th.header(colspan='5')
+                                .col-sm-2.pull-right
+                                    input.form-control(type='text' st-search='' placeholder='Filter users...')
+                        tr
+                            th(st-sort='username') User name
+                            th(st-sort='email') Email
+                            th.col-sm-2(st-sort='lastLogin') Last login
+                            th(width='1%'  st-sort='admin') Admin
+                            th(width='1%') Actions
+                    tbody
+                        tr(ng-repeat='row in displayedUsers')
+                            td {{row.username}}
+                            td
+                                a(ng-href='mailto:{{row.email}}') {{row.email}}
+                            td
+                                span {{row.lastLogin | date:'medium'}}
+                            td(style='text-align: center;')
+                                input(type='checkbox' ng-disabled='row.adminChanging || row._id == user._id'
+                                    ng-model='row.admin' ng-change='toggleAdmin(row)')
+                            td(style='text-align: center;')
+                                a(ng-click='removeUser(row)' ng-show='row._id != user._id' bs-tooltip data-title='Remove user')
+                                    i.fa.fa-remove
+                                a(style='margin-left: 5px' ng-href='admin/become?viewedUserId={{row._id}}' ng-show='row._id != user._id' bs-tooltip data-title='Become this user')
+                                    i.fa.fa-eye
+                    tfoot
+                        tr
+                            td.text-right(colspan='5')
+                                div(st-pagination st-items-by-page='15' st-displayed-pages='5')
+

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/control-center-web/src/main/js/views/settings/profile.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/views/settings/profile.jade b/modules/control-center-web/src/main/js/views/settings/profile.jade
new file mode 100644
index 0000000..6ddcafa
--- /dev/null
+++ b/modules/control-center-web/src/main/js/views/settings/profile.jade
@@ -0,0 +1,58 @@
+//-
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+
+extends ../templates/layout
+
+mixin lbl(txt)
+    label.col-sm-2.required.labelFormField #{txt}
+
+append scripts
+    script(src='/profile-controller.js')
+
+block container
+    .row(ng-controller='profileController')
+        .docs-content
+            .docs-header
+                h1 User profile
+                hr
+            .docs-body
+                form.form-horizontal(name='profileForm' novalidate)
+                    .col-sm-10(style='padding: 0')
+                        .details-row
+                            +lbl('User name:')
+                            .col-sm-4
+                                input.form-control(type='text' ng-model='profileUser.username' placeholder='Input name' required)
+                        .details-row
+                            +lbl('Email:')
+                            .col-sm-4
+                                input.form-control(type='email' ng-model='profileUser.email' placeholder='you@domain.com' required)
+                        .details-row
+                            .checkbox
+                                label
+                                    input(type='checkbox' ng-model='profileUser.changePassword')
+                                    | Change password
+                        div(ng-show='profileUser.changePassword')
+                            .details-row
+                                +lbl('New password:')
+                                .col-sm-4
+                                    input.form-control(type='password' ng-model='profileUser.newPassword' placeholder='New password' ng-required='profileUser.changePassword')
+                            .details-row
+                                +lbl('Confirm:')
+                                .col-sm-4
+                                    input.form-control(type='password' ng-model='profileUser.confirmPassword' match='profileUser.newPassword' placeholder='Confirm new password' ng-required='profileUser.changePassword')
+                    .col-sm-12.details-row
+                        button.btn.btn-primary(ng-disabled='profileForm.$invalid' ng-click='saveUser()') Save
+

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/control-center-web/src/main/js/views/sql/sql.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/views/sql/sql.jade b/modules/control-center-web/src/main/js/views/sql/sql.jade
new file mode 100644
index 0000000..97d34de
--- /dev/null
+++ b/modules/control-center-web/src/main/js/views/sql/sql.jade
@@ -0,0 +1,85 @@
+//-
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+         http://www.apache.org/licenses/LICENSE-2.0
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+extends ../templates/layout
+
+append scripts
+    script(src='/sql-controller.js')
+
+    script(src='//cdnjs.cloudflare.com/ajax/libs/ace/1.2.0/theme-chrome.js')
+    script(src='//cdnjs.cloudflare.com/ajax/libs/ace/1.2.0/mode-sql.js')
+    script(src='//cdnjs.cloudflare.com/ajax/libs/ace/1.2.0/ext-language_tools.js')
+
+block container
+    .row
+        .col-sm-12
+            .docs-content
+                .docs-header
+                    h1 Connect to Ignite and Execute SQL Queries
+                    hr
+                .docs-body(ng-controller='sqlController')
+                    - var tab = 'tabs[tabs.activeIdx]'
+
+                    .block-callout-parent.block-callout-border.margin-bottom-dflt
+                        .block-callout
+                            p(ng-bind-html='joinTip(screenTip)')
+                    .tabs-below(bs-tabs bs-active-pane='tabs.activeIdx' data-template='/tab')
+                        div(ng-repeat='tab in tabs' title='Query' bs-pane)
+                    .row
+                        .col-sm-9(style='border-right: 1px solid #eee')
+                            div(style='height: 200px' ui-ace='{ theme: "chrome", mode: "sql",' +
+                                'require: ["ace/ext/language_tools"],' +
+                                'rendererOptions: {showPrintMargin: false, highlightGutterLine: false, fontSize: 14},' +
+                                'advanced: {enableSnippets: false, enableBasicAutocompletion: true, enableLiveAutocompletion: true}}' ng-model='#{tab}.query')
+                        .col-sm-3
+                            div(ng-hide='caches.length == 0' style='margin-top: 0.65em')
+                                lable.labelHeader Caches:
+                                table.links(st-table='caches')
+                                    tbody
+                                        tr(ng-repeat='row in caches track by row._id')
+                                            td.col-sm-6(ng-class='{active: row._id == #{tab}.selectedItem._id}')
+                                                a(ng-click='#{tab}.selectedItem = row') {{$index + 1}}) {{row.name}}, {{row.mode | displayValue:modes:'Cache mode not set'}}
+                    hr(style='margin: 0')
+                    .settings-row
+                        label Page Size:&nbsp;
+                        button.btn.btn-default.base-control(ng-init='pageSize = pageSizes[0]' ng-model='pageSize' bs-options='item for item in pageSizes' bs-select)
+                    .settings-row
+                        button.btn.btn-primary(ng-click='') Explain
+                        button.btn.btn-primary(ng-click='') Execute
+                        button.btn.btn-primary(ng-click='' disabled) Scan
+
+                    div(ng-show='#{tab}.rows.length > 0' style='margin-top: 0.65em')
+                        hr
+                        div
+                            table.table.table-striped.col-sm-12.sql-results(st-table='rows' st-safe-src='#{tab}.rows')
+                                thead
+                                    tr(style='border-size: 0')
+                                        td(colspan='{{#{tab}.cols.length}}')
+                                            .col-sm-8
+                                                lable Page #:&nbsp;
+                                                b {{#{tab}.page}}&nbsp;&nbsp;&nbsp;
+                                                | Results:&nbsp;
+                                                b {{#{tab}.rows.length + #{tab}.total}}
+                                            .col-sm-4
+                                                button.btn.btn-primary.fieldButton(ng-click='') Next page
+                                                .input-tip
+                                                    input.form-control(type='text' st-search='' placeholder='Filter...')
+
+                                    tr
+                                        th(ng-repeat='column in #{tab}.cols' st-sort='{{column}}') {{column}}
+                                tbody
+                                    //tr
+                                    //    td(colspan='{{#{tab}.cols.length}}')
+                                    //        .loading-indicator
+                                    tr(ng-repeat='row in rows')
+                                        td(ng-repeat='column in #{tab}.cols') {{row[column]}}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/control-center-web/src/main/js/views/templates/confirm.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/views/templates/confirm.jade b/modules/control-center-web/src/main/js/views/templates/confirm.jade
new file mode 100644
index 0000000..949318a
--- /dev/null
+++ b/modules/control-center-web/src/main/js/views/templates/confirm.jade
@@ -0,0 +1,27 @@
+//-
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+
+.modal(tabindex='-1' role='dialog')
+    .modal-dialog
+        .modal-content
+            .modal-header
+                button.close(type='button' ng-click='$hide()') &times;
+                h4.modal-title Confirmation
+            .modal-body(ng-show='content')
+                p(ng-bind-html='content' style='text-align: center;')
+            .modal-footer
+                button.btn.btn-default(type='button' ng-click='$hide()') Cancel
+                button.btn.btn-primary(type='button' ng-click='ok()') Confirm
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/control-center-web/src/main/js/views/templates/copy.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/views/templates/copy.jade b/modules/control-center-web/src/main/js/views/templates/copy.jade
new file mode 100644
index 0000000..2ba9096
--- /dev/null
+++ b/modules/control-center-web/src/main/js/views/templates/copy.jade
@@ -0,0 +1,31 @@
+//-
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+
+.modal(tabindex='-1' role='dialog')
+    .modal-dialog
+        .modal-content
+            .modal-header
+                button.close(type='button' ng-click='$hide()') &times;
+                h4.modal-title Copy
+            form.form-horizontal(name='inputForm' novalidate)
+                .modal-body.row
+                    .col-sm-9.login.col-sm-offset-1
+                        label.required.labelFormField() New name:&nbsp;
+                        .col-sm-9
+                            input.form-control(type='text' ng-model='newName' required)
+            .modal-footer
+                button.btn.btn-default(type='button' ng-click='$hide()') Cancel
+                button.btn.btn-primary(type='button' ng-disabled='inputForm.$invalid' ng-click='ok(newName)') Confirm
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/control-center-web/src/main/js/views/templates/layout.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/views/templates/layout.jade b/modules/control-center-web/src/main/js/views/templates/layout.jade
new file mode 100644
index 0000000..71d8936
--- /dev/null
+++ b/modules/control-center-web/src/main/js/views/templates/layout.jade
@@ -0,0 +1,61 @@
+//-
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+
+doctype html
+html(ng-app='ignite-web-control-center' ng-init='user = #{JSON.stringify(user)}; becomeUsed = #{becomeUsed}')
+    head
+        title= title
+
+        block css
+            // Bootstrap
+            link(rel='stylesheet', href='//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.4/css/bootstrap.css')
+
+            // Font Awesome Icons
+            link(rel='stylesheet', href='//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.css')
+
+            // Font
+            link(rel='stylesheet', href='//fonts.googleapis.com/css?family=Roboto+Slab:700:serif|Roboto+Slab:400:serif')
+
+            link(rel='stylesheet', href='/stylesheets/style.css')
+
+        block scripts
+            script(src='//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.js')
+
+            script(src='//cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.0/lodash.min.js')
+
+            script(src='//ajax.googleapis.com/ajax/libs/angularjs/1.4.2/angular.js')
+            script(src='//cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.2/angular-sanitize.js')
+            script(src='//cdnjs.cloudflare.com/ajax/libs/angular-strap/2.3.0/angular-strap.js')
+            script(src='//cdnjs.cloudflare.com/ajax/libs/angular-strap/2.3.0/angular-strap.tpl.min.js')
+
+            script(src='//cdnjs.cloudflare.com/ajax/libs/angular-smart-table/2.0.3/smart-table.js')
+
+            script(src='//cdnjs.cloudflare.com/ajax/libs/ace/1.2.0/ace.js')
+            script(src='//angular-ui.github.io/ui-ace/dist/ui-ace.min.js')
+
+            script(src='/common-module.js')
+            script(src='/data-structures.js')
+
+    body.theme-line.body-overlap.greedy
+        .wrapper
+            include ../includes/header
+
+            block main-container
+                .container.body-container
+                    .main-content
+                        block container
+
+            include ../includes/footer

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/control-center-web/src/main/js/views/templates/select.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/views/templates/select.jade b/modules/control-center-web/src/main/js/views/templates/select.jade
new file mode 100644
index 0000000..b219f13
--- /dev/null
+++ b/modules/control-center-web/src/main/js/views/templates/select.jade
@@ -0,0 +1,26 @@
+//-
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+
+ul.select.dropdown-menu(tabindex='-1' ng-show='$isVisible()' role='select')
+    li(role='presentation' ng-repeat='match in $matches')
+        hr(ng-if='match.value == undefined' style='margin: 5px 0')
+        a(style='cursor: default; padding: 3px 6px;' role='menuitem' tabindex='-1' ng-class='{active: $isActive($index)}' ng-click='$select($index, $event)')
+            i(class='{{$iconCheckmark}}' ng-if='$isActive($index)' ng-class='{active: $isActive($index)}' style='color: #ec1c24; margin-left: 15px; line-height: 20px; float: right;background-color: transparent;')
+            span(ng-bind='match.label')
+    li(ng-if='$showAllNoneButtons || ($isMultiple && $matches.length > 5)')
+        hr(style='margin: 5px 0')
+        a(ng-click='$selectAll()') {{$allText}}
+        a(ng-click='$selectNone()') {{$noneText}}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/control-center-web/src/main/js/views/templates/tab.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/views/templates/tab.jade b/modules/control-center-web/src/main/js/views/templates/tab.jade
new file mode 100644
index 0000000..6c7afc5
--- /dev/null
+++ b/modules/control-center-web/src/main/js/views/templates/tab.jade
@@ -0,0 +1,26 @@
+//-
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+
+ul.nav(ng-class='$navClass', role='tablist')
+    li(role='presentation' ng-repeat='$pane in $panes track by $index' ng-class='[ $isActive($pane, $index) ? $activeClass : "", $pane.disabled ? "disabled" : "" ]')
+        a(ng-if='$index == 0' role='tab' data-toggle='tab' ng-click='!$pane.disabled && $setActive($pane.name || $index)' data-index='{{ $index }}' aria-controls='$pane.title') {{$pane.title}}
+            i.fa.fa-remove(ng-click='removeTab($index)' ng-if='$index > 0' style='margin-left: 5px')
+        a(ng-if='$index > 0' role='tab' data-toggle='tab' ng-click='!$pane.disabled && $setActive($pane.name || $index)' data-index='{{ $index }}' aria-controls='$pane.title') {{$pane.title}}: {{$index}}
+            i.fa.fa-remove(ng-click='removeTab($index)' style='margin-left: 5px')
+    li.pull-right(bs-tooltip data-title='Add new query')
+        a(role='tab' data-toggle='tab' ng-click='addTab()')
+            i.fa.fa-plus
+.tab-content(ng-transclude)

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/web-control-center/licenses/apache-2.0.txt
----------------------------------------------------------------------
diff --git a/modules/web-control-center/licenses/apache-2.0.txt b/modules/web-control-center/licenses/apache-2.0.txt
deleted file mode 100644
index d645695..0000000
--- a/modules/web-control-center/licenses/apache-2.0.txt
+++ /dev/null
@@ -1,202 +0,0 @@
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "[]"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright [yyyy] [name of copyright owner]
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/web-control-center/src/main/js/.gitignore
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/.gitignore b/modules/web-control-center/src/main/js/.gitignore
deleted file mode 100644
index 65f2596..0000000
--- a/modules/web-control-center/src/main/js/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-node_modules
-*.idea
-*.log
-*.css
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/web-control-center/src/main/js/DEVNOTES.txt
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/DEVNOTES.txt b/modules/web-control-center/src/main/js/DEVNOTES.txt
deleted file mode 100644
index e8c558c..0000000
--- a/modules/web-control-center/src/main/js/DEVNOTES.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-Ignite Web Control Center Instructions
-======================================
-
-How to deploy:
-
-1. Install locally NodeJS using installer from site https://nodejs.org for your OS.
-2. Install locally MongoDB folow instructions from site http://docs.mongodb.org/manual/installation
-3. Checkout ignite-843 branch.
-4. Change directory '$IGNITE_HOME/modules/web-control-center/src/main/js'.
-5. Run "npm install" in terminal for download all dependencies.
-
-Steps 1 - 5 should be executed once.
-
-How to run:
-
-1. Run MongoDB.
- 1.1 In terminal change dir to $MONGO_ISNTALL_DIR/server/3.0/bin.
- 1.2 Run "mongod".
-2. In new terminal change directory '$IGNITE_HOME/modules/web-control-center/src/main/js'.
-3. Start application by executing "npm start".
-4. In browser open: http://localhost:3000
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/web-control-center/src/main/js/app.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/app.js b/modules/web-control-center/src/main/js/app.js
deleted file mode 100644
index a67afc8..0000000
--- a/modules/web-control-center/src/main/js/app.js
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-var flash = require('connect-flash');
-var express = require('express');
-var path = require('path');
-var favicon = require('serve-favicon');
-var logger = require('morgan');
-var cookieParser = require('cookie-parser');
-var bodyParser = require('body-parser');
-var session = require('express-session');
-var mongoStore = require('connect-mongo')(session);
-
-var publicRoutes = require('./routes/public');
-var clustersRouter = require('./routes/clusters');
-var cachesRouter = require('./routes/caches');
-var metadataRouter = require('./routes/metadata');
-var summary = require('./routes/summary');
-var adminRouter = require('./routes/admin');
-var profileRouter = require('./routes/profile');
-var sqlRouter = require('./routes/sql');
-
-var passport = require('passport');
-
-var db = require('./db');
-
-var app = express();
-
-// Views engine setup.
-app.set('views', path.join(__dirname, 'views'));
-app.set('view engine', 'jade');
-
-// Site favicon.
-app.use(favicon(__dirname + '/public/favicon.ico'));
-
-app.use(logger('dev'));
-
-app.use(bodyParser.json());
-app.use(bodyParser.urlencoded({extended: false}));
-
-app.use(require('node-sass-middleware')({
-    /* Options */
-    src: path.join(__dirname, 'public'),
-    dest: path.join(__dirname, 'public'),
-    debug: true,
-    outputStyle: 'nested'
-}));
-
-app.use(express.static(path.join(__dirname, 'public')));
-app.use(express.static(path.join(__dirname, 'controllers')));
-app.use(express.static(path.join(__dirname, 'helpers')));
-
-app.use(cookieParser('keyboard cat'));
-
-app.use(session({
-    secret: 'keyboard cat',
-    resave: false,
-    saveUninitialized: true,
-    store: new mongoStore({
-        mongooseConnection: db.mongoose.connection
-    })
-}));
-
-app.use(flash());
-
-app.use(passport.initialize());
-app.use(passport.session());
-
-passport.serializeUser(db.Account.serializeUser());
-passport.deserializeUser(db.Account.deserializeUser());
-
-passport.use(db.Account.createStrategy());
-
-var mustAuthenticated = function (req, res, next) {
-    req.isAuthenticated() ? next() : res.redirect('/');
-};
-
-var adminOnly = function(req, res, next) {
-    req.isAuthenticated() && req.user.admin ? next() : res.sendStatus(403);
-};
-
-app.all('/configuration/*', mustAuthenticated);
-
-app.all('*', function(req, res, next) {
-    var becomeUsed = req.session.viewedUser && req.user.admin;
-
-    res.locals.user = becomeUsed ? req.session.viewedUser : req.user;
-    res.locals.becomeUsed = becomeUsed;
-
-    req.currentUserId = function() {
-        if (!req.user)
-            return null;
-
-        if (req.session.viewedUser && req.user.admin)
-            return req.session.viewedUser._id;
-
-        return req.user._id;
-    };
-
-    next();
-});
-
-app.use('/', publicRoutes);
-app.use('/admin', mustAuthenticated, adminOnly, adminRouter);
-app.use('/profile', mustAuthenticated, profileRouter);
-
-app.use('/configuration/clusters', clustersRouter);
-app.use('/configuration/caches', cachesRouter);
-app.use('/configuration/metadata', metadataRouter);
-app.use('/configuration/summary', summary);
-app.use('/sql', sqlRouter);
-
-// Catch 404 and forward to error handler.
-app.use(function (req, res, next) {
-    var err = new Error('Not Found: ' + req.originalUrl);
-    err.status = 404;
-    next(err);
-});
-
-// Error handlers.
-
-// Development error handler: will print stacktrace.
-if (app.get('env') === 'development') {
-    app.use(function (err, req, res) {
-        res.status(err.status || 500);
-        res.render('error', {
-            message: err.message,
-            error: err
-        });
-    });
-}
-
-// Production error handler: no stacktraces leaked to user.
-app.use(function (err, req, res) {
-    res.status(err.status || 500);
-    res.render('error', {
-        message: err.message,
-        error: {}
-    });
-});
-
-module.exports = app;

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/web-control-center/src/main/js/bin/www
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/bin/www b/modules/web-control-center/src/main/js/bin/www
deleted file mode 100644
index 4cf0583..0000000
--- a/modules/web-control-center/src/main/js/bin/www
+++ /dev/null
@@ -1,85 +0,0 @@
-#!/usr/bin/env node
-
-/**
- * Module dependencies.
- */
-var app = require('../app');
-var config = require('../helpers/configuration-loader.js');
-var debug = require('debug')('ignite-web-control-center:server');
-var http = require('http');
-
-/**
- * Get port from environment and store in Express.
- */
-var port = normalizePort(process.env.PORT || config.get('express:port'));
-app.set('port', port);
-
-/**
- * Create HTTP server.
- */
-var server = http.createServer(app);
-
-/**
- * Listen on provided port, on all network interfaces.
- */
-server.listen(port);
-server.on('error', onError);
-server.on('listening', onListening);
-
-/**
- * Normalize a port into a number, string, or false.
- */
-function normalizePort(val) {
-  var port = parseInt(val, 10);
-
-  if (isNaN(port)) {
-    // named pipe
-    return val;
-  }
-
-  if (port >= 0) {
-    // port number
-    return port;
-  }
-
-  return false;
-}
-
-/**
- * Event listener for HTTP server "error" event.
- */
-function onError(error) {
-  if (error.syscall !== 'listen') {
-    throw error;
-  }
-
-  var bind = typeof port === 'string'
-    ? 'Pipe ' + port
-    : 'Port ' + port;
-
-  // handle specific listen errors with friendly messages
-  switch (error.code) {
-    case 'EACCES':
-      console.error(bind + ' requires elevated privileges');
-      process.exit(1);
-      break;
-    case 'EADDRINUSE':
-      console.error(bind + ' is already in use');
-      process.exit(1);
-      break;
-    default:
-      throw error;
-  }
-}
-
-/**
- * Event listener for HTTP server "listening" event.
- */
-function onListening() {
-  var addr = server.address();
-  var bind = typeof addr === 'string'
-    ? 'pipe ' + addr
-    : 'port ' + addr.port;
-
-  debug('Listening on ' + bind);
-}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/web-control-center/src/main/js/config/default.json
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/config/default.json b/modules/web-control-center/src/main/js/config/default.json
deleted file mode 100644
index 72dbd4e..0000000
--- a/modules/web-control-center/src/main/js/config/default.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
-    "express": {
-        "port": 3000
-    },
-    "mongoDB": {
-        "url": "mongodb://localhost/web-control-center"
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/web-control-center/src/main/js/controllers/admin-controller.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/controllers/admin-controller.js b/modules/web-control-center/src/main/js/controllers/admin-controller.js
deleted file mode 100644
index 09490fe..0000000
--- a/modules/web-control-center/src/main/js/controllers/admin-controller.js
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-controlCenterModule.controller('adminController', ['$scope', '$http', '$common', '$confirm', function ($scope, $http, $common, $confirm) {
-    $scope.users = null;
-
-    function reload() {
-        $http.post('admin/list')
-            .success(function (data) {
-                $scope.users = data;
-            })
-            .error(function (errMsg) {
-                $common.showError($common.errorMessage(errMsg));
-            });
-    }
-
-    reload();
-
-    $scope.removeUser = function (user) {
-        $confirm.show('Are you sure you want to remove user: "' + user.username + '"?').then(function () {
-            $http.post('admin/remove', {userId: user._id}).success(
-                function () {
-                    var i = _.findIndex($scope.users, function (u) {
-                        return u._id == user._id;
-                    });
-
-                    if (i >= 0)
-                        $scope.users.splice(i, 1);
-
-                    $common.showInfo('User has been removed: "' + user.username + '"');
-                }).error(function (errMsg) {
-                    $common.showError('Failed to remove user: "' + $common.errorMessage(errMsg) + '"');
-                });
-        });
-    };
-
-    $scope.toggleAdmin = function (user) {
-        if (user.adminChanging)
-            return;
-
-        user.adminChanging = true;
-
-        $http.post('admin/save', {userId: user._id, adminFlag: user.admin}).success(
-            function () {
-                $common.showInfo('Admin right was successfully toggled for user: "' + user.username + '"');
-
-                user.adminChanging = false;
-            }).error(function (errMsg) {
-                $common.showError('Failed to toggle admin right for user: "' + $common.errorMessage(errMsg) + '"');
-
-                user.adminChanging = false;
-            });
-    }
-}]);
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/web-control-center/src/main/js/controllers/cache-viewer-controller.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/controllers/cache-viewer-controller.js b/modules/web-control-center/src/main/js/controllers/cache-viewer-controller.js
deleted file mode 100644
index 6e0c130..0000000
--- a/modules/web-control-center/src/main/js/controllers/cache-viewer-controller.js
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-var demoResults = [
-    {
-        id: 256,
-        s: 'com.foo.User@3213',
-        fields: {
-            id: 256,
-            firstName: 'Ivan',
-            lastName: 'Ivanov',
-            old: 23
-        }
-    },
-
-    {
-        id: 384,
-        s: 'com.foo.User@23214',
-        fields: {
-            id: 384,
-            firstName: 'Sergey',
-            lastName: 'Petrov',
-            old: 28
-        }
-    },
-
-    {
-        id: 923,
-        s: 'com.foo.User@93494',
-        fields: {
-            id: 923,
-            firstName: 'Andrey',
-            lastName: 'Sidorov',
-            old: 28
-        }
-    }
-];
-
-var demoCaches = ['Users', 'Organizations', 'Cities'];
-
-controlCenterModule.controller('cacheViewerController', ['$scope', '$http', '$common', function ($scope, $http, $common) {
-    $scope.results = demoResults;
-
-    $scope.caches = demoCaches;
-
-    $scope.defCache = $scope.caches.length > 0 ? $scope.caches[0] : null;
-
-    var sqlEditor = ace.edit('querySql');
-
-    sqlEditor.setOptions({
-        highlightActiveLine: false,
-        showPrintMargin: false,
-        showGutter: true,
-        theme: "ace/theme/chrome",
-        mode: "ace/mode/sql",
-        fontSize: 14
-    });
-
-    sqlEditor.setValue("select u.id from User u where u.name like 'aaaa';");
-
-    sqlEditor.selection.clearSelection()
-
-}]);



[22/41] incubator-ignite git commit: IGNITE-843 Added support for set focus to specified control.

Posted by an...@apache.org.
IGNITE-843 Added support for set focus to specified control.


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

Branch: refs/heads/ignite-1121
Commit: 2e4daaa83271659e01698ae094e6367cd93624ab
Parents: b90a6d7
Author: AKuznetsov <ak...@gridgain.com>
Authored: Wed Jul 29 01:01:11 2015 +0700
Committer: AKuznetsov <ak...@gridgain.com>
Committed: Wed Jul 29 01:01:11 2015 +0700

----------------------------------------------------------------------
 .../src/main/js/controllers/common-module.js    | 29 +++++++
 .../src/main/js/controllers/models/caches.json  |  7 +-
 .../main/js/controllers/models/clusters.json    | 20 ++---
 .../main/js/controllers/models/metadata.json    | 14 +++-
 .../src/main/js/views/configuration/caches.jade |  4 +-
 .../main/js/views/configuration/clusters.jade   |  4 +-
 .../main/js/views/configuration/metadata.jade   |  4 +-
 .../src/main/js/views/includes/controls.jade    | 84 ++++++++++----------
 8 files changed, 102 insertions(+), 64 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/2e4daaa8/modules/web-control-center/src/main/js/controllers/common-module.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/controllers/common-module.js b/modules/web-control-center/src/main/js/controllers/common-module.js
index 8f31397..df2ff19 100644
--- a/modules/web-control-center/src/main/js/controllers/common-module.js
+++ b/modules/web-control-center/src/main/js/controllers/common-module.js
@@ -406,6 +406,35 @@ controlCenterModule.directive('ngEscape', function() {
     };
 });
 
+// Factory function to focus element.
+controlCenterModule.factory('focus', function ($timeout, $window) {
+    return function (id) {
+        // Timeout makes sure that is invoked after any other event has been triggered.
+        // E.g. click events that need to run before the focus or inputs elements that are
+        // in a disabled state but are enabled when those events are triggered.
+        $timeout(function () {
+            var element = $window.document.getElementById(id);
+
+            if (element)
+                element.focus();
+        });
+    };
+});
+
+// Directive to mark elements to focus.
+controlCenterModule.directive('eventFocus', function (focus) {
+    return function (scope, elem, attr) {
+        elem.on(attr.eventFocus, function () {
+            focus(attr.eventFocusId);
+        });
+
+        // Removes bound events in the element itself when the scope is destroyed
+        scope.$on('$destroy', function () {
+            element.off(attr.eventFocus);
+        });
+    };
+});
+
 // Navigation bar controller.
 controlCenterModule.controller('activeLink', [
     '$scope', function ($scope) {

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/2e4daaa8/modules/web-control-center/src/main/js/controllers/models/caches.json
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/controllers/models/caches.json b/modules/web-control-center/src/main/js/controllers/models/caches.json
index 6f334d2..932eecc 100644
--- a/modules/web-control-center/src/main/js/controllers/models/caches.json
+++ b/modules/web-control-center/src/main/js/controllers/models/caches.json
@@ -22,7 +22,8 @@
       "type": "text",
       "model": "name",
       "required": true,
-      "placeholder": "Input name"
+      "placeholder": "Input name",
+      "id": "defaultFocusId"
     },
     {
       "label": "Mode",
@@ -386,6 +387,8 @@
           "model": "indexedTypes",
           "keyName": "keyClass",
           "valueName": "valueClass",
+          "focusNewItemId": "newIndexedType",
+          "focusCurItemId": "curIndexedType",
           "addTip": "Add new key and value classes to indexed types.",
           "removeTip": "Remove item from indexed types.",
           "tip": [
@@ -398,6 +401,8 @@
           "model": "sqlFunctionClasses",
           "editIdx": -1,
           "placeholder": "SQL function full class name",
+          "focusNewItemId": "newSqlFxField",
+          "focusCurItemId": "curSqlFxField",
           "addTip": "Add new user-defined functions for SQL queries.",
           "removeTip": "Remove user-defined function.",
           "tableTip": [

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/2e4daaa8/modules/web-control-center/src/main/js/controllers/models/clusters.json
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/controllers/models/clusters.json b/modules/web-control-center/src/main/js/controllers/models/clusters.json
index 0ffb1b3..36d0dd8 100644
--- a/modules/web-control-center/src/main/js/controllers/models/clusters.json
+++ b/modules/web-control-center/src/main/js/controllers/models/clusters.json
@@ -29,7 +29,8 @@
       "type": "text",
       "model": "name",
       "required": true,
-      "placeholder": "Input name"
+      "placeholder": "Input name",
+      "id": "defaultFocusId"
     },
     {
       "label": "Caches",
@@ -68,6 +69,8 @@
               "reordering": true,
               "ipaddress": true,
               "placeholder": "IP address:port",
+              "focusNewItemId": "newIpAddress",
+              "focusCurItemId": "curIpAddress",
               "addTip": "Add new address.",
               "removeTip": "Remove address.",
               "tip": [
@@ -157,7 +160,6 @@
               "required": true,
               "path": "discovery.S3",
               "model": "bucketName",
-              "placeholder": "",
               "tip": [
                 "Bucket name for IP finder."
               ]
@@ -176,7 +178,6 @@
               "type": "text",
               "path": "discovery.Cloud",
               "model": "credential",
-              "placeholder": "",
               "tip": [
                 "Credential that is used during authentication on the cloud.",
                 "Depending on a cloud platform it can be a password or access key."
@@ -187,7 +188,6 @@
               "type": "text",
               "path": "discovery.Cloud",
               "model": "credentialPath",
-              "placeholder": "",
               "tip": [
                 "Path to a credential that is used during authentication on the cloud.",
                 "Access key or private key should be stored in a plain or PEM file without a passphrase."
@@ -199,7 +199,6 @@
               "required": true,
               "path": "discovery.Cloud",
               "model": "identity",
-              "placeholder": "",
               "tip": [
                 "Identity that is used as a user name during a connection to the cloud.",
                 "Depending on a cloud platform it can be an email address, user name, etc."
@@ -211,7 +210,6 @@
               "required": true,
               "path": "discovery.Cloud",
               "model": "provider",
-              "placeholder": "",
               "tip": [
                 "Cloud provider to use."
               ]
@@ -222,7 +220,8 @@
               "path": "discovery.Cloud",
               "model": "regions",
               "editIdx": -1,
-              "placeholder": "",
+              "focusNewItemId": "newRegion",
+              "focusCurItemId": "curRegion",
               "addTip": "Add new region.",
               "removeTip": "Remove region.",
               "tableTip": [
@@ -240,7 +239,8 @@
               "path": "discovery.Cloud",
               "model": "zones",
               "editIdx": -1,
-              "placeholder": "",
+              "focusNewItemId": "newZone",
+              "focusCurItemId": "curZone",
               "addTip": "Add new zone.",
               "removeTip": "Remove zone.",
               "tableTip": [
@@ -263,7 +263,6 @@
               "required": true,
               "path": "discovery.GoogleStorage",
               "model": "projectName",
-              "placeholder": "",
               "tip": [
                 "Google Cloud Platforms project name.",
                 "Usually this is an auto generated project number (ex. 208709979073) that can be found in 'Overview' section of Google Developer Console."
@@ -275,7 +274,6 @@
               "required": true,
               "path": "discovery.GoogleStorage",
               "model": "bucketName",
-              "placeholder": "",
               "tip": [
                 "Google Cloud Storage bucket name.",
                 "If the bucket doesn't exist Ignite will automatically create it.",
@@ -288,7 +286,6 @@
               "required": true,
               "path": "discovery.GoogleStorage",
               "model": "serviceAccountP12FilePath",
-              "placeholder": "",
               "tip": [
                 "Full path to the private key in PKCS12 format of the Service Account."
               ]
@@ -299,7 +296,6 @@
               "required": true,
               "path": "discovery.GoogleStorage",
               "model": "accountId",
-              "placeholder": "",
               "tip": [
                 "Service account ID (typically an e-mail address)."
               ]

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/2e4daaa8/modules/web-control-center/src/main/js/controllers/models/metadata.json
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/controllers/models/metadata.json b/modules/web-control-center/src/main/js/controllers/models/metadata.json
index 85ac5aa..a9b60de 100644
--- a/modules/web-control-center/src/main/js/controllers/models/metadata.json
+++ b/modules/web-control-center/src/main/js/controllers/models/metadata.json
@@ -30,7 +30,8 @@
       "type": "text",
       "model": "name",
       "required": true,
-      "placeholder": "Input name"
+      "placeholder": "Input name",
+      "id": "defaultFocusId"
     },
     {
       "label": "Metadata for",
@@ -119,6 +120,8 @@
       "keyName": "name",
       "valueName": "className",
       "hide": "backupItem.kind != 'both' && backupItem.kind != 'query'",
+      "focusNewItemId": "newQryField",
+      "focusCurItemId": "curQryField",
       "addTip": "Add field to query.",
       "removeTip": "Remove field.",
       "tip": [
@@ -132,6 +135,8 @@
       "keyName": "name",
       "valueName": "className",
       "hide": "backupItem.kind != 'both' && backupItem.kind != 'query'",
+      "focusNewItemId": "newAscField",
+      "focusCurItemId": "curAscField",
       "addTip": "Add field to index in ascending order.",
       "removeTip": "Remove field.",
       "tip": [
@@ -145,6 +150,8 @@
       "keyName": "name",
       "valueName": "className",
       "hide": "backupItem.kind != 'both' && backupItem.kind != 'query'",
+      "focusNewItemId": "newDescField",
+      "focusCurItemId": "curDescField",
       "addTip": "Add field to index in descending order.",
       "removeTip": "Remove field.",
       "tip": [
@@ -157,6 +164,8 @@
       "model": "textFields",
       "hide": "backupItem.kind != 'both' && backupItem.kind != 'query'",
       "placeholder": "Field name",
+      "focusNewItemId": "newTextField",
+      "focusCurItemId": "curTextField",
       "addTip": "Add field to index as text.",
       "removeTip": "Remove field.",
       "tableTip": [
@@ -218,7 +227,6 @@
       "type": "number",
       "model": "port",
       "max": 65535,
-      "placeholder": "",
       "tip": [
         "Port number for connecting to database."
       ]
@@ -227,7 +235,6 @@
       "label": "User",
       "type": "text",
       "model": "user",
-      "placeholder": "",
       "tip": [
         "User name for connecting to database."
       ]
@@ -236,7 +243,6 @@
       "label": "Password",
       "type": "password",
       "model": "password",
-      "placeholder": "",
       "tip": [
         "Password for connecting to database.",
         "Note, password would not be saved."

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/2e4daaa8/modules/web-control-center/src/main/js/views/configuration/caches.jade
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/views/configuration/caches.jade b/modules/web-control-center/src/main/js/views/configuration/caches.jade
index 579b5aa..15d8f40 100644
--- a/modules/web-control-center/src/main/js/views/configuration/caches.jade
+++ b/modules/web-control-center/src/main/js/views/configuration/caches.jade
@@ -34,9 +34,9 @@ block content
                     tbody
                         tr(ng-repeat='row in caches track by row._id')
                             td.col-sm-6(ng-class='{active: row._id == selectedItem._id}')
-                                a(ng-click='selectItem(row)') {{$index + 1}}) {{row.name}}, {{row.mode | displayValue:modes:'Cache mode not set'}}, {{row.atomicityMode | displayValue:atomicities:'Cache atomicity not set'}}
+                                a(event-focus='click' event-focus-id='defaultFocusId' ng-click='selectItem(row)') {{$index + 1}}) {{row.name}}, {{row.mode | displayValue:modes:'Cache mode not set'}}, {{row.atomicityMode | displayValue:atomicities:'Cache atomicity not set'}}
         .padding-top-dflt
-            button.btn.btn-primary(ng-click='createItem()') Add cache
+            button.btn.btn-primary(event-focus='click' event-focus-id='defaultFocusId' ng-click='createItem()') Add cache
         hr
         form.form-horizontal(name='inputForm' ng-if='backupItem' novalidate)
             div(bs-collapse data-start-collapsed='false')

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/2e4daaa8/modules/web-control-center/src/main/js/views/configuration/clusters.jade
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/views/configuration/clusters.jade b/modules/web-control-center/src/main/js/views/configuration/clusters.jade
index 882a2b9..239a31f 100644
--- a/modules/web-control-center/src/main/js/views/configuration/clusters.jade
+++ b/modules/web-control-center/src/main/js/views/configuration/clusters.jade
@@ -34,9 +34,9 @@ block content
                     tbody
                         tr(ng-repeat='row in clusters track by row._id')
                             td.col-sm-6(ng-class='{active: row._id == selectedItem._id}')
-                                a(ng-click='selectItem(row)') {{$index + 1}}) {{row.name}}, {{row.discovery.kind | displayValue:discoveries:'Discovery not set'}}
+                                a(event-focus='click' event-focus-id='defaultFocusId' ng-click='selectItem(row)') {{$index + 1}}) {{row.name}}, {{row.discovery.kind | displayValue:discoveries:'Discovery not set'}}
         .padding-top-dflt
-            button.btn.btn-primary(ng-click='createItem()') &nbspAdd cluster
+            button.btn.btn-primary(event-focus='click' event-focus-id='defaultFocusId' ng-click='createItem()') &nbspAdd cluster
             label(style='margin-left: 10px; margin-right: 10px') Use template:
             button.btn.btn-default.base-control(ng-init='create.template = templates[0].value' ng-model='create.template' data-template='/select' data-placeholder='Choose cluster template' bs-options='item.value as item.label for item in templates' bs-select)
             i.tiplabel.fa.fa-question-circle(bs-tooltip data-title='{{joinTip(templateTip)}}' type='button')

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/2e4daaa8/modules/web-control-center/src/main/js/views/configuration/metadata.jade
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/views/configuration/metadata.jade b/modules/web-control-center/src/main/js/views/configuration/metadata.jade
index e01eaa8..e0cc76f 100644
--- a/modules/web-control-center/src/main/js/views/configuration/metadata.jade
+++ b/modules/web-control-center/src/main/js/views/configuration/metadata.jade
@@ -34,9 +34,9 @@ block content
                     tbody
                         tr(ng-repeat='row in metadatas track by row._id')
                             td.col-sm-6(ng-class='{active: row._id == selectedItem._id}')
-                                a(ng-click='selectItem(row)') {{$index + 1}}) {{row.name}}
+                                a(event-focus='click' event-focus-id='defaultFocusId' ng-click='selectItem(row)') {{$index + 1}}) {{row.name}}
         .padding-top-dflt
-            button.btn.btn-primary(ng-click='panels.activePanel = [0]; createItem()') &nbspAdd metadata
+            button.btn.btn-primary(event-focus='click' event-focus-id='defaultFocusId' ng-click='panels.activePanel = [0]; createItem()') &nbspAdd metadata
             label(style='margin-left: 6px; margin-right: 10px') For:
             button.btn.btn-default(ng-model='template' data-template='/select' data-placeholder='Choose metadata type' bs-options='item.value as item.label for item in templates' bs-select)
             i.tiplabel.fa.fa-question-circle(bs-tooltip data-title='{{joinTip(templateTip)}}' type='button')

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/2e4daaa8/modules/web-control-center/src/main/js/views/includes/controls.jade
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/views/includes/controls.jade b/modules/web-control-center/src/main/js/views/includes/controls.jade
index 94cdda4..e9fe71b 100644
--- a/modules/web-control-center/src/main/js/views/includes/controls.jade
+++ b/modules/web-control-center/src/main/js/views/includes/controls.jade
@@ -40,8 +40,8 @@ mixin ico-exclamation(mdl, err, msg)
 mixin btn-save(show, click)
     i.tipField.fa.fa-floppy-o(ng-show=show ng-click=click bs-tooltip data-title='Save item')
 
-mixin btn-add(click, tip)
-    i.tipField.fa.fa-plus(ng-click=click bs-tooltip=tip)
+mixin btn-add(click, tip, focusId)
+    i.tipField.fa.fa-plus(ng-click=click bs-tooltip=tip event-focus='click' event-focus-id=focusId)
 
 mixin btn-remove(click, tip)
     i.tipField.fa.fa-remove(ng-click=click bs-tooltip=tip data-trigger='hover')
@@ -52,7 +52,7 @@ mixin btn-up(show, click)
 mixin btn-down(show, click)
     i.tipField.fa.fa-arrow-down(ng-show=show ng-click=click bs-tooltip data-title='Move item down')
 
-mixin table-pair-edit(keyModel, valModel, keyPlaceholder, valPlaceholder, keyJavaBuildInTypes, valueJavaBuildInTypes)
+mixin table-pair-edit(keyModel, valModel, keyPlaceholder, valPlaceholder, keyJavaBuildInTypes, valueJavaBuildInTypes, focusId)
     .col-sm-6(style='float: right')
         if valueJavaBuildInTypes
             input.form-control(type='text' ng-model=valModel placeholder=valPlaceholder bs-typeahead data-min-length='1' bs-options='javaType for javaType in javaBuildInTypes' ng-escape='tableReset()')
@@ -61,32 +61,32 @@ mixin table-pair-edit(keyModel, valModel, keyPlaceholder, valPlaceholder, keyJav
     label.fieldSep /
     .input-tip
         if keyJavaBuildInTypes
-            input.form-control(type='text' ng-model=keyModel placeholder=keyPlaceholder bs-typeahead data-min-length='1' bs-options='javaType for javaType in javaBuildInTypes' ng-escape='tableReset()')
+            input.form-control(id=focusId type='text' ng-model=keyModel placeholder=keyPlaceholder bs-typeahead data-min-length='1' bs-options='javaType for javaType in javaBuildInTypes' ng-escape='tableReset()')
         else
-            input.form-control(type='text' ng-model=keyModel placeholder=keyPlaceholder ng-escape='tableReset()')
+            input.form-control(id=focusId type='text' ng-model=keyModel placeholder=keyPlaceholder ng-escape='tableReset()')
 
 mixin table-pair(header, tblMdl, keyFld, valFld, keyPlaceholder, valPlaceholder, keyJavaBuildInTypes, valueJavaBuildInTypes)
     .col-sm-6
         label.table-header #{header}:
         +tipLabel('field.tip')
-        +btn-add('tableNewItem(field)', 'field.addTip')
+        +btn-add('tableNewItem(field)', 'field.addTip', '{{::field.focusNewItemId}}')
         .table-details(ng-show='(#{tblMdl} && #{tblMdl}.length > 0) || tableNewItemActive(field)')
             table.links-edit.col-sm-12(st-table=tblMdl)
                 tbody
                     tr(ng-repeat='item in #{tblMdl}')
                         td.col-sm-12
                             div(ng-show='!tableEditing(field, $index)')
-                                a.labelFormField(ng-click='curPair = tableStartEdit(backupItem, field, $index); curKey = curPair.#{keyFld}; curValue = curPair.#{valFld}') {{$index + 1}}) {{item.#{keyFld}}} / {{item.#{valFld}}}
+                                a.labelFormField(event-focus='click' event-focus-id='{{::field.focusCurItemId}}' ng-click='curPair = tableStartEdit(backupItem, field, $index); curKey = curPair.#{keyFld}; curValue = curPair.#{valFld}') {{$index + 1}}) {{item.#{keyFld}}} / {{item.#{valFld}}}
                                 +btn-remove('tableRemove(backupItem, field, $index)', 'field.removeTip')
-                            div(ng-show='tableEditing(field, $index)')
+                            div(ng-if='tableEditing(field, $index)')
                                 label.labelField {{$index + 1}})
                                 +btn-save('tablePairSaveVisible(curKey, curValue)', 'tablePairSave(tablePairValid, backupItem, field, curKey, curValue, $index)')
-                                +table-pair-edit('curKey', 'curValue', keyPlaceholder, valPlaceholder, keyJavaBuildInTypes, valueJavaBuildInTypes)
+                                +table-pair-edit('curKey', 'curValue', keyPlaceholder, valPlaceholder, keyJavaBuildInTypes, valueJavaBuildInTypes, '{{::field.focusCurItemId}}')
                 tfoot(ng-show='tableNewItemActive(field)')
                     tr
                         td.col-sm-12
                             +btn-save('tablePairSaveVisible(newKey, newValue)', 'tablePairSave(tablePairValid, backupItem, field, newKey, newValue, -1)')
-                            +table-pair-edit('newKey', 'newValue', keyPlaceholder, valPlaceholder, keyJavaBuildInTypes, valueJavaBuildInTypes)
+                            +table-pair-edit('newKey', 'newValue', keyPlaceholder, valPlaceholder, keyJavaBuildInTypes, valueJavaBuildInTypes, '{{::field.focusNewItemId}}')
 
 mixin details-row
     - var lblDetailClasses = ['col-sm-4', 'details-label']
@@ -139,15 +139,15 @@ mixin details-row
                     tr(ng-repeat='item in #{detailMdl} track by $index')
                         td
                             div(ng-show='!tableEditing(detail, $index)')
-                                a.labelFormField(ng-click='curValue = tableStartEdit(backupItem, detail, $index)') {{$index + 1}}) {{item}}
+                                a.labelFormField(event-focus='click' event-focus-id='{{::detail.focusCurItemId}}' ng-click='curValue = tableStartEdit(backupItem, detail, $index)') {{$index + 1}}) {{item}}
                                 +btn-remove('tableRemove(backupItem, detail, $index)', 'detail.removeTip')
                                 +btn-down('detail.reordering && tableSimpleDownVisible(backupItem, detail, $index)', 'tableSimpleDown(backupItem, detail, $index)')
                                 +btn-up('detail.reordering && $index > 0', 'tableSimpleUp(backupItem, detail, $index)')
-                            div(ng-show='tableEditing(detail, $index)')
+                            div(ng-if='tableEditing(detail, $index)')
                                 label.labelField {{$index + 1}})
                                 +btn-save('tableSimpleSaveVisible(curValue)', 'tableSimpleSave(tableSimpleValid, backupItem, detail, curValue, $index)')
                                 .input-tip.form-group.has-feedback
-                                    input.form-control(name='{{detail.model}}.edit' type='text' ng-model='curValue' placeholder='{{::detail.placeholder}}' ng-escape='tableReset()')&attributes(customValidators)
+                                    input.form-control(id='{{::detail.focusCurItemId}}' name='{{detail.model}}.edit' type='text' ng-model='curValue' placeholder='{{::detail.placeholder}}' ng-escape='tableReset()')&attributes(customValidators)
                                     +ico-exclamation('{{detail.model}}.edit', 'ipaddress', 'Invalid address, see help for format description.')
             button.btn.btn-primary.fieldButton(ng-disabled='!newValue' ng-click='tableSimpleSave(tableSimpleValid, backupItem, detail, newValue, -1)') Add
             +tipField('detail.tip')
@@ -168,7 +168,7 @@ mixin table-db-field-edit(databaseName, databaseType, javaName, javaType)
     .input-tip
         input.form-control(type='text' ng-model=databaseName placeholder='DB name' ng-escape='tableReset()')
 
-mixin table-group-item-edit(fieldName, className, direction)
+mixin table-group-item-edit(fieldName, className, direction, focusId)
     div(style='width: 15%; float: right')
         button.form-control(ng-model=direction bs-select data-placeholder='Sort' bs-options='item.value as item.label for item in {{sortDirections}}')
     label.fieldSep /
@@ -176,7 +176,7 @@ mixin table-group-item-edit(fieldName, className, direction)
         input.form-control(type='text' ng-model=className placeholder='Class name' bs-typeahead data-min-length='1' bs-options='javaType for javaType in javaBuildInTypes' ng-escape='tableReset()')
     label.fieldSep /
     .input-tip
-        input.form-control(type='text' ng-model=fieldName placeholder='Field name' ng-escape='tableReset()')
+        input.form-control(id=focusId type='text' ng-model=fieldName placeholder='Field name' ng-escape='tableReset()')
 
 mixin form-row
     +form-row-custom(['col-sm-2'], ['col-sm-4'])
@@ -200,7 +200,7 @@ mixin form-row-custom(lblClasses, fieldClasses)
             div(class=fieldClasses)
                 +tipField('field.tip')
                 .input-tip
-                    input.form-control(type='text' placeholder='{{::field.placeholder}}')&attributes(fieldCommon)
+                    input.form-control(id='{{::field.id}}' type='text' placeholder='{{::field.placeholder}}')&attributes(fieldCommon)
         div(ng-switch-when='withJavaBuildInTypes' ng-hide=fieldHide)
             label(class=lblClasses ng-class=fieldRequiredClass) {{::field.label}}:
             div(class=fieldClasses)
@@ -251,7 +251,7 @@ mixin form-row-custom(lblClasses, fieldClasses)
             .col-sm-6
                 label.table-header {{::field.label}}:
                 +tipLabel('field.tableTip')
-                +btn-add('tableNewItem(field)', 'field.addTip')
+                +btn-add('tableNewItem(field)', 'field.addTip', '{{::field.focusNewItemId}}')
             .col-sm-12(ng-show='(#{fieldMdl} && #{fieldMdl}.length > 0) || tableNewItemActive(field)')
                 .col-sm-6
                     .table-details
@@ -260,21 +260,21 @@ mixin form-row-custom(lblClasses, fieldClasses)
                                 tr(ng-repeat='item in #{fieldMdl} track by $index')
                                     td.col-sm-12
                                         div(ng-show='!tableEditing(field, $index)')
-                                            a.labelFormField(ng-click='curValue = tableStartEdit(backupItem, field, $index)') {{$index + 1}}) {{item | compact}}
+                                            a.labelFormField(event-focus='click' event-focus-id='{{::field.focusCurItemId}}' ng-click='curValue = tableStartEdit(backupItem, field, $index)') {{$index + 1}}) {{item | compact}}
                                             +btn-remove('tableRemove(backupItem, field, $index)', 'field.removeTip')
                                             +btn-down('field.reordering && tableSimpleDownVisible(backupItem, field, $index)', 'tableSimpleDown(backupItem, field, $index)')
                                             +btn-up('field.reordering && $index > 0', 'tableSimpleUp(backupItem, field, $index)')
-                                        div(ng-show='tableEditing(field, $index)')
+                                        div(ng-if='tableEditing(field, $index)')
                                             label.labelField {{$index + 1}})
                                             +btn-save('tableSimpleSaveVisible(curValue)', 'tableSimpleSave(tableSimpleValid, backupItem, field, curValue, $index)')
                                             .input-tip
-                                                input.form-control(type='text' ng-model='curValue' placeholder='{{::field.placeholder}}' ng-enter='tableSimpleSaveVisible(curValue) && tableSimpleSave(tableSimpleValid, backupItem, field, curValue, $index)' ng-escape='tableReset()')
+                                                input.form-control(id='{{::field.focusCurItemId}}' type='text' ng-model='curValue' placeholder='{{::field.placeholder}}' ng-enter='tableSimpleSaveVisible(curValue) && tableSimpleSave(tableSimpleValid, backupItem, field, curValue, $index)' ng-escape='tableReset()')
                             tfoot(ng-show='tableNewItemActive(field)')
                                 tr
                                     td.col-sm-12
                                         +btn-save('tableSimpleSaveVisible(newValue)', 'tableSimpleSave(tableSimpleValid, backupItem, field, newValue, -1)')
                                         .input-tip
-                                            input.form-control(type='text' ng-model='newValue' placeholder='{{::field.placeholder}}' ng-enter='tableSimpleSaveVisible(newValue) && tableSimpleSave(tableSimpleValid, backupItem, field, newValue, -1)' ng-escape='tableReset()')
+                                            input.form-control(id='{{::field.focusNewItemId}}' type='text' ng-model='newValue' placeholder='{{::field.placeholder}}' ng-enter='tableSimpleSaveVisible(newValue) && tableSimpleSave(tableSimpleValid, backupItem, field, newValue, -1)' ng-escape='tableReset()')
         div(ng-switch-when='indexedTypes')
             +table-pair('Index key-value type pairs', fieldMdl, 'keyClass', 'valueClass', 'Key class full name', 'Value class full name', true, false)
         div(ng-switch-when='queryFields' ng-hide=fieldHide)
@@ -283,7 +283,7 @@ mixin form-row-custom(lblClasses, fieldClasses)
             .col-sm-6
                 label.table-header {{::field.label}}:
                 +tipLabel('field.tip')
-                +btn-add('tableNewItem(field)', 'field.addTip')
+                +btn-add('tableNewItem(field)', 'field.addTip', 'field.focusNewItemId')
             .col-sm-12(ng-show='(#{fieldMdl} && #{fieldMdl}.length > 0) || tableNewItemActive(field)')
                 .col-sm-6
                     .table-details
@@ -307,7 +307,7 @@ mixin form-row-custom(lblClasses, fieldClasses)
             .col-sm-6
                 label.table-header {{::field.label}}:
                 +tipLabel('field.tip')
-                +btn-add('tableNewItem(field)', 'field.addTip')
+                +btn-add('tableNewItem(field)', 'field.addTip', 'newGroupId')
             .col-sm-12(ng-show='(#{fieldMdl} && #{fieldMdl}.length > 0) || tableNewItemActive(field)')
                 .col-sm-6
                     .table-details
@@ -317,32 +317,34 @@ mixin form-row-custom(lblClasses, fieldClasses)
                                     td.col-sm-12
                                         div
                                             .col-sm-12(ng-show='!tableEditing(field, $index)')
-                                                a.labelFormField(ng-click='curGroup = tableStartEdit(backupItem, field, $index); curGroupName = curGroup.name; curFields = curGroup.fields') {{$index + 1}}) {{group.name}}
+                                                a.labelFormField(event-focus='click' event-focus-id='curGroupId' ng-click='curGroup = tableStartEdit(backupItem, field, $index); curGroupName = curGroup.name; curFields = curGroup.fields') {{$index + 1}}) {{group.name}}
                                                 +btn-remove('tableRemove(backupItem, field, $index)', 'field.removeTip')
-                                                +btn-add('tableGroupNewItem($index)', 'field.addItemTip')
-                                            div(ng-show='tableEditing(field, $index)')
+                                                +btn-add('tableGroupNewItem($index)', 'field.addItemTip', 'newGroupItemId')
+                                            div(ng-if='tableEditing(field, $index)')
                                                 label.labelField {{$index + 1}})
                                                 +btn-save('tableGroupSaveVisible(curGroupName)', 'tableGroupSave(curGroupName, $index)')
                                                 .input-tip
-                                                    input.form-control(type='text' ng-model='curGroupName' placeholder='Index name' ng-enter='tableGroupSaveVisible(curGroupName) && tableGroupSave(curGroupName, $index)' ng-escape='tableReset()')
+                                                    input#curGroupId.form-control(type='text' ng-model='curGroupName' placeholder='Index name' ng-enter='tableGroupSaveVisible(curGroupName) && tableGroupSave(curGroupName, $index)' ng-escape='tableReset()')
                                             div
                                                 table.links-edit.col-sm-12(st-table='group.fields' ng-init='groupIndex = $index')
-                                                    tr(ng-repeat='groupItem in group.fields')
-                                                        td
-                                                            div(ng-show='!tableGroupItemEditing(groupIndex, $index)')
-                                                                a.labelFormField(ng-click='curGroupItem = tableGroupItemStartEdit(groupIndex, $index); curFieldName = curGroupItem.name; curClassName = curGroupItem.className; curDirection = curGroupItem.direction') {{$index + 1}}) {{groupItem.name}} / {{groupItem.className}} / {{groupItem.direction ? "DESC" : "ASC"}}
-                                                                +btn-remove('tableRemoveGroupItem(group, $index)', 'field.removeItemTip')
-                                                            div(ng-show='tableGroupItemEditing(groupIndex, $index)')
-                                                                label.labelField {{$index + 1}})
-                                                                +btn-save('tableGroupItemSaveVisible(curFieldName, curClassName)', 'tableGroupItemSave(curFieldName, curClassName, curDirection, groupIndex, $index)')
-                                                                +table-group-item-edit('curFieldName', 'curClassName', 'curDirection')
-                                                    tr.col-sm-12(style='padding-left: 18px' ng-show='tableGroupNewItemActive(groupIndex)')
-                                                        td
-                                                            +btn-save('tableGroupItemSaveVisible(newFieldName, newClassName)', 'tableGroupItemSave(newFieldName, newClassName, newDirection, groupIndex, -1)')
-                                                            +table-group-item-edit('newFieldName', 'newClassName', 'newDirection')
+                                                    tbody
+                                                        tr(ng-repeat='groupItem in group.fields')
+                                                            td
+                                                                div(ng-show='!tableGroupItemEditing(groupIndex, $index)')
+                                                                    a.labelFormField(event-focus='click' event-focus-id='curGroupItemId' ng-click='curGroupItem = tableGroupItemStartEdit(groupIndex, $index); curFieldName = curGroupItem.name; curClassName = curGroupItem.className; curDirection = curGroupItem.direction') {{$index + 1}}) {{groupItem.name}} / {{groupItem.className}} / {{groupItem.direction ? "DESC" : "ASC"}}
+                                                                    +btn-remove('tableRemoveGroupItem(group, $index)', 'field.removeItemTip')
+                                                                div(ng-if='tableGroupItemEditing(groupIndex, $index)')
+                                                                    label.labelField {{$index + 1}})
+                                                                    +btn-save('tableGroupItemSaveVisible(curFieldName, curClassName)', 'tableGroupItemSave(curFieldName, curClassName, curDirection, groupIndex, $index)')
+                                                                    +table-group-item-edit('curFieldName', 'curClassName', 'curDirection', 'curGroupItemId')
+                                                    tfoot(ng-if='tableGroupNewItemActive(groupIndex)')
+                                                        tr.col-sm-12(style='padding-left: 18px')
+                                                            td
+                                                                +btn-save('tableGroupItemSaveVisible(newFieldName, newClassName)', 'tableGroupItemSave(newFieldName, newClassName, newDirection, groupIndex, -1)')
+                                                                +table-group-item-edit('newFieldName', 'newClassName', 'newDirection', 'newGroupItemId')
                             tfoot(ng-show='tableNewItemActive(field)')
                                 tr
                                     td.col-sm-12
                                         +btn-save('tableGroupSaveVisible(newGroupName)', 'tableGroupSave(newGroupName, -1)')
                                         .input-tip
-                                            input.form-control(type='text' ng-model='newGroupName' placeholder='Group name' ng-enter='tableGroupSaveVisible(newGroupName) && tableGroupSave(newGroupName, -1)' ng-escape='tableReset()')
\ No newline at end of file
+                                            input#newGroupId.form-control(type='text' ng-model='newGroupName' placeholder='Group name' ng-enter='tableGroupSaveVisible(newGroupName) && tableGroupSave(newGroupName, -1)' ng-escape='tableReset()')
\ No newline at end of file



[12/41] incubator-ignite git commit: IGNITE-843: WIP Generate cache type metadata configs + typeahead for java types + minor fixes.

Posted by an...@apache.org.
IGNITE-843: WIP Generate cache type metadata configs + typeahead for java types + minor fixes.


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

Branch: refs/heads/ignite-1121
Commit: 8af110a8f5bd58fc069cfdac1eb4daa59e28c032
Parents: ee6fa09
Author: AKuznetsov <ak...@gridgain.com>
Authored: Mon Jul 27 18:17:06 2015 +0700
Committer: AKuznetsov <ak...@gridgain.com>
Committed: Mon Jul 27 18:17:06 2015 +0700

----------------------------------------------------------------------
 .../main/js/controllers/caches-controller.js    |   1 +
 .../src/main/js/controllers/common-module.js    |   5 +-
 .../main/js/controllers/metadata-controller.js  |  63 +++++-----
 .../main/js/controllers/models/metadata.json    |   4 +-
 modules/web-control-center/src/main/js/db.js    |  20 +++-
 .../web-control-center/src/main/js/package.json |   1 +
 .../src/main/js/routes/generator/common.js      |  16 +++
 .../src/main/js/routes/generator/xml.js         | 114 +++++++++++++++++--
 .../src/main/js/routes/summary.js               |   2 +-
 .../src/main/js/views/configuration/caches.jade |   2 +-
 .../main/js/views/configuration/clusters.jade   |   2 +-
 .../main/js/views/configuration/metadata.jade   |   8 +-
 .../main/js/views/configuration/summary.jade    |  27 +++--
 .../src/main/js/views/includes/controls.jade    |  44 ++++---
 .../src/main/js/views/login.jade                |   2 +-
 .../src/main/js/views/settings/admin.jade       |   2 +-
 .../src/main/js/views/settings/profile.jade     |   2 +-
 .../src/main/js/views/templates/confirm.jade    |   6 +-
 .../src/main/js/views/templates/copy.jade       |   8 +-
 19 files changed, 234 insertions(+), 95 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/8af110a8/modules/web-control-center/src/main/js/controllers/caches-controller.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/controllers/caches-controller.js b/modules/web-control-center/src/main/js/controllers/caches-controller.js
index d8993c2..0cebc16 100644
--- a/modules/web-control-center/src/main/js/controllers/caches-controller.js
+++ b/modules/web-control-center/src/main/js/controllers/caches-controller.js
@@ -18,6 +18,7 @@
 controlCenterModule.controller('cachesController', ['$scope', '$http', '$common', '$confirm', '$copy', '$table', function ($scope, $http, $common, $confirm, $copy, $table) {
         $scope.joinTip = $common.joinTip;
         $scope.getModel = $common.getModel;
+        $scope.javaBuildInTypes = $common.javaBuildInTypes;
 
         $scope.tableNewItem = $table.tableNewItem;
         $scope.tableNewItemActive = $table.tableNewItemActive;

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/8af110a8/modules/web-control-center/src/main/js/controllers/common-module.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/controllers/common-module.js b/modules/web-control-center/src/main/js/controllers/common-module.js
index 75af155..d44b895 100644
--- a/modules/web-control-center/src/main/js/controllers/common-module.js
+++ b/modules/web-control-center/src/main/js/controllers/common-module.js
@@ -129,7 +129,10 @@ controlCenterModule.service('$common', ['$alert', function ($alert) {
                 title: msg,
                 duration: 2
             });
-        }
+        },
+        javaBuildInTypes: [
+            'Boolean', 'Byte', 'Date', 'Double', 'Float', 'Integer', 'Long', 'Short', 'String', 'Time', 'Timestamp', 'UUID'
+        ]
     }
 }]);
 

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/8af110a8/modules/web-control-center/src/main/js/controllers/metadata-controller.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/controllers/metadata-controller.js b/modules/web-control-center/src/main/js/controllers/metadata-controller.js
index 21af931..47c8687 100644
--- a/modules/web-control-center/src/main/js/controllers/metadata-controller.js
+++ b/modules/web-control-center/src/main/js/controllers/metadata-controller.js
@@ -18,6 +18,7 @@
 controlCenterModule.controller('metadataController', ['$scope', '$http', '$common', '$confirm', '$copy', '$table', function ($scope, $http, $common, $confirm, $copy, $table) {
         $scope.joinTip = $common.joinTip;
         $scope.getModel = $common.getModel;
+        $scope.javaBuildInTypes = $common.javaBuildInTypes;
 
         $scope.tableNewItem = $table.tableNewItem;
         $scope.tableNewItemActive = $table.tableNewItemActive;
@@ -127,8 +128,8 @@ controlCenterModule.controller('metadataController', ['$scope', '$http', '$commo
                             use: true,
                             key: true,
                             ak: true,
-                            dbName: 'name1',
-                            dbType: 'dbType1',
+                            databaseName: 'name1',
+                            databaseType: 'dbType1',
                             javaName: 'javaName1',
                             javaType: 'javaType1'
                         },
@@ -136,8 +137,8 @@ controlCenterModule.controller('metadataController', ['$scope', '$http', '$commo
                             use: true,
                             key: false,
                             ak: false,
-                            dbName: 'name2',
-                            dbType: 'dbType2',
+                            databaseName: 'name2',
+                            databaseType: 'dbType2',
                             javaName: 'javaName2',
                             javaType: 'javaType2'
                         },
@@ -145,8 +146,8 @@ controlCenterModule.controller('metadataController', ['$scope', '$http', '$commo
                             use: false,
                             key: false,
                             ak: false,
-                            dbName: 'name3',
-                            dbType: 'dbType3',
+                            databaseName: 'name3',
+                            databaseType: 'dbType3',
                             javaName: 'javaName3',
                             javaType: 'javaType3'
                         }
@@ -164,8 +165,8 @@ controlCenterModule.controller('metadataController', ['$scope', '$http', '$commo
                             use: true,
                             key: true,
                             ak: true,
-                            dbName: 'name4',
-                            dbType: 'dbType4',
+                            databaseName: 'name4',
+                            databaseType: 'dbType4',
                             javaName: 'javaName4',
                             javaType: 'javaType4'
                         },
@@ -173,8 +174,8 @@ controlCenterModule.controller('metadataController', ['$scope', '$http', '$commo
                             use: true,
                             key: false,
                             ak: false,
-                            dbName: 'name5',
-                            dbType: 'dbType5',
+                            databaseName: 'name5',
+                            databaseType: 'dbType5',
                             javaName: 'javaName5',
                             javaType: 'javaType5'
                         },
@@ -182,8 +183,8 @@ controlCenterModule.controller('metadataController', ['$scope', '$http', '$commo
                             use: false,
                             key: false,
                             ak: false,
-                            dbName: 'name6',
-                            dbType: 'dbType6',
+                            databaseName: 'name6',
+                            databaseType: 'dbType6',
                             javaName: 'javaName6',
                             javaType: 'javaType6'
                         }
@@ -200,8 +201,8 @@ controlCenterModule.controller('metadataController', ['$scope', '$http', '$commo
                             use: true,
                             key: true,
                             ak: true,
-                            dbName: 'name7',
-                            dbType: 'dbType7',
+                            databaseName: 'name7',
+                            databaseType: 'dbType7',
                             javaName: 'javaName7',
                             javaType: 'javaType7'
                         },
@@ -209,8 +210,8 @@ controlCenterModule.controller('metadataController', ['$scope', '$http', '$commo
                             use: true,
                             key: false,
                             ak: false,
-                            dbName: 'name8',
-                            dbType: 'dbType8',
+                            databaseName: 'name8',
+                            databaseType: 'dbType8',
                             javaName: 'javaName8',
                             javaType: 'javaType8'
                         },
@@ -218,8 +219,8 @@ controlCenterModule.controller('metadataController', ['$scope', '$http', '$commo
                             use: false,
                             key: false,
                             ak: false,
-                            dbName: 'name9',
-                            dbType: 'dbType9',
+                            databaseName: 'name9',
+                            databaseType: 'dbType9',
                             javaName: 'javaName9',
                             javaType: 'javaType9'
                         },
@@ -227,8 +228,8 @@ controlCenterModule.controller('metadataController', ['$scope', '$http', '$commo
                             use: false,
                             key: false,
                             ak: false,
-                            dbName: 'name10',
-                            dbType: 'dbType10',
+                            databaseName: 'name10',
+                            databaseType: 'dbType10',
                             javaName: 'javaName10',
                             javaType: 'javaType10'
                         },
@@ -236,8 +237,8 @@ controlCenterModule.controller('metadataController', ['$scope', '$http', '$commo
                             use: false,
                             key: false,
                             ak: false,
-                            dbName: 'name11',
-                            dbType: 'dbType11',
+                            databaseName: 'name11',
+                            databaseType: 'dbType11',
                             javaName: 'javaName11',
                             javaType: 'javaType11'
                         },
@@ -245,8 +246,8 @@ controlCenterModule.controller('metadataController', ['$scope', '$http', '$commo
                             use: false,
                             key: false,
                             ak: false,
-                            dbName: 'name12',
-                            dbType: 'dbType12',
+                            databaseName: 'name12',
+                            databaseType: 'dbType12',
                             javaName: 'javaName12',
                             javaType: 'javaType12'
                         }
@@ -467,21 +468,21 @@ controlCenterModule.controller('metadataController', ['$scope', '$http', '$commo
             return true;
         };
 
-        $scope.tableDbFieldSaveVisible = function (dbName, dbType, javaName, javaType) {
-            return $common.isNonEmpty(dbName) && $common.isDefined(dbType) &&
+        $scope.tableDbFieldSaveVisible = function (databaseName, databaseType, javaName, javaType) {
+            return $common.isNonEmpty(databaseName) && $common.isDefined(databaseType) &&
                 $common.isNonEmpty(javaName) && $common.isDefined(javaType);
         };
 
-        $scope.tableDbFieldSave = function (field, newDbName, newDbType, newJavaName, newJavaType, index) {
+        $scope.tableDbFieldSave = function (field, newDatabaseName, newDatabaseType, newJavaName, newJavaType, index) {
             var item = $scope.backupItem;
 
             var model = item[field.model];
 
-            var newItem = {dbName: newDbName, dbType: newDbType, javaName: newJavaName, javaType: newJavaType};
+            var newItem = {databaseName: newDatabaseName, databaseType: newDatabaseType, javaName: newJavaName, javaType: newJavaType};
 
             if ($common.isDefined(model)) {
                 var idx = _.findIndex(model, function (dbMeta) {
-                    return dbMeta.dbName == newDbName
+                    return dbMeta.databaseName == newDatabaseName
                 });
 
                 // Found duplicate.
@@ -500,8 +501,8 @@ controlCenterModule.controller('metadataController', ['$scope', '$http', '$commo
                 else {
                     var dbField = model[index];
 
-                    dbField.dbName = newDbName;
-                    dbField.dbType = newDbType;
+                    dbField.databaseName = newDatabaseName;
+                    dbField.databaseType = newDatabaseType;
                     dbField.javaName = newJavaName;
                     dbField.javaType = newJavaType;
                 }

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/8af110a8/modules/web-control-center/src/main/js/controllers/models/metadata.json
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/controllers/models/metadata.json b/modules/web-control-center/src/main/js/controllers/models/metadata.json
index 6c9bf35..85ac5aa 100644
--- a/modules/web-control-center/src/main/js/controllers/models/metadata.json
+++ b/modules/web-control-center/src/main/js/controllers/models/metadata.json
@@ -68,7 +68,7 @@
     },
     {
       "label": "Key type",
-      "type": "text",
+      "type": "withJavaBuildInTypes",
       "model": "keyType",
       "required": true,
       "placeholder": "Full class name for Key",
@@ -189,7 +189,7 @@
     {
       "label": "Database type",
       "type": "dropdown",
-      "model": "dbType",
+      "model": "rdbms",
       "placeholder": "Choose database",
       "items": "databases",
       "tip": [

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/8af110a8/modules/web-control-center/src/main/js/db.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/db.js b/modules/web-control-center/src/main/js/db.js
index 84947e5..e6fb99b 100644
--- a/modules/web-control-center/src/main/js/db.js
+++ b/modules/web-control-center/src/main/js/db.js
@@ -23,6 +23,8 @@ var mongoose = require('mongoose'),
     ObjectId = mongoose.Schema.Types.ObjectId,
     passportLocalMongoose = require('passport-local-mongoose');
 
+var deepPopulate = require('mongoose-deep-populate');
+
 // Connect to mongoDB database.
 mongoose.connect(config.get('mongoDB:url'), {server: {poolSize: 4}});
 
@@ -70,8 +72,8 @@ var CacheTypeMetadataSchema = new Schema({
     databaseTable: String,
     keyType: String,
     valueType: String,
-    keyFields: [{dbName: String, dbType: String, javaName: String, javaType: String}],
-    valueFields: [{dbName: String, dbType: String, javaName: String, javaType: String}],
+    keyFields: [{databaseName: String, databaseType: String, javaName: String, javaType: String}],
+    valueFields: [{databaseName: String, databaseType: String, javaName: String, javaType: String}],
     queryFields: [{name: String, className: String}],
     ascendingFields: [{name: String, className: String}],
     descendingFields:  [{name: String, className: String}],
@@ -312,6 +314,14 @@ var ClusterSchema = new Schema({
     waitForSegmentOnStart: Boolean
 });
 
+ClusterSchema.plugin(deepPopulate, {
+    whitelist: [
+        'caches',
+        'caches.queryMetadata',
+        'caches.storeMetadata'
+    ]
+});
+
 // Define cluster model.
 exports.Cluster = mongoose.model('Cluster', ClusterSchema);
 
@@ -319,7 +329,7 @@ exports.Cluster = mongoose.model('Cluster', ClusterSchema);
 var PersistenceSchema = new Schema({
     space: {type: ObjectId, ref: 'Space'},
     name: String,
-    dbType: {type: String, enum: ['oracle', 'db2', 'mssql', 'postgre', 'mysql', 'h2']},
+    rdbms: {type: String, enum: ['oracle', 'db2', 'mssql', 'postgre', 'mysql', 'h2']},
     dbName: String,
     host: String,
     user: String,
@@ -334,8 +344,8 @@ var PersistenceSchema = new Schema({
             pk: Boolean,
             ak: Boolean,
             notNull: Boolean,
-            dbName: String,
-            dbType: Number,
+            databaseName: String,
+            databaseType: Number,
             javaName: String,
             javaType: String
         }]

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/8af110a8/modules/web-control-center/src/main/js/package.json
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/package.json b/modules/web-control-center/src/main/js/package.json
index ed06004..fd82196 100644
--- a/modules/web-control-center/src/main/js/package.json
+++ b/modules/web-control-center/src/main/js/package.json
@@ -32,6 +32,7 @@
     "jade": "~1.9.2",
     "lodash": "3.10.0",
     "mongoose": "^4.0.2",
+    "mongoose-deep-populate": "1.1.0",
     "nconf": "^0.7.1",
     "node-sass-middleware": "^0.9.0",
     "passport": "^0.2.1",

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/8af110a8/modules/web-control-center/src/main/js/routes/generator/common.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/routes/generator/common.js b/modules/web-control-center/src/main/js/routes/generator/common.js
index dcbf156..05405d3 100644
--- a/modules/web-control-center/src/main/js/routes/generator/common.js
+++ b/modules/web-control-center/src/main/js/routes/generator/common.js
@@ -174,6 +174,22 @@ exports.marshallers = {
     JdkMarshaller: new ClassDescriptor('org.apache.ignite.marshaller.jdk.JdkMarshaller', {})
 };
 
+exports.knownBuildInClasses = {
+    BigDecimal: {className: 'java.math.Boolean'},
+    Boolean: {className: 'java.lang.Boolean'},
+    Byte: {className: 'java.lang.Byte'},
+    Date: {className: 'java.sql.Date'},
+    Double: {className: 'java.lang.Double'},
+    Float: {className: 'java.lang.Float'},
+    Integer: {className: 'java.lang.Integer'},
+    Long: {className: 'java.lang.Long'},
+    Short: {className: 'java.lang.Short'},
+    String: {className: 'java.lang.String'},
+    Time: {className: 'java.sql.Time'},
+    Timestamp: {className: 'java.sql.Timestamp'},
+    UUID: {className: 'java.util.UUID'}
+};
+
 exports.knownClasses = {
     Oracle: new ClassDescriptor('org.apache.ignite.cache.store.jdbc.dialect.OracleDialect', {}),
     DB2: new ClassDescriptor('org.apache.ignite.cache.store.jdbc.dialect.DB2Dialect', {}),

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/8af110a8/modules/web-control-center/src/main/js/routes/generator/xml.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/routes/generator/xml.js b/modules/web-control-center/src/main/js/routes/generator/xml.js
index 7c18655..8009698 100644
--- a/modules/web-control-center/src/main/js/routes/generator/xml.js
+++ b/modules/web-control-center/src/main/js/routes/generator/xml.js
@@ -337,13 +337,79 @@ function createEvictionPolicy(res, evictionPolicy, propertyName) {
     }
 }
 
+function addFields(res, meta, fieldsProperty) {
+    var fields = meta[fieldsProperty];
+
+    if (fields && fields.length > 0) {
+        res.startBlock('<property name="' + fieldsProperty + '">');
+
+        res.startBlock('<list>');
+
+        _.forEach(fields, function (field) {
+            res.startBlock('<bean class="org.apache.ignite.cache.CacheTypeFieldMetadata">');
+
+            addProperty(res, field, 'databaseName');
+
+            addProperty(res, field, 'databaseType');
+            //addPropertyAsConst(res, field, databaseType, toJdbcTypeConst);
+
+            addProperty(res, field, 'javaName');
+            addElement(res, 'property', 'name', 'javaType', 'value', knownBuildInClasses(field.javaType));
+
+            res.endBlock('</bean>');
+        });
+
+        res.endBlock('</list>');
+    }
+}
+
+function knownBuildInClasses(className) {
+    var fullClassName = generatorUtils.knownBuildInClasses[className];
+
+    if (fullClassName)
+        return fullClassName.className;
+
+    return className;
+}
+
+function addQueryFields(res, meta, fieldsProperty) {
+    var fields = meta[fieldsProperty];
+
+    if (fields && fields.length > 0) {
+        res.startBlock('<property name="' + fieldsProperty + '">');
+
+        res.startBlock('<map>');
+
+        _.forEach(fields, function (field) {
+            addElement(res, 'entry', 'key', field.name, 'value', knownBuildInClasses(field.className));
+        });
+
+        res.endBlock('</map>');
+
+        res.endBlock('</property>');
+    }
+}
+
 function generateCacheTypeMetadataConfiguration(metaCfg, res) {
     if (!res)
         res = generatorUtils.builder();
 
     res.startBlock('<bean class="org.apache.ignite.cache.CacheTypeMetadata">');
 
+    addProperty(res, metaCfg, 'databaseSchema');
+    addProperty(res, metaCfg, 'databaseTable');
+
+    addProperty(res, metaCfg, 'keyType');
+    addProperty(res, metaCfg, 'valueType');
+
+    addFields(res, metaCfg, 'keyFields');
+    addFields(res, metaCfg, 'valueFields');
+
+    addQueryFields(res, metaCfg, 'queryFields');
+    addQueryFields(res, metaCfg, 'ascendingFields');
+    addQueryFields(res, metaCfg, 'descendingFields');
 
+    addListProperty(res, metaCfg, 'textFields');
 
     res.endBlock('</bean>');
 
@@ -409,8 +475,8 @@ function generateCacheConfiguration(cacheCfg, res) {
         for (var i = 0; i < cacheCfg.indexedTypes.length; i++) {
             var pair = cacheCfg.indexedTypes[i];
 
-            res.line('<value>' + escape(pair.keyClass) + '</value>');
-            res.line('<value>' + escape(pair.valueClass) + '</value>');
+            res.line('<value>' + knownBuildInClasses(pair.keyClass) + '</value>');
+            res.line('<value>' + knownBuildInClasses(pair.valueClass) + '</value>');
         }
 
         res.endBlock('</list>');
@@ -486,10 +552,26 @@ function generateCacheConfiguration(cacheCfg, res) {
         res.startBlock('<property name="typeMetadata">');
         res.startBlock('<list>');
 
-        // TODO
+        var metas = [];
+
+        if (cacheCfg.queryMetadata && cacheCfg.queryMetadata.length > 0) {
+            _.forEach(cacheCfg.queryMetadata, function (meta) {
+                metas.push(meta);
+            });
+        }
+
+        if (cacheCfg.storeMetadata && cacheCfg.storeMetadata.length > 0) {
+            _.forEach(cacheCfg.storeMetadata, function (meta) {
+                metas.push(meta);
+            });
+        }
+
+        _.forEach(metas, function (meta) {
+            generateCacheTypeMetadataConfiguration(meta, res);
+        });
 
         res.endBlock('</list>');
-        res.endBlock('</property');
+        res.endBlock('</property>');
     }
 
     res.endBlock('</bean>');
@@ -499,14 +581,28 @@ function generateCacheConfiguration(cacheCfg, res) {
 
 exports.generateCacheConfiguration = generateCacheConfiguration;
 
-function addProperty(res, obj, propName, setterName) {
-    var val = obj[propName];
+function addElement(res, tag, attr1, val1, attr2, val2) {
+    var elem = '<' + tag;
 
-    if (generatorUtils.isDefined(val)) {
-        res.emptyLineIfNeeded();
+    if (attr1) {
+        elem += ' ' + attr1 + '="' + val1 + '"'
+    }
 
-        res.line('<property name="' + (setterName ? setterName : propName) + '" value="' + escapeAttr(val) + '"/>');
+    if (attr2) {
+        elem += ' ' + attr2 + '="' + val2 + '"'
     }
+
+    elem += '/>';
+
+    res.emptyLineIfNeeded();
+    res.line(elem);
+}
+
+function addProperty(res, obj, propName, setterName) {
+    var val = obj[propName];
+
+    if (generatorUtils.isDefined(val))
+        addElement(res, 'property', 'name', setterName ? setterName : propName, 'value', escapeAttr(val));
 }
 
 function addBeanWithProperties(res, bean, beanPropName, beanClass, props, createBeanAlthoughNoProps) {

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/8af110a8/modules/web-control-center/src/main/js/routes/summary.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/routes/summary.js b/modules/web-control-center/src/main/js/routes/summary.js
index f766945..9f8df2a 100644
--- a/modules/web-control-center/src/main/js/routes/summary.js
+++ b/modules/web-control-center/src/main/js/routes/summary.js
@@ -30,7 +30,7 @@ router.get('/', function (req, res) {
 
 router.post('/generator', function (req, res) {
     // Get cluster.
-    db.Cluster.findById(req.body._id).populate('caches').exec(function (err, cluster) {
+    db.Cluster.findById(req.body._id).deepPopulate('caches caches.queryMetadata caches.storeMetadata').exec(function (err, cluster) {
         if (err)
             return res.status(500).send(err.message);
 

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/8af110a8/modules/web-control-center/src/main/js/views/configuration/caches.jade
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/views/configuration/caches.jade b/modules/web-control-center/src/main/js/views/configuration/caches.jade
index ea50317..579b5aa 100644
--- a/modules/web-control-center/src/main/js/views/configuration/caches.jade
+++ b/modules/web-control-center/src/main/js/views/configuration/caches.jade
@@ -48,7 +48,7 @@ block content
                         .panel-body
                             .settings-row(ng-repeat='field in general')
                                 +form-row(['col-sm-3'], ['col-sm-3'])
-            .panel-group(bs-collapse data-allow-multiple="true")
+            .panel-group(bs-collapse data-allow-multiple='true')
                 div(bs-collapse data-start-collapsed='true')
                     .panel-title(ng-show='expanded')
                         h3

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/8af110a8/modules/web-control-center/src/main/js/views/configuration/clusters.jade
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/views/configuration/clusters.jade b/modules/web-control-center/src/main/js/views/configuration/clusters.jade
index cf429e5..882a2b9 100644
--- a/modules/web-control-center/src/main/js/views/configuration/clusters.jade
+++ b/modules/web-control-center/src/main/js/views/configuration/clusters.jade
@@ -51,7 +51,7 @@ block content
                         .panel-body
                             .settings-row(ng-repeat='field in general')
                                 +form-row
-            .panel-group(bs-collapse data-allow-multiple="true")
+            .panel-group(bs-collapse data-allow-multiple='true')
                 div(bs-collapse data-start-collapsed='true')
                     .panel-title(ng-show='expanded')
                         h3

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/8af110a8/modules/web-control-center/src/main/js/views/configuration/metadata.jade
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/views/configuration/metadata.jade b/modules/web-control-center/src/main/js/views/configuration/metadata.jade
index 9f94965..e01eaa8 100644
--- a/modules/web-control-center/src/main/js/views/configuration/metadata.jade
+++ b/modules/web-control-center/src/main/js/views/configuration/metadata.jade
@@ -41,12 +41,12 @@ block content
             button.btn.btn-default(ng-model='template' data-template='/select' data-placeholder='Choose metadata type' bs-options='item.value as item.label for item in templates' bs-select)
             i.tiplabel.fa.fa-question-circle(bs-tooltip data-title='{{joinTip(templateTip)}}' type='button')
         hr
-        .panel-group(bs-collapse ng-model='panels.activePanel' data-allow-multiple="false")
+        .panel-group(bs-collapse ng-model='panels.activePanel' data-allow-multiple='false')
             .panel.panel-default(ng-show='selectedItem || backupItem')
                 .panel-heading
                     h3
                         a(bs-collapse-toggle) Manual
-                .panel-collapse(role="tabpanel" bs-collapse-target)
+                .panel-collapse(role='tabpanel' bs-collapse-target)
                     .panel-body
                         form.form-horizontal(name='manualForm' ng-if='backupItem' novalidate)
                             .settings-row(ng-repeat='field in metadataManual')
@@ -107,9 +107,9 @@ block content
                         //                td
                         //                    +dbcheck('row.ak')
                         //                td
-                        //                    label {{row.dbName}}
+                        //                    label {{row.databaseName}}
                         //                td
-                        //                    label {{row.dbType}}
+                        //                    label {{row.databaseType}}
                         //                td
                         //                    a(ng-show='data.curFieldIdx != $index' ng-click='selectField($index)') {{row.javaName}}
                         //                    input.form-control(type='text' ng-show='data.curFieldIdx == $index' ng-model='data.curJavaName' placeholder='Field Java name')

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/8af110a8/modules/web-control-center/src/main/js/views/configuration/summary.jade
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/views/configuration/summary.jade b/modules/web-control-center/src/main/js/views/configuration/summary.jade
index 8e19b7c..be1cf77 100644
--- a/modules/web-control-center/src/main/js/views/configuration/summary.jade
+++ b/modules/web-control-center/src/main/js/views/configuration/summary.jade
@@ -19,8 +19,8 @@ extends sidebar
 append scripts
     script(src='/summary-controller.js')
 
-    script(src="//cdn.jsdelivr.net/angularjs/1.3.15/angular-animate.min.js")
-    script(src="//cdn.jsdelivr.net/angularjs/1.3.15/angular-sanitize.min.js")
+    script(src='//cdn.jsdelivr.net/angularjs/1.3.15/angular-animate.min.js')
+    script(src='//cdn.jsdelivr.net/angularjs/1.3.15/angular-sanitize.min.js')
 
     script(src='//cdnjs.cloudflare.com/ajax/libs/ace/1.2.0/theme-chrome.js')
     script(src='//cdnjs.cloudflare.com/ajax/libs/ace/1.2.0/mode-xml.js')
@@ -32,7 +32,7 @@ append css
 include ../includes/controls
 
 mixin hard-link(ref, txt)
-    a(style='color:#ec1c24' href=ref target="_blank") #{txt}
+    a(style='color:#ec1c24' href=ref target='_blank') #{txt}
 
 block content
     .docs-header
@@ -51,17 +51,17 @@ block content
                     tr(ng-repeat='row in clusters track by row._id')
                         td.col-sm-6(ng-class='{active: row._id == selectedItem._id}')
                             a(ng-click='selectItem(row)') {{$index + 1}}) {{row.name}}
-        div(ng-show='selectedItem' role="tab" method='post' action='summary/download')
+        div(ng-show='selectedItem' role='tab' method='post' action='summary/download')
             .padding-dflt(bs-collapse data-start-collapsed='false')
                 .panel.panel-default
                     form.panel-heading(role='tab' method='post' action='summary/download')
-                        input(type="hidden" name="_id" value="{{selectedItem._id}}")
-                        input(type="hidden" name="os" value="{{os}}")
-                        input(type="hidden" name="javaClass" value="{{javaClassServer}}")
+                        input(type='hidden' name='_id' value='{{selectedItem._id}}')
+                        input(type='hidden' name='os' value='{{os}}')
+                        input(type='hidden' name='javaClass' value='{{javaClassServer}}')
                         h3
                             a(bs-collapse-toggle) Server
                             button.btn.btn-primary.pull-right(type='submit' style='margin-top: -5px') Download
-                    .panel-collapse(role="tabpanel" bs-collapse-target)
+                    .panel-collapse(role='tabpanel' bs-collapse-target)
                         div(ng-show='selectedItem' bs-tabs style='margin-top: 0.65em')
                             div(title='<img src="/images/xml.png" width="16px" height="16px"/> XML' bs-pane)
                                 div(ui-ace='{ onLoad: aceInit, mode: "xml" }' ng-model='xmlServer')
@@ -86,19 +86,18 @@ block content
                                     .col-sm-2
                                         label(for='os') Operation System:
                                     .col-sm-4
-                                        input#os.form-control(type='text', ng-model='configServer.os' placeholder='debian:8' data-min-length="0" data-html="1" data-auto-select="true" data-animation="am-flip-x" bs-typeahead bs-options='os for os in oss')
+                                        input#os.form-control(type='text', ng-model='configServer.os' placeholder='debian:8' data-min-length='0' data-html='1' data-auto-select='true' data-animation='am-flip-x' bs-typeahead bs-options='os for os in oss')
                                 div(ui-ace='{ onLoad: aceInit, mode: "dockerfile" }' ng-model='dockerServer')
             .padding-dflt(bs-collapse data-start-collapsed='false')
                 .panel.panel-default
                     form.panel-heading(role='tab' method='post' action='summary/download')
-                        input(type="hidden" name="_id" value="{{selectedItem._id}}")
-                        input(type="hidden" name="javaClass" value="{{javaClassClient}}")
-                        input(type="hidden" name="clientNearConfiguration" value="{{backupItem}}")
-
+                        input(type='hidden' name='_id' value='{{selectedItem._id}}')
+                        input(type='hidden' name='javaClass' value='{{javaClassClient}}')
+                        input(type='hidden' name='clientNearConfiguration' value='{{backupItem}}')
                         h3
                             a(bs-collapse-toggle) Client
                             button.btn.btn-primary.pull-right(type='submit' style='margin-top: -5px') Download
-                    .panel-collapse(role="tabpanel" bs-collapse-target)
+                    .panel-collapse(role='tabpanel' bs-collapse-target)
                         div(ng-show='selectedItem')
                             .details-row(ng-repeat='field in clientFields')
                                 +form-row-custom(['col-sm-3'], ['col-sm-3'])

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/8af110a8/modules/web-control-center/src/main/js/views/includes/controls.jade
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/views/includes/controls.jade b/modules/web-control-center/src/main/js/views/includes/controls.jade
index aebe4de..340a612 100644
--- a/modules/web-control-center/src/main/js/views/includes/controls.jade
+++ b/modules/web-control-center/src/main/js/views/includes/controls.jade
@@ -52,14 +52,20 @@ mixin btn-up(show, click)
 mixin btn-down(show, click)
     i.tipField.fa.fa-arrow-down(ng-show=show ng-click=click bs-tooltip data-title='Move item down')
 
-mixin table-pair-edit(keyModel, valModel, keyPlaceholder, valPlaceholder)
+mixin table-pair-edit(keyModel, valModel, keyPlaceholder, valPlaceholder, keyJavaBuildInTypes, valueJavaBuildInTypes)
     .col-sm-6(style='float: right')
-        input.form-control(type='text' ng-model=valModel placeholder=valPlaceholder)
+        if valueJavaBuildInTypes
+            input.form-control(type='text' ng-model=valModel placeholder=valPlaceholder bs-typeahead data-min-length='1' bs-options='javaType for javaType in javaBuildInTypes')
+        else
+            input.form-control(type='text' ng-model=valModel placeholder=valPlaceholder)
     label.fieldSep /
     .input-tip
-        input.form-control(type='text' ng-model=keyModel placeholder=keyPlaceholder)
+        if keyJavaBuildInTypes
+            input.form-control(type='text' ng-model=keyModel placeholder=keyPlaceholder bs-typeahead data-min-length='1' bs-options='javaType for javaType in javaBuildInTypes')
+        else
+            input.form-control(type='text' ng-model=keyModel placeholder=keyPlaceholder)
 
-mixin table-pair(header, tblMdl, keyFld, valFld, keyPlaceholder, valPlaceholder)
+mixin table-pair(header, tblMdl, keyFld, valFld, keyPlaceholder, valPlaceholder, keyJavaBuildInTypes, valueJavaBuildInTypes)
     .col-sm-6
         label.table-header #{header}:
         +tipLabel('field.tip')
@@ -75,12 +81,12 @@ mixin table-pair(header, tblMdl, keyFld, valFld, keyPlaceholder, valPlaceholder)
                             div(ng-show='tableEditing(field, $index)')
                                 label.labelField {{$index + 1}})
                                 +btn-save('tablePairSaveVisible(curKey, curValue)', 'tablePairSave(tablePairValid, backupItem, field, curKey, curValue, $index)')
-                                +table-pair-edit('curKey', 'curValue', keyPlaceholder, valPlaceholder)
+                                +table-pair-edit('curKey', 'curValue', keyPlaceholder, valPlaceholder, keyJavaBuildInTypes, valueJavaBuildInTypes)
                 tfoot(ng-show='tableNewItemActive(field)')
                     tr
                         td.col-sm-12
                             +btn-save('tablePairSaveVisible(newKey, newValue)', 'tablePairSave(tablePairValid, backupItem, field, newKey, newValue, -1)')
-                            +table-pair-edit('newKey', 'newValue', keyPlaceholder, valPlaceholder)
+                            +table-pair-edit('newKey', 'newValue', keyPlaceholder, valPlaceholder, keyJavaBuildInTypes, valueJavaBuildInTypes)
 
 mixin details-row
     - var lblDetailClasses = ['col-sm-4', 'details-label']
@@ -149,7 +155,7 @@ mixin details-row
                 input.form-control(name='{{detail.model}}' type='text' ng-model='newValue' ng-focus='tableNewItem(detail)' placeholder='{{::detail.placeholder}}')&attributes(customValidators)
                 +ico-exclamation('{{detail.model}}', 'ipaddress', 'Invalid address, see help for format description.')
 
-mixin table-db-field-edit(dbName, dbType, javaName, javaType)
+mixin table-db-field-edit(databaseName, databaseType, javaName, javaType)
     div(style='width: 22%; float: right')
         button.form-control(ng-model=javaType bs-select data-placeholder='Java type' bs-options='item.value as item.label for item in {{javaTypes}}')
     label.fieldSep /
@@ -157,10 +163,10 @@ mixin table-db-field-edit(dbName, dbType, javaName, javaType)
         input.form-control(type='text' ng-model=javaName placeholder='Java name')
     label.fieldSep /
     div(style='width: 22%; float: right')
-        button.form-control(ng-model=dbType bs-select data-placeholder='JDBC type' bs-options='item.value as item.label for item in {{jdbcTypes}}')
+        button.form-control(ng-model=databaseType bs-select data-placeholder='JDBC type' bs-options='item.value as item.label for item in {{jdbcTypes}}')
     label.fieldSep /
     .input-tip
-        input.form-control(type='text' ng-model=dbName placeholder='DB name')
+        input.form-control(type='text' ng-model=databaseName placeholder='DB name')
 
 mixin table-group-item-edit(fieldName, className, direction)
     div(style='width: 15%; float: right')
@@ -195,6 +201,12 @@ mixin form-row-custom(lblClasses, fieldClasses)
                 +tipField('field.tip')
                 .input-tip
                     input.form-control(type='text' placeholder='{{::field.placeholder}}')&attributes(fieldCommon)
+        div(ng-switch-when='withJavaBuildInTypes' ng-hide=fieldHide)
+            label(class=lblClasses ng-class=fieldRequiredClass) {{::field.label}}:
+            div(class=fieldClasses)
+                +tipField('field.tip')
+                .input-tip
+                    input.form-control(type='text' placeholder='{{::field.placeholder}}' bs-typeahead data-min-length='1' bs-options='javaType for javaType in javaBuildInTypes')&attributes(fieldCommon)
         div(ng-switch-when='password' ng-hide=fieldHide)
             label(class=lblClasses ng-class=fieldRequiredClass) {{::field.label}}:
             div(class=fieldClasses)
@@ -264,9 +276,9 @@ mixin form-row-custom(lblClasses, fieldClasses)
                                         .input-tip
                                             input.form-control(type='text' ng-model='newValue' placeholder='{{::field.placeholder}}')
         div(ng-switch-when='indexedTypes')
-            +table-pair('Index key-value type pairs', fieldMdl, 'keyClass', 'valueClass', 'Key class full name', 'Value class full name')
+            +table-pair('Index key-value type pairs', fieldMdl, 'keyClass', 'valueClass', 'Key class full name', 'Value class full name', true, false)
         div(ng-switch-when='queryFields' ng-hide=fieldHide)
-            +table-pair('{{::field.label}}', fieldMdl, 'name', 'className', 'Field name', 'Field class full name')
+            +table-pair('{{::field.label}}', fieldMdl, 'name', 'className', 'Field name', 'Field class full name', false, true)
         div(ng-switch-when='dbFields' ng-hide=fieldHide)
             .col-sm-6
                 label.table-header {{::field.label}}:
@@ -280,17 +292,17 @@ mixin form-row-custom(lblClasses, fieldClasses)
                                 tr(ng-repeat='item in #{fieldMdl}')
                                     td.col-sm-12
                                         div(ng-show='!tableEditing(field, $index)')
-                                            a.labelFormField(ng-click='curField = tableStartEdit(backupItem, field, $index); curDbName = curField.dbName; curDbType = curField.dbType; curJavaName = curField.javaName; curJavaType = curField.javaType') {{$index + 1}}) {{item.dbName}} / {{item.dbType}} / {{item.javaName}} / {{item.javaType}}
+                                            a.labelFormField(ng-click='curField = tableStartEdit(backupItem, field, $index); curDatabaseName = curField.databaseName; curDatabaseType = curField.databaseType; curJavaName = curField.javaName; curJavaType = curField.javaType') {{$index + 1}}) {{item.databaseName}} / {{item.databaseType}} / {{item.javaName}} / {{item.javaType}}
                                             +btn-remove('tableRemove(backupItem, field, $index)', 'field.removeTip')
                                         div(ng-if='tableEditing(field, $index)')
                                             label.labelField {{$index + 1}})
-                                            +btn-save('tableDbFieldSaveVisible(curDbName, curDbType, curJavaName, curJavaType)', 'tableDbFieldSave(field, curDbName, curDbType, curJavaName, curJavaType, $index)')
-                                            +table-db-field-edit('curDbName', 'curDbType', 'curJavaName', 'curJavaType')
+                                            +btn-save('tableDbFieldSaveVisible(curDatabaseName, curDatabaseType, curJavaName, curJavaType)', 'tableDbFieldSave(field, curDatabaseName, curDatabaseType, curJavaName, curJavaType, $index)')
+                                            +table-db-field-edit('curDatabaseName', 'curDatabaseType', 'curJavaName', 'curJavaType')
                             tfoot(ng-show='tableNewItemActive(field)')
                                 tr
                                     td.col-sm-12
-                                        +btn-save('tableDbFieldSaveVisible(newDbName, newDbType, newJavaName, newJavaType)', 'tableDbFieldSave(field, newDbName, newDbType, newJavaName, newJavaType, -1)')
-                                        +table-db-field-edit('newDbName', 'newDbType', 'newJavaName', 'newJavaType')
+                                        +btn-save('tableDbFieldSaveVisible(newDatabaseName, newDatabaseType, newJavaName, newJavaType)', 'tableDbFieldSave(field, newDatabaseName, newDatabaseType, newJavaName, newJavaType, -1)')
+                                        +table-db-field-edit('newDatabaseName', 'newDatabaseType', 'newJavaName', 'newJavaType')
         div(ng-switch-when='queryGroups' ng-hide=fieldHide)
             .col-sm-6
                 label.table-header {{::field.label}}:

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/8af110a8/modules/web-control-center/src/main/js/views/login.jade
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/views/login.jade b/modules/web-control-center/src/main/js/views/login.jade
index 5bb39dd..7cce3f6 100644
--- a/modules/web-control-center/src/main/js/views/login.jade
+++ b/modules/web-control-center/src/main/js/views/login.jade
@@ -49,7 +49,7 @@ mixin lbl(txt)
 
             .modal-footer
                 a.show-signup.ng-hide(ng-show='action != "login"', ng-click='action = "login";') log in
-                a.show-signup(ng-show="action != 'register'", ng-click='action = "register";') sign up
+                a.show-signup(ng-show='action != "register"', ng-click='action = "register"') sign up
                 | &nbsp;or&nbsp;
                 button.btn.btn-primary(ng-show='action == "login"' ng-click='auth(action, user_info)') Log In
                 button.btn.btn-primary(ng-show='action == "register"' ng-disabled='loginForm.$invalid || user_info.password != user_info.confirm' ng-click='auth(action, user_info)') Sign Up

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/8af110a8/modules/web-control-center/src/main/js/views/settings/admin.jade
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/views/settings/admin.jade b/modules/web-control-center/src/main/js/views/settings/admin.jade
index 4d50631..8345bb9 100644
--- a/modules/web-control-center/src/main/js/views/settings/admin.jade
+++ b/modules/web-control-center/src/main/js/views/settings/admin.jade
@@ -53,6 +53,6 @@ block container
                                     i.fa.fa-eye
                     tfoot
                         tr
-                            td(colspan='5' class="text-right")
+                            td.text-right(colspan='5')
                                 div(st-pagination st-items-by-page='15' st-displayed-pages='5')
 

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/8af110a8/modules/web-control-center/src/main/js/views/settings/profile.jade
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/views/settings/profile.jade b/modules/web-control-center/src/main/js/views/settings/profile.jade
index dbc6dea..96f06c5 100644
--- a/modules/web-control-center/src/main/js/views/settings/profile.jade
+++ b/modules/web-control-center/src/main/js/views/settings/profile.jade
@@ -42,7 +42,7 @@ block container
                         .details-row
                             .checkbox
                                 label
-                                    input(type="checkbox" ng-model='profileUser.changePassword')
+                                    input(type='checkbox' ng-model='profileUser.changePassword')
                                     | Change password
                         div(ng-show='profileUser.changePassword')
                             .details-row

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/8af110a8/modules/web-control-center/src/main/js/views/templates/confirm.jade
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/views/templates/confirm.jade b/modules/web-control-center/src/main/js/views/templates/confirm.jade
index bdaf9bf..949318a 100644
--- a/modules/web-control-center/src/main/js/views/templates/confirm.jade
+++ b/modules/web-control-center/src/main/js/views/templates/confirm.jade
@@ -18,10 +18,10 @@
     .modal-dialog
         .modal-content
             .modal-header
-                button.close(type="button" ng-click="$hide()") &times;
+                button.close(type='button' ng-click='$hide()') &times;
                 h4.modal-title Confirmation
             .modal-body(ng-show='content')
                 p(ng-bind-html='content' style='text-align: center;')
             .modal-footer
-                button.btn.btn-default(type="button" ng-click="$hide()") Cancel
-                button.btn.btn-primary(type="button" ng-click="ok()") Confirm
\ No newline at end of file
+                button.btn.btn-default(type='button' ng-click='$hide()') Cancel
+                button.btn.btn-primary(type='button' ng-click='ok()') Confirm
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/8af110a8/modules/web-control-center/src/main/js/views/templates/copy.jade
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/views/templates/copy.jade b/modules/web-control-center/src/main/js/views/templates/copy.jade
index 22cc64c..2ba9096 100644
--- a/modules/web-control-center/src/main/js/views/templates/copy.jade
+++ b/modules/web-control-center/src/main/js/views/templates/copy.jade
@@ -18,14 +18,14 @@
     .modal-dialog
         .modal-content
             .modal-header
-                button.close(type="button" ng-click="$hide()") &times;
+                button.close(type='button' ng-click='$hide()') &times;
                 h4.modal-title Copy
             form.form-horizontal(name='inputForm' novalidate)
                 .modal-body.row
                     .col-sm-9.login.col-sm-offset-1
                         label.required.labelFormField() New name:&nbsp;
                         .col-sm-9
-                            input.form-control(type="text" ng-model='newName' required)
+                            input.form-control(type='text' ng-model='newName' required)
             .modal-footer
-                button.btn.btn-default(type="button" ng-click="$hide()") Cancel
-                button.btn.btn-primary(type="button" ng-disabled='inputForm.$invalid' ng-click="ok(newName)") Confirm
\ No newline at end of file
+                button.btn.btn-default(type='button' ng-click='$hide()') Cancel
+                button.btn.btn-primary(type='button' ng-disabled='inputForm.$invalid' ng-click='ok(newName)') Confirm
\ No newline at end of file


[36/41] incubator-ignite git commit: # ignite-843 Rename

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/control-center-web/src/main/js/controllers/metadata-controller.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/controllers/metadata-controller.js b/modules/control-center-web/src/main/js/controllers/metadata-controller.js
new file mode 100644
index 0000000..c8fad8d
--- /dev/null
+++ b/modules/control-center-web/src/main/js/controllers/metadata-controller.js
@@ -0,0 +1,709 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+controlCenterModule.controller('metadataController', ['$scope', '$http', '$common', '$confirm', '$copy', '$table', function ($scope, $http, $common, $confirm, $copy, $table) {
+        $scope.joinTip = $common.joinTip;
+        $scope.getModel = $common.getModel;
+        $scope.javaBuildInTypes = $common.javaBuildInTypes;
+
+        $scope.tableReset = $table.tableReset;
+        $scope.tableNewItem = $table.tableNewItem;
+        $scope.tableNewItemActive = $table.tableNewItemActive;
+        $scope.tableEditing = $table.tableEditing;
+        $scope.tableStartEdit = $table.tableStartEdit;
+        $scope.tableRemove = $table.tableRemove;
+
+        $scope.tableSimpleSave = $table.tableSimpleSave;
+        $scope.tableSimpleSaveVisible = $table.tableSimpleSaveVisible;
+        $scope.tableSimpleUp = $table.tableSimpleUp;
+        $scope.tableSimpleDown = $table.tableSimpleDown;
+        $scope.tableSimpleDownVisible = $table.tableSimpleDownVisible;
+
+        $scope.tablePairSave = $table.tablePairSave;
+        $scope.tablePairSaveVisible = $table.tablePairSaveVisible;
+
+        $scope.templates = [
+            {value: {kind: 'query'}, label: 'query'},
+            {value: {kind: 'store'}, label: 'store'},
+            {value: {kind: 'both'}, label: 'both'}
+        ];
+
+        $scope.template = $scope.templates[0].value;
+
+        $scope.kinds = [
+            {value: 'query', label: 'query'},
+            {value: 'store', label: 'store'},
+            {value: 'both', label: 'both'}
+        ];
+
+        $scope.databases = [
+            {value: 'oracle', label: 'Oracle database'},
+            {value: 'db2', label: 'IBM DB2'},
+            {value: 'mssql', label: 'MS SQL Server'},
+            {value: 'postgre', label: 'PostgreSQL'},
+            {value: 'mysql', label: 'MySQL'},
+            {value: 'h2', label: 'H2 database'}
+        ];
+
+        $scope.jdbcTypes = [
+            {value: 'BIT', label: 'BIT'},
+            {value: 'BOOLEAN', label: 'BOOLEAN'},
+            {value: 'TINYINT', label: 'TINYINT'},
+            {value: 'SMALLINT', label: 'SMALLINT'},
+            {value: 'INTEGER', label: 'INTEGER'},
+            {value: 'BIGINT', label: 'BIGINT'},
+            {value: 'REAL', label: 'REAL'},
+            {value: 'FLOAT', label: 'FLOAT'},
+            {value: 'DOUBLE', label: 'DOUBLE'},
+            {value: 'NUMERIC', label: 'NUMERIC'},
+            {value: 'DECIMAL', label: 'DECIMAL'},
+            {value: 'CHAR', label: 'CHAR'},
+            {value: 'VARCHAR', label: 'VARCHAR'},
+            {value: 'LONGVARCHAR', label: 'LONGVARCHAR'},
+            {value: 'NCHAR', label: 'NCHAR'},
+            {value: 'NVARCHAR', label: 'NVARCHAR'},
+            {value: 'LONGNVARCHAR', label: 'LONGNVARCHAR'},
+            {value: 'DATE', label: 'DATE'},
+            {value: 'TIME', label: 'TIME'},
+            {value: 'TIMESTAMP', label: 'TIMESTAMP'}
+        ];
+
+        $scope.javaTypes = [
+            {value: 'boolean', label: 'boolean'},
+            {value: 'Boolean', label: 'Boolean'},
+            {value: 'byte', label: 'byte'},
+            {value: 'Byte', label: 'Byte'},
+            {value: 'short', label: 'short'},
+            {value: 'Short', label: 'Short'},
+            {value: 'int', label: 'int'},
+            {value: 'Integer', label: 'Integer'},
+            {value: 'long', label: 'long'},
+            {value: 'Long', label: 'Long'},
+            {value: 'float', label: 'float'},
+            {value: 'Float', label: 'Float'},
+            {value: 'double', label: 'double'},
+            {value: 'Double', label: 'Double'},
+            {value: 'BigDecimal', label: 'BigDecimal'},
+            {value: 'String', label: 'String'},
+            {value: 'Date', label: 'Date'},
+            {value: 'Time', label: 'Time'},
+            {value: 'Timestamp', label: 'Timestamp'}
+        ];
+
+        $scope.sortDirections = [
+            {value: false, label: 'ASC'},
+            {value: true, label: 'DESC'}
+        ];
+
+        $scope.data = {
+            curTableIdx: 0,
+            curFieldIdx: 0,
+            curKeyClass: '',
+            curValueClass: '',
+            curJavaName: '',
+            curJavaType: '',
+            tables: [
+                {schemaName: 'Schema1', use: true},
+                {
+                    schemaName: 'Schema1',
+                    use: true,
+                    tableName: 'Table1',
+                    keyClass: 'KeyClass1',
+                    valueClass: 'ValueClass1',
+                    fields: [
+                        {
+                            use: true,
+                            key: true,
+                            ak: true,
+                            databaseName: 'name1',
+                            databaseType: 'dbType1',
+                            javaName: 'javaName1',
+                            javaType: 'javaType1'
+                        },
+                        {
+                            use: true,
+                            key: false,
+                            ak: false,
+                            databaseName: 'name2',
+                            databaseType: 'dbType2',
+                            javaName: 'javaName2',
+                            javaType: 'javaType2'
+                        },
+                        {
+                            use: false,
+                            key: false,
+                            ak: false,
+                            databaseName: 'name3',
+                            databaseType: 'dbType3',
+                            javaName: 'javaName3',
+                            javaType: 'javaType3'
+                        }
+                    ]
+                },
+                {schemaName: 'Schema2 with very long name', use: false},
+                {
+                    schemaName: 'Schema2',
+                    use: false,
+                    tableName: 'Table2',
+                    keyClass: 'KeyClass2',
+                    valueClass: 'ValueClass2',
+                    fields: [
+                        {
+                            use: true,
+                            key: true,
+                            ak: true,
+                            databaseName: 'name4',
+                            databaseType: 'dbType4',
+                            javaName: 'javaName4',
+                            javaType: 'javaType4'
+                        },
+                        {
+                            use: true,
+                            key: false,
+                            ak: false,
+                            databaseName: 'name5',
+                            databaseType: 'dbType5',
+                            javaName: 'javaName5',
+                            javaType: 'javaType5'
+                        },
+                        {
+                            use: false,
+                            key: false,
+                            ak: false,
+                            databaseName: 'name6',
+                            databaseType: 'dbType6',
+                            javaName: 'javaName6',
+                            javaType: 'javaType6'
+                        }
+                    ]
+                },
+                {
+                    schemaName: 'Schema2',
+                    use: false,
+                    tableName: 'Table3',
+                    keyClass: 'KeyClass3',
+                    valueClass: 'ValueClass3',
+                    fields: [
+                        {
+                            use: true,
+                            key: true,
+                            ak: true,
+                            databaseName: 'name7',
+                            databaseType: 'dbType7',
+                            javaName: 'javaName7',
+                            javaType: 'javaType7'
+                        },
+                        {
+                            use: true,
+                            key: false,
+                            ak: false,
+                            databaseName: 'name8',
+                            databaseType: 'dbType8',
+                            javaName: 'javaName8',
+                            javaType: 'javaType8'
+                        },
+                        {
+                            use: false,
+                            key: false,
+                            ak: false,
+                            databaseName: 'name9',
+                            databaseType: 'dbType9',
+                            javaName: 'javaName9',
+                            javaType: 'javaType9'
+                        },
+                        {
+                            use: false,
+                            key: false,
+                            ak: false,
+                            databaseName: 'name10',
+                            databaseType: 'dbType10',
+                            javaName: 'javaName10',
+                            javaType: 'javaType10'
+                        },
+                        {
+                            use: false,
+                            key: false,
+                            ak: false,
+                            databaseName: 'name11',
+                            databaseType: 'dbType11',
+                            javaName: 'javaName11',
+                            javaType: 'javaType11'
+                        },
+                        {
+                            use: false,
+                            key: false,
+                            ak: false,
+                            databaseName: 'name12',
+                            databaseType: 'dbType12',
+                            javaName: 'javaName12',
+                            javaType: 'javaType12'
+                        }
+                    ]
+                }]
+        };
+
+        $scope.metadatas = [];
+
+        $http.get('/models/metadata.json')
+            .success(function (data) {
+                $scope.screenTip = data.screenTip;
+                $scope.templateTip = data.templateTip;
+                $scope.metadataManual = data.metadataManual;
+                $scope.metadataDb = data.metadataDb;
+            })
+            .error(function (errMsg) {
+                $common.showError(errMsg);
+            });
+
+        function selectFirstItem() {
+            if ($scope.metadatas.length > 0)
+                $scope.selectItem($scope.metadatas[0]);
+        }
+
+        function setSelectedAndBackupItem(sel, bak) {
+            $table.tableReset();
+
+            $scope.selectedItem = sel;
+            $scope.backupItem = bak;
+
+            $scope.panels.activePanel = [0];
+        }
+
+        // When landing on the page, get metadatas and show them.
+        $http.post('metadata/list')
+            .success(function (data) {
+                $scope.spaces = data.spaces;
+                $scope.metadatas = data.metadatas;
+
+                var restoredItem = angular.fromJson(sessionStorage.metadataBackupItem);
+
+                if (restoredItem) {
+                    if (restoredItem._id) {
+                        var idx = _.findIndex($scope.metadatas, function (metadata) {
+                            return metadata._id == restoredItem._id;
+                        });
+
+                        if (idx >= 0)
+                            setSelectedAndBackupItem($scope.metadatas[idx], restoredItem);
+                        else {
+                            sessionStorage.removeItem('metadataBackupItem');
+
+                            selectFirstItem();
+                        }
+                    }
+                    else
+                        setSelectedAndBackupItem(undefined, restoredItem);
+                }
+                else
+                    selectFirstItem();
+
+                $scope.$watch('backupItem', function (val) {
+                    if (val)
+                        sessionStorage.metadataBackupItem = angular.toJson(val);
+                }, true);
+            })
+            .error(function (errMsg) {
+                $common.showError(errMsg);
+            });
+
+        $scope.selectItem = function (item) {
+            setSelectedAndBackupItem(item, angular.copy(item));
+        };
+
+        // Add new metadata.
+        $scope.createItem = function () {
+            $table.tableReset();
+
+            $scope.backupItem = angular.copy($scope.template);
+            $scope.backupItem.space = $scope.spaces[0]._id;
+        };
+
+        // Check metadata logical consistency.
+        function validate(item) {
+            return true;
+        }
+
+        // Save cache type metadata into database.
+        function save(item) {
+            $http.post('metadata/save', item)
+                .success(function (_id) {
+                    $common.showInfo('Metadata "' + item.name + '" saved.');
+
+                    var idx = _.findIndex($scope.metadatas, function (metadata) {
+                        return metadata._id == _id;
+                    });
+
+                    if (idx >= 0)
+                        angular.extend($scope.metadatas[idx], item);
+                    else {
+                        item._id = _id;
+
+                        $scope.metadatas.push(item);
+                    }
+
+                    $scope.selectItem(item);
+
+                    $common.showInfo('Cache type metadata"' + item.name + '" saved.');
+                })
+                .error(function (errMsg) {
+                    $common.showError(errMsg);
+                });
+        }
+
+        // Save cache type metadata.
+        $scope.saveItem = function () {
+            $table.tableReset();
+
+            var item = $scope.backupItem;
+
+            if (validate(item))
+                save(item);
+        };
+
+        // Save cache type metadata with new name.
+        $scope.saveItemAs = function () {
+            $table.tableReset();
+
+            if (validate($scope.backupItem))
+                $copy.show($scope.backupItem.name).then(function (newName) {
+                    var item = angular.copy($scope.backupItem);
+
+                    item._id = undefined;
+                    item.name = newName;
+
+                    save(item);
+                });
+        };
+
+        $scope.removeItem = function () {
+            $table.tableReset();
+
+            var selectedItem = $scope.selectedItem;
+
+            $confirm.show('Are you sure you want to remove cache type metadata: "' + selectedItem.name + '"?').then(
+                function () {
+                    var _id = selectedItem._id;
+
+                    $http.post('metadata/remove', {_id: _id})
+                        .success(function () {
+                            $common.showInfo('Cache type metadata has been removed: ' + selectedItem.name);
+
+                            var metadatas = $scope.metadatas;
+
+                            var idx = _.findIndex(metadatas, function (metadata) {
+                                return metadata._id == _id;
+                            });
+
+                            if (idx >= 0) {
+                                metadatas.splice(idx, 1);
+
+                                if (metadatas.length > 0)
+                                    $scope.selectItem(metadatas[0]);
+                                else {
+                                    $scope.selectedItem = undefined;
+                                    $scope.backupItem = undefined;
+                                }
+                            }
+                        })
+                        .error(function (errMsg) {
+                            $common.showError(errMsg);
+                        });
+                });
+        };
+
+        $scope.tableSimpleValid = function (item, field, name, index) {
+            var model = item[field.model];
+
+            if ($common.isDefined(model)) {
+                var idx = _.indexOf(model, name);
+
+                // Found itself.
+                if (index >= 0 && index == idx)
+                    return true;
+
+                // Found duplicate.
+                if (idx >= 0) {
+                    $common.showError('Field with such name already exists!');
+
+                    return false;
+                }
+            }
+
+            return true;
+        };
+
+        $scope.tablePairValid = function (item, field, name, clsName, index) {
+            var model = item[field.model];
+
+            if ($common.isDefined(model)) {
+                var idx = _.findIndex(model, function (pair) {
+                    return pair.name == name
+                });
+
+                // Found itself.
+                if (index >= 0 && index == idx)
+                    return true;
+
+                // Found duplicate.
+                if (idx >= 0) {
+                    $common.showError('Field with such name already exists!');
+
+                    return false;
+                }
+            }
+
+            return true;
+        };
+
+        $scope.tableDbFieldSaveVisible = function (databaseName, databaseType, javaName, javaType) {
+            return $common.isNonEmpty(databaseName) && $common.isDefined(databaseType) &&
+                $common.isNonEmpty(javaName) && $common.isDefined(javaType);
+        };
+
+        $scope.tableDbFieldSave = function (field, newDatabaseName, newDatabaseType, newJavaName, newJavaType, index) {
+            var item = $scope.backupItem;
+
+            var model = item[field.model];
+
+            var newItem = {databaseName: newDatabaseName, databaseType: newDatabaseType, javaName: newJavaName, javaType: newJavaType};
+
+            if ($common.isDefined(model)) {
+                var idx = _.findIndex(model, function (dbMeta) {
+                    return dbMeta.databaseName == newDatabaseName
+                });
+
+                // Found duplicate.
+                if (idx >= 0 && index != idx) {
+                    $common.showError('DB field with such name already exists!');
+
+                    return;
+                }
+
+                if (index < 0) {
+                    if (model)
+                        model.push(newItem);
+                    else
+                        item[field.model] = [newItem];
+                }
+                else {
+                    var dbField = model[index];
+
+                    dbField.databaseName = newDatabaseName;
+                    dbField.databaseType = newDatabaseType;
+                    dbField.javaName = newJavaName;
+                    dbField.javaType = newJavaType;
+                }
+            }
+            else
+                item[field.model] = [newItem];
+
+            $table.tableReset();
+        };
+
+        $scope.tableGroupSaveVisible = function (group) {
+            return $common.isNonEmpty(group);
+        };
+
+        function tableGroupValid(groupName, index) {
+            var groups = $scope.backupItem.groups;
+
+            if ($common.isDefined(groups)) {
+                var idx = _.findIndex(groups, function (group) {
+                    return group.name == groupName;
+                });
+
+                // Found itself.
+                if (index >= 0 && index == idx)
+                    return true;
+
+                // Found duplicate.
+                if (idx >= 0) {
+                    $common.showError('Group with such name already exists!');
+
+                    return false;
+                }
+            }
+
+            return true;
+        }
+
+        $scope.tableGroupSave = function (groupName, index) {
+            if (tableGroupValid(groupName, index)) {
+                $table.tableReset();
+
+                var item = $scope.backupItem;
+
+                if (index < 0) {
+                    var newGroup = {name: groupName};
+
+                    if (item.groups)
+                        item.groups.push(newGroup);
+                    else
+                        item.groups = [newGroup];
+                }
+                else
+                    item.groups[index].name = groupName;
+            }
+        };
+
+        $scope.tableGroupNewItem = function (groupIndex) {
+            var groupName = $scope.backupItem.groups[groupIndex].name;
+
+            return $table.tableNewItem({model: groupName});
+        };
+
+        $scope.tableGroupNewItemActive = function (groupIndex) {
+            var groups = $scope.backupItem.groups;
+
+            if (groups) {
+                var group = groups[groupIndex];
+
+                if (group) {
+                    var groupName = group.name;
+
+                    return $table.tableNewItemActive({model: groupName});
+                }
+            }
+
+            return false;
+        };
+
+        $scope.tableGroupItemEditing = function (groupIndex, index) {
+            var groups = $scope.backupItem.groups;
+
+            if (groups) {
+                var group = groups[groupIndex];
+
+                if (group)
+                    return $table.tableEditing({model: group.name}, index);
+            }
+
+            return false;
+        };
+
+        $scope.tableGroupItemStartEdit = function (groupIndex, index) {
+            var groups = $scope.backupItem.groups;
+
+            $table.tableState(groups[groupIndex].name, index);
+
+            return groups[groupIndex].fields[index];
+        };
+
+        $scope.tableGroupItemSaveVisible = function (fieldName, className) {
+            return $common.isNonEmpty(fieldName) && $common.isNonEmpty(className);
+        };
+
+        function tableGroupItemValid(fieldName, groupIndex, index) {
+            var groupItems = $scope.backupItem.groups[groupIndex].fields;
+
+            if ($common.isDefined(groupItems)) {
+                var idx = _.findIndex(groupItems, function (groupItem) {
+                    return groupItem.name == fieldName;
+                });
+
+                // Found itself.
+                if (index >= 0 && index == idx)
+                    return true;
+
+                // Found duplicate.
+                if (idx >= 0) {
+                    $common.showError('Field with such name already exists in group!');
+
+                    return false;
+                }
+            }
+
+            return true;
+        }
+
+        $scope.tableGroupItemSave = function (fieldName, className, direction, groupIndex, index) {
+            if (tableGroupItemValid(fieldName, groupIndex, index)) {
+                $table.tableReset();
+
+                var group = $scope.backupItem.groups[groupIndex];
+
+                if (index < 0) {
+                    var newGroupItem = {name: fieldName, className: className, direction: direction};
+
+                    if (group.fields)
+                        group.fields.push(newGroupItem);
+                    else
+                        group.fields = [newGroupItem];
+                }
+                else {
+                    var groupItem = group.fields[index];
+
+                    groupItem.name = fieldName;
+                    groupItem.className = className;
+                    groupItem.direction = direction;
+                }
+            }
+        };
+
+        $scope.tableRemoveGroupItem = function (group, index) {
+            $table.tableReset();
+
+            group.fields.splice(index, 1);
+        };
+
+        $scope.selectSchema = function (idx) {
+            var data = $scope.data;
+            var tables = data.tables;
+            var schemaName = tables[idx].schemaName;
+            var use = tables[idx].use;
+
+            for (var i = idx + 1; i < tables.length; i++) {
+                var item = tables[i];
+
+                if (item.schemaName == schemaName && item.tableName)
+                    item.use = use;
+                else
+                    break;
+            }
+
+            data.curTableIdx = -1;
+            data.curFieldIdx = -1;
+        };
+
+        $scope.selectTable = function (idx) {
+            var data = $scope.data;
+
+            data.curTableIdx = idx;
+            data.curFieldIdx = -1;
+
+            if (idx >= 0) {
+                var tbl = data.tables[idx];
+
+                data.curKeyClass = tbl.keyClass;
+                data.curValueClass = tbl.valueClass;
+            }
+        };
+
+        $scope.selectField = function (idx) {
+            var data = $scope.data;
+
+            data.curFieldIdx = idx;
+
+            if (idx >= 0) {
+                var fld = data.tables[data.curTableIdx].fields[idx];
+
+                data.curJavaName = fld.javaName;
+                data.curJavaType = fld.javaType;
+            }
+        };
+    }]
+);
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/control-center-web/src/main/js/controllers/models/caches.json
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/controllers/models/caches.json b/modules/control-center-web/src/main/js/controllers/models/caches.json
new file mode 100644
index 0000000..932eecc
--- /dev/null
+++ b/modules/control-center-web/src/main/js/controllers/models/caches.json
@@ -0,0 +1,943 @@
+{
+  "screenTip": {
+    "workflowTitle": "Use caches view to:",
+    "workflowContent": [
+      "<ul>",
+      "  <li>Configure caches.</li>",
+      "  <li>Associate metadata with cache queries and/or cache store.</li>",
+      "</ul>"
+    ],
+    "whatsNextTitle": "What's next:",
+    "whatsNextContent": [
+      "<ul>",
+      "  <li>Configure clusters.</li>",
+      "  <li>Configure cache type metadata.</li>",
+      "  <li>Generate XML and java code on Summary view.</li>",
+      "</ul>"
+    ]
+  },
+  "general": [
+    {
+      "label": "Name",
+      "type": "text",
+      "model": "name",
+      "required": true,
+      "placeholder": "Input name",
+      "id": "defaultFocusId"
+    },
+    {
+      "label": "Mode",
+      "type": "dropdown",
+      "model": "mode",
+      "placeholder": "PARTITIONED",
+      "items": "modes",
+      "tip": [
+        "Cache modes:",
+        "<ul>",
+        "  <li>Partitioned - in this mode the overall key set will be divided into partitions and all partitions will be split equally between participating nodes.</li>",
+        "  <li>Replicated - in this mode all the keys are distributed to all participating nodes.</li>",
+        "  <li>Local - in this mode caches residing on different grid nodes will not know about each other.</li>",
+        "</ul>"
+      ]
+    },
+    {
+      "label": "Atomicity",
+      "type": "dropdown",
+      "model": "atomicityMode",
+      "placeholder": "ATOMIC",
+      "items": "atomicities",
+      "tip": [
+        "Atomicity:",
+        "<ul>",
+        "  <li>Transactional - in this mode specified fully ACID-compliant transactional cache behavior.</li>",
+        "  <li>Atomic - in this mode distributed transactions and distributed locking are not supported.</li>",
+        "</ul>"
+      ]
+    },
+    {
+      "label": "Backups",
+      "type": "number",
+      "model": "backups",
+      "hide": "backupItem.mode == 'LOCAL'",
+      "placeholder": 0,
+      "tip": [
+        "Number of nodes used to back up single partition for partitioned cache."
+      ]
+    },
+    {
+      "label": "Read from backup",
+      "type": "check",
+      "model": "readFromBackup",
+      "placeholder": true,
+      "hide": "!backupItem.backups || backupItem.mode == 'LOCAL'",
+      "tip": [
+        "Flag indicating whether data can be read from backup.",
+        "If not set then always get data from primary node (never from backup)."
+      ]
+    },
+    {
+      "label": "Copy on read",
+      "type": "check",
+      "model": "copyOnRead",
+      "placeholder": true,
+      "tip": [
+        "Flag indicating whether copy of of the value stored in cache should be created for cache operation implying return value.",
+        "Also if this flag is set copies are created for values passed to CacheInterceptor and to CacheEntryProcessor."
+      ]
+    },
+    {
+      "label": "Invalidate near cache",
+      "type": "check",
+      "model": "invalidate",
+      "tip": [
+        "Invalidation flag for near cache entries in transaction.",
+        "If set then values will be invalidated (nullified) upon commit in near cache."
+      ]
+    }
+  ],
+  "advanced": [
+    {
+      "label": "Concurrency control",
+      "tip": [
+        "Cache concurrent usage settings."
+      ],
+      "fields": [
+        {
+          "label": "Max async operations",
+          "type": "number",
+          "model": "maxConcurrentAsyncOperations",
+          "placeholder": 500,
+          "tip": [
+            "Maximum number of allowed concurrent asynchronous operations.",
+            "If 0 then number of concurrent asynchronous operations is unlimited."
+          ]
+        },
+        {
+          "label": "Default lock timeout",
+          "type": "number",
+          "model": "defaultLockTimeout",
+          "placeholder": 0,
+          "tip": [
+            "Default lock acquisition timeout.",
+            "If 0 then lock acquisition will never timeout."
+          ]
+        },
+        {
+          "label": "Entry versioning",
+          "type": "dropdown",
+          "model": "atomicWriteOrderMode",
+          "placeholder": "Choose versioning",
+          "items": "atomicWriteOrderModes",
+          "hide": "backupItem.atomicityMode == 'TRANSACTIONAL'",
+          "tip": [
+            "Write ordering mode determines which node assigns the write version, sender or the primary node.",
+            "<ul>",
+            "  <li>CLOCK - in this mode write versions are assigned on a sender node which generally leads to better performance.</li>",
+            "  <li>PRIMARY - in this mode version is assigned only on primary node. This means that sender will only send write request to primary node, which in turn will assign write version and forward it to backups.</li>",
+            "</ul>"
+          ]
+        }
+      ]
+    },
+    {
+      "label": "Memory",
+      "tip": [
+        "Cache memory settings."
+      ],
+      "fields": [
+        {
+          "label": "Mode",
+          "type": "dropdown",
+          "model": "memoryMode",
+          "placeholder": "ONHEAP_TIERED",
+          "items": "memoryModes",
+          "tip": [
+            "Memory modes:",
+            "<ul>",
+            "  <li>ONHEAP_TIERED - entries are cached on heap memory first.",
+            "    <ul>",
+            "      <li>If offheap memory is enabled and eviction policy evicts an entry from heap memory, entry will be moved to offheap memory. If offheap memory is disabled, then entry is simply discarded.</li>",
+            "      <li>If swap space is enabled and offheap memory fills up, then entry will be evicted into swap space. If swap space is disabled, then entry will be discarded. If swap is enabled and offheap memory is disabled, then entry will be evicted directly from heap memory into swap.</li>",
+            "    </ul>",
+            "  </li>",
+            "  <li>OFFHEAP_TIERED - works the same as ONHEAP_TIERED, except that entries never end up in heap memory and get stored in offheap memory right away. Entries get cached in offheap memory first and then get evicted to swap, if one is configured.</li>",
+            "  <li>OFFHEAP_VALUES - entry keys will be stored on heap memory, and values will be stored in offheap memory. Note that in this mode entries can be evicted only to swap.</li>",
+            "</ul>"
+          ]
+        },
+        {
+          "label": "Off-heap max memory",
+          "type": "number",
+          "model": "offHeapMaxMemory",
+          "min": -1,
+          "placeholder": -1,
+          "hide": "backupItem.memoryMode == 'OFFHEAP_VALUES'",
+          "tip": [
+            "Sets maximum amount of memory available to off-heap storage.",
+            "Possible values are:",
+            "<ul>",
+            "  <li>-1 - means that off-heap storage is disabled.</li>",
+            "  <li>0 - Ignite will not limit off-heap storage (it's up to user to properly add and remove entries from cache to ensure that off-heap storage does not grow infinitely.</li>",
+            "  <li>Any positive value specifies the limit of off-heap storage in bytes.</li>",
+            "</ul>"
+          ]
+        },
+        {
+          "label": "Eviction policy",
+          "type": "dropdown-details",
+          "path": "evictionPolicy",
+          "model": "kind",
+          "placeholder": "Choose eviction policy",
+          "items": "evictionPolicies",
+          "hide": "backupItem.memoryMode == 'OFFHEAP_TIERED'",
+          "tip": [
+            "Optional cache eviction policy. Must be set for entries to be evicted from on-heap to off-heap or swap."
+          ],
+          "details": {
+            "LRU": {
+              "expanded": false,
+              "fields": [
+                {
+                  "label": "Batch size",
+                  "type": "number",
+                  "path": "evictionPolicy.LRU",
+                  "model": "batchSize",
+                  "placeholder": 1,
+                  "tip": [
+                    "Number of entries to remove on shrink."
+                  ]
+                },
+                {
+                  "label": "Max memory size",
+                  "type": "number",
+                  "path": "evictionPolicy.LRU",
+                  "model": "maxMemorySize",
+                  "placeholder": 0,
+                  "tip": [
+                    "Maximum allowed cache size in bytes."
+                  ]
+                },
+                {
+                  "label": "Max size",
+                  "type": "number",
+                  "path": "evictionPolicy.LRU",
+                  "model": "maxSize",
+                  "placeholder": 100000,
+                  "tip": [
+                    "Maximum allowed size of cache before entry will start getting evicted."
+                  ]
+                }
+              ]
+            },
+            "RND": {
+              "expanded": false,
+              "fields": [
+                {
+                  "label": "Max size",
+                  "type": "number",
+                  "path": "evictionPolicy.RND",
+                  "model": "maxSize",
+                  "placeholder": 100000,
+                  "tip": [
+                    "Maximum allowed size of cache before entry will start getting evicted."
+                  ]
+                }
+              ]
+            },
+            "FIFO": {
+              "expanded": false,
+              "fields": [
+                {
+                  "label": "Batch size",
+                  "type": "number",
+                  "path": "evictionPolicy.FIFO",
+                  "model": "batchSize",
+                  "placeholder": 1,
+                  "tip": [
+                    "Number of entries to remove on shrink."
+                  ]
+                },
+                {
+                  "label": "Max memory size",
+                  "type": "number",
+                  "path": "evictionPolicy.FIFO",
+                  "model": "maxMemorySize",
+                  "placeholder": 0,
+                  "tip": [
+                    "Maximum allowed cache size in bytes."
+                  ]
+                },
+                {
+                  "label": "Max size",
+                  "type": "number",
+                  "path": "evictionPolicy.FIFO",
+                  "model": "maxSize",
+                  "placeholder": 100000,
+                  "tip": [
+                    "Maximum allowed size of cache before entry will start getting evicted."
+                  ]
+                }
+              ]
+            },
+            "SORTED": {
+              "expanded": false,
+              "fields": [
+                {
+                  "label": "Batch size",
+                  "type": "number",
+                  "path": "evictionPolicy.SORTED",
+                  "model": "batchSize",
+                  "placeholder": 1,
+                  "tip": [
+                    "Number of entries to remove on shrink."
+                  ]
+                },
+                {
+                  "label": "Max memory size",
+                  "type": "number",
+                  "path": "evictionPolicy.SORTED",
+                  "model": "maxMemorySize",
+                  "placeholder": 0,
+                  "tip": [
+                    "Maximum allowed cache size in bytes."
+                  ]
+                },
+                {
+                  "label": "Max size",
+                  "type": "number",
+                  "path": "evictionPolicy.SORTED",
+                  "model": "maxSize",
+                  "placeholder": 100000,
+                  "tip": [
+                    "Maximum allowed size of cache before entry will start getting evicted."
+                  ]
+                }
+              ]
+            }
+          }
+        },
+        {
+          "label": "Start size",
+          "type": "number",
+          "model": "startSize",
+          "placeholder": 1500000,
+          "tip": [
+            "Initial cache size which will be used to pre-create internal hash table after start."
+          ]
+        },
+        {
+          "label": "Swap enabled",
+          "type": "check",
+          "model": "swapEnabled",
+          "tip": [
+            "Flag indicating whether swap storage is enabled or not for this cache."
+          ]
+        }
+      ]
+    },
+    {
+      "label": "Query",
+      "tip": [
+        "Cache query settings."
+      ],
+      "fields": [
+        {
+          "label": "Escape table and filed names",
+          "type": "check",
+          "model": "sqlEscapeAll",
+          "tip": [
+            "If set then all the SQL table and field names will be escaped with double quotes.",
+            "This enforces case sensitivity for field names and also allows having special characters in table and field names."
+          ]
+        },
+        {
+          "label": "On-heap cache for off-heap indexes",
+          "type": "number",
+          "model": "sqlOnheapRowCacheSize",
+          "placeholder": 10240,
+          "tip": [
+            "Number of SQL rows which will be cached onheap to avoid deserialization on each SQL index access."
+          ]
+        },
+        {
+          "label": "Long query timeout",
+          "type": "number",
+          "model": "longQueryWarningTimeout",
+          "placeholder": 3000,
+          "tip": [
+            "Timeout in milliseconds after which long query warning will be printed."
+          ]
+        },
+        {
+          "label": "Metadata",
+          "type": "dropdown-multiple",
+          "model": "queryMetadata",
+          "placeholder": "Choose metadata",
+          "items": "queryMetadata",
+          "tip": [
+            "Select cache type metadata to describe types in cache."
+          ],
+          "addLink": {
+            "label": "Add metadata(s)",
+            "ref": "/configuration/metadata"
+          }
+        } ,
+        {
+          "type": "indexedTypes",
+          "model": "indexedTypes",
+          "keyName": "keyClass",
+          "valueName": "valueClass",
+          "focusNewItemId": "newIndexedType",
+          "focusCurItemId": "curIndexedType",
+          "addTip": "Add new key and value classes to indexed types.",
+          "removeTip": "Remove item from indexed types.",
+          "tip": [
+            "Collection of types to index."
+          ]
+        },
+        {
+          "label": "SQL functions",
+          "type": "table-simple",
+          "model": "sqlFunctionClasses",
+          "editIdx": -1,
+          "placeholder": "SQL function full class name",
+          "focusNewItemId": "newSqlFxField",
+          "focusCurItemId": "curSqlFxField",
+          "addTip": "Add new user-defined functions for SQL queries.",
+          "removeTip": "Remove user-defined function.",
+          "tableTip": [
+            "Collections of classes with user-defined functions for SQL queries."
+          ],
+          "tip": [
+            "Class with user-defined functions for SQL queries."
+          ]
+        }
+      ]
+    },
+    {
+      "label": "Rebalance",
+      "tip": [
+        "Cache rebalance settings."
+      ],
+      "fields": [
+        {
+          "label": "Mode",
+          "type": "dropdown",
+          "model": "rebalanceMode",
+          "placeholder": "ASYNC",
+          "items": "rebalanceModes",
+          "tip": [
+            "Rebalance modes:",
+            "<ul>",
+            "  <li>Synchronous - in this mode distributed caches will not start until all necessary data is loaded from other available grid nodes.</li>",
+            "  <li>Asynchronous - in this mode distributed caches will start immediately and will load all necessary data from other available grid nodes in the background.</li>",
+            "  <li>None - in this mode no rebalancing will take place which means that caches will be either loaded on demand from persistent store whenever data is accessed, or will be populated explicitly.</li>",
+            "</ul>"
+          ]
+        },
+        {
+          "label": "Pool size",
+          "type": "number",
+          "model": "rebalanceThreadPoolSize",
+          "placeholder": 2,
+          "tip": [
+            "Size of rebalancing thread pool.<br>",
+            "Note that size serves as a hint and implementation may create more threads for rebalancing than specified here (but never less threads)."
+          ]
+        },
+        {
+          "label": "Batch size",
+          "type": "number",
+          "model": "rebalanceBatchSize",
+          "placeholder": "512 * 1024",
+          "tip": [
+            "Size (in bytes) to be loaded within a single rebalance message.",
+            "Rebalancing algorithm will split total data set on every node into multiple batches prior to sending data."
+          ]
+        },
+        {
+          "label": "Order",
+          "type": "number",
+          "model": "rebalanceOrder",
+          "placeholder": 0,
+          "tip": [
+            "If cache rebalance order is positive, rebalancing for this cache will be started only when rebalancing for all caches with smaller rebalance order (except caches with rebalance order 0) will be completed."
+          ]
+        },
+        {
+          "label": "Delay",
+          "type": "number",
+          "model": "rebalanceDelay",
+          "placeholder": 0,
+          "tip": [
+            "Delay in milliseconds upon a node joining or leaving topology (or crash) after which rebalancing should be started automatically."
+          ]
+        },
+        {
+          "label": "Timeout",
+          "type": "number",
+          "model": "rebalanceTimeout",
+          "placeholder": 10000,
+          "tip": [
+            "Rebalance timeout in milliseconds."
+          ]
+        },
+        {
+          "label": "Throttle",
+          "type": "number",
+          "model": "rebalanceThrottle",
+          "placeholder": 0,
+          "tip": [
+            "Time in milliseconds to wait between rebalance messages to avoid overloading of CPU or network."
+          ]
+        }
+      ]
+    },
+    {
+      "label": "Server near cache",
+      "tip": [
+        "Near cache settings.",
+        "Near cache is a small local cache that stores most recently or most frequently accessed data.",
+        "Should be used in case when it is impossible to send computations to remote nodes."
+      ],
+      "fields": [
+        {
+          "label": "Enabled",
+          "type": "check",
+          "model": "nearCacheEnabled",
+          "tip": [
+            "Flag indicating whether to configure near cache."
+          ]
+        },
+        {
+          "label": "Start size",
+          "type": "number",
+          "path": "nearConfiguration",
+          "model": "nearStartSize",
+          "hide": "!backupItem.nearCacheEnabled",
+          "placeholder": 375000,
+          "tip": [
+            "Initial cache size for near cache which will be used to pre-create internal hash table after start."
+          ]
+        },
+        {
+          "label": "Eviction policy",
+          "type": "dropdown-details",
+          "path": "nearConfiguration.nearEvictionPolicy",
+          "model": "kind",
+          "placeholder": "Choose eviction policy",
+          "items": "evictionPolicies",
+          "hide": "!backupItem.nearCacheEnabled",
+          "tip": [
+            "Cache expiration policy."
+          ],
+          "details": {
+            "LRU": {
+              "expanded": false,
+              "fields": [
+                {
+                  "label": "Batch size",
+                  "type": "number",
+                  "path": "nearConfiguration.nearEvictionPolicy.LRU",
+                  "model": "batchSize",
+                  "placeholder": 1,
+                  "tip": [
+                    "Number of entries to remove on shrink."
+                  ]
+                },
+                {
+                  "label": "Max memory size",
+                  "type": "number",
+                  "path": "nearConfiguration.nearEvictionPolicy.LRU",
+                  "model": "maxMemorySize",
+                  "placeholder": 0,
+                  "tip": [
+                    "Maximum allowed cache size in bytes."
+                  ]
+                },
+                {
+                  "label": "Max size",
+                  "type": "number",
+                  "path": "nearConfiguration.nearEvictionPolicy.LRU",
+                  "model": "maxSize",
+                  "placeholder": 100000,
+                  "tip": [
+                    "Maximum allowed size of cache before entry will start getting evicted."
+                  ]
+                }
+              ]
+            },
+            "RND": {
+              "expanded": false,
+              "fields": [
+                {
+                  "label": "Max size",
+                  "type": "number",
+                  "path": "nearConfiguration.nearEvictionPolicy.RND",
+                  "model": "maxSize",
+                  "placeholder": 100000,
+                  "tip": [
+                    "Maximum allowed size of cache before entry will start getting evicted."
+                  ]
+                }
+              ]
+            },
+            "FIFO": {
+              "expanded": false,
+              "fields": [
+                {
+                  "label": "Batch size",
+                  "type": "number",
+                  "path": "nearConfiguration.nearEvictionPolicy.FIFO",
+                  "model": "batchSize",
+                  "placeholder": 1,
+                  "tip": [
+                    "Number of entries to remove on shrink."
+                  ]
+                },
+                {
+                  "label": "Max memory size",
+                  "type": "number",
+                  "path": "nearConfiguration.nearEvictionPolicy.FIFO",
+                  "model": "maxMemorySize",
+                  "placeholder": 0,
+                  "tip": [
+                    "Maximum allowed cache size in bytes."
+                  ]
+                },
+                {
+                  "label": "Max size",
+                  "type": "number",
+                  "path": "nearConfiguration.nearEvictionPolicy.FIFO",
+                  "model": "maxSize",
+                  "placeholder": 100000,
+                  "tip": [
+                    "Maximum allowed size of cache before entry will start getting evicted."
+                  ]
+                }
+              ]
+            },
+            "SORTED": {
+              "expanded": false,
+              "fields": [
+                {
+                  "label": "Batch size",
+                  "type": "number",
+                  "path": "nearConfiguration.nearEvictionPolicy.SORTED",
+                  "model": "batchSize",
+                  "placeholder": 1,
+                  "tip": [
+                    "Number of entries to remove on shrink."
+                  ]
+                },
+                {
+                  "label": "Max memory size",
+                  "type": "number",
+                  "path": "nearConfiguration.nearEvictionPolicy.SORTED",
+                  "model": "maxMemorySize",
+                  "placeholder": 0,
+                  "tip": [
+                    "Maximum allowed cache size in bytes."
+                  ]
+                },
+                {
+                  "label": "Max size",
+                  "type": "number",
+                  "path": "nearConfiguration.nearEvictionPolicy.SORTED",
+                  "model": "maxSize",
+                  "placeholder": 100000,
+                  "tip": [
+                    "Maximum allowed size of cache before entry will start getting evicted."
+                  ]
+                }
+              ]
+            }
+          }
+        }
+      ]
+    },
+    {
+      "label": "Statistics",
+      "tip": [
+        "Cache statistics and management settings."
+      ],
+      "fields": [
+        {
+          "label": "Statistics enabled",
+          "type": "check",
+          "model": "statisticsEnabled",
+          "tip": [
+            "Flag indicating whether statistics gathering is enabled on a cache."
+          ]
+        },
+        {
+          "label": "Management enabled",
+          "type": "check",
+          "model": "managementEnabled",
+          "tip": [
+            "Flag indicating whether management is enabled on this cache."
+          ]
+        }
+      ]
+    },
+    {
+      "label": "Store",
+      "tip": [
+        "Cache store settings."
+      ],
+      "fields": [
+        {
+          "label": "Store factory",
+          "type": "dropdown-details",
+          "path": "cacheStoreFactory",
+          "model": "kind",
+          "placeholder": "Choose store factory",
+          "items": "cacheStoreFactories",
+          "tip": [
+            "Factory for persistent storage for cache data."
+          ],
+          "details": {
+            "CacheJdbcPojoStoreFactory": {
+              "expanded": true,
+              "fields": [
+                {
+                  "label": "Data source bean",
+                  "type": "text",
+                  "path": "cacheStoreFactory.CacheJdbcPojoStoreFactory",
+                  "model": "dataSourceBean",
+                  "required": true,
+                  "placeholder": "Bean name in Spring context",
+                  "tip": [
+                    "Name of the data source bean in Spring context."
+                  ]
+                },
+                {
+                  "label": "Dialect",
+                  "type": "dropdown",
+                  "path": "cacheStoreFactory.CacheJdbcPojoStoreFactory",
+                  "model": "dialect",
+                  "required": true,
+                  "placeholder": "Choose JDBC dialect",
+                  "items": "cacheStoreJdbcDialects",
+                  "tip": [
+                    "Dialect of SQL implemented by a particular RDBMS:",
+                    "<ul>",
+                    "  <li>Generic JDBC dialect.</li>",
+                    "  <li>Oracle database.</li>",
+                    "  <li>IBM DB2.</li>",
+                    "  <li>Microsoft SQL Server.</li>",
+                    "  <li>My SQL.</li>",
+                    "  <li>H2 database.</li>",
+                    "</ul>"
+                  ]
+                }
+              ]
+            },
+            "CacheJdbcBlobStoreFactory": {
+              "expanded": true,
+              "fields": [
+                {
+                  "label": "user",
+                  "type": "text",
+                  "path": "cacheStoreFactory.CacheJdbcBlobStoreFactory",
+                  "model": "user",
+                  "required": true,
+                  "tip": [
+                    "User name for database access."
+                  ]
+                },
+                {
+                  "label": "Data source bean",
+                  "type": "text",
+                  "path": "cacheStoreFactory.CacheJdbcBlobStoreFactory",
+                  "model": "dataSourceBean",
+                  "required": true,
+                  "placeholder": "Bean name in Spring context",
+                  "tip": [
+                    "Name of the data source bean in Spring context."
+                  ]
+                },
+                {
+                  "label": "Init schema",
+                  "type": "check",
+                  "path": "cacheStoreFactory.CacheJdbcBlobStoreFactory",
+                  "model": "initSchema",
+                  "tip": [
+                    "Flag indicating whether DB schema should be initialized by Ignite (default behaviour) or was explicitly created by user."
+                  ]
+                },
+                {
+                  "label": "Create query",
+                  "type": "text",
+                  "path": "cacheStoreFactory.CacheJdbcBlobStoreFactory",
+                  "model": "createTableQuery",
+                  "placeholder": "SQL for table creation",
+                  "tip": [
+                    "Query for table creation in underlying database.",
+                    "Default value: create table if not exists ENTRIES (key binary primary key, val binary)"
+                  ]
+                },
+                {
+                  "label": "Load query",
+                  "type": "text",
+                  "path": "cacheStoreFactory.CacheJdbcBlobStoreFactory",
+                  "model": "loadQuery",
+                  "placeholder": "SQL for load entry",
+                  "tip": [
+                    "Query for entry load from underlying database.",
+                    "Default value: select * from ENTRIES where key=?"
+                  ]
+                },
+                {
+                  "label": "Insert query",
+                  "type": "text",
+                  "path": "cacheStoreFactory.CacheJdbcBlobStoreFactory",
+                  "model": "insertQuery",
+                  "placeholder": "SQL for insert entry",
+                  "tip": [
+                    "Query for insert entry into underlying database.",
+                    "Default value: insert into ENTRIES (key, val) values (?, ?)"
+                  ]
+                },
+                {
+                  "label": "Update query",
+                  "type": "text",
+                  "path": "cacheStoreFactory.CacheJdbcBlobStoreFactory",
+                  "model": "updateQuery",
+                  "placeholder": "SQL for update entry",
+                  "tip": [
+                    "Query fpr update entry in underlying database.",
+                    "Default value: update ENTRIES set val=? where key=?"
+                  ]
+                },
+                {
+                  "label": "Delete query",
+                  "type": "text",
+                  "path": "cacheStoreFactory.CacheJdbcBlobStoreFactory",
+                  "model": "deleteQuery",
+                  "placeholder": "SQL for delete entry",
+                  "tip": [
+                    "Query for delete entry from underlying database.",
+                    "Default value: delete from ENTRIES where key=?"
+                  ]
+                }
+              ]
+            },
+            "CacheHibernateBlobStoreFactory": {
+              "expanded": true,
+              "fields": [
+                {
+                  "label": "Hibernate properties",
+                  "type": "table-simple",
+                  "path": "cacheStoreFactory.CacheHibernateBlobStoreFactory",
+                  "model": "hibernateProperties",
+                  "editIdx": -1,
+                  "placeholder": "key=value",
+                  "addTip": "Add new Hibernate property.",
+                  "removeTip": "Remove Hibernate property.",
+                  "tip": [
+                    "List of Hibernate properties.",
+                    "For example: connection.url=jdbc:h2:mem:"
+                  ]
+                }
+              ]
+            }
+          }
+        },
+        {
+          "label": "Load previous value",
+          "type": "check",
+          "model": "loadPreviousValue",
+          "tip": [
+            "Flag indicating whether value should be loaded from store if it is not in the cache for following cache operations:",
+            "<ul>",
+            "  <li>IgniteCache.putIfAbsent()</li>",
+            "  <li>IgniteCache.replace()</li>",
+            "  <li>IgniteCache.replace()</li>",
+            "  <li>IgniteCache.remove()</li>",
+            "  <li>IgniteCache.getAndPut()</li>",
+            "  <li>IgniteCache.getAndRemove()</li>",
+            "  <li>IgniteCache.getAndReplace()</li>",
+            "  <li>IgniteCache.getAndPutIfAbsent()</li>",
+            "</ul>"
+          ]
+        },
+        {
+          "label": "Read-through",
+          "type": "check",
+          "model": "readThrough",
+          "tip": [
+            "Flag indicating whether read-through caching should be used."
+          ]
+        },
+        {
+          "label": "Write-through",
+          "type": "check",
+          "model": "writeThrough",
+          "tip": [
+            "Flag indicating whether write-through caching should be used."
+          ]
+        }
+      ]
+    },
+    {
+      "label": "Write behind",
+      "tip": [
+        "Cache write behind settings.",
+        "Write-behind is a special mode when updates to cache accumulated and then asynchronously flushed to persistent store as a bulk operation."
+      ],
+      "fields": [
+        {
+          "label": "Enabled",
+          "type": "check",
+          "model": "writeBehindEnabled",
+          "tip": [
+            "Flag indicating whether Ignite should use write-behind behaviour for the cache store."
+          ]
+        },
+        {
+          "label": "Batch size",
+          "type": "number",
+          "model": "writeBehindBatchSize",
+          "hide": "!backupItem.writeBehindEnabled",
+          "placeholder": 512,
+          "tip": [
+            "Maximum batch size for write-behind cache store operations.",
+            "Store operations (get or remove) are combined in a batch of this size to be passed to cache store."
+          ]
+        },
+        {
+          "label": "Flush size",
+          "type": "number",
+          "model": "writeBehindFlushSize",
+          "hide": "!backupItem.writeBehindEnabled",
+          "placeholder": 10240,
+          "tip": [
+            "Maximum size of the write-behind cache.<br>",
+            "If cache size exceeds this value, all cached items are flushed to the cache store and write cache is cleared."
+          ]
+        },
+        {
+          "label": "Flush frequency",
+          "type": "number",
+          "model": "writeBehindFlushFrequency",
+          "hide": "!backupItem.writeBehindEnabled",
+          "placeholder": 5000,
+          "tip": [
+            "Frequency with which write-behind cache is flushed to the cache store in milliseconds."
+          ]
+        },
+        {
+          "label": "Flush threads count",
+          "type": "number",
+          "model": "writeBehindFlushThreadCount",
+          "hide": "!backupItem.writeBehindEnabled",
+          "placeholder": 1,
+          "tip": [
+            "Number of threads that will perform cache flushing."
+          ]
+        }
+      ]
+    }
+  ]
+}


[41/41] incubator-ignite git commit: # ignite-1121 Sql tab

Posted by an...@apache.org.
# ignite-1121 Sql tab


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

Branch: refs/heads/ignite-1121
Commit: e24f3b74bdf6a3bb5171717537fb834532e4f0b3
Parents: 6ecf626
Author: Andrey <an...@gridgain.com>
Authored: Fri Jul 31 09:29:28 2015 +0700
Committer: Andrey <an...@gridgain.com>
Committed: Fri Jul 31 09:29:28 2015 +0700

----------------------------------------------------------------------
 .../src/main/js/agents/agent-manager.js         | 283 +++++++++++++++++++
 .../src/main/js/agents/agent-server.js          |  90 ++++++
 modules/control-center-web/src/main/js/app.js   |   8 +-
 .../src/main/js/controllers/common-module.js    |  26 +-
 .../src/main/js/controllers/sql-controller.js   |  22 +-
 modules/control-center-web/src/main/js/db.js    |  12 +
 .../src/main/js/keys/test.crt                   |  13 +
 .../src/main/js/keys/test.key                   |  18 ++
 .../src/main/js/routes/agent.js                 |  84 ++++++
 .../src/main/js/routes/notebooks.js             | 102 +++++++
 .../src/main/js/routes/sql.js                   |   4 +-
 .../src/main/js/views/includes/header.jade      |   7 +-
 .../src/main/js/views/sql/sql.jade              |   3 +-
 .../src/test/js/routes/agent.js                 |  94 ++++++
 modules/nodejs/src/main/js/cluster-node.js      |  23 +-
 modules/nodejs/src/main/js/ignite.js            |   5 +-
 .../http/jetty/GridJettyJsonConfig.java         |   3 +
 .../src/main/js/agents/agent-manager.js         | 283 -------------------
 .../src/main/js/agents/agent-server.js          |  90 ------
 .../src/main/js/keys/test.crt                   |  13 -
 .../src/main/js/keys/test.key                   |  18 --
 .../src/main/js/routes/agent.js                 |  84 ------
 .../src/test/js/routes/agent.js                 |  94 ------
 23 files changed, 778 insertions(+), 601 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e24f3b74/modules/control-center-web/src/main/js/agents/agent-manager.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/agents/agent-manager.js b/modules/control-center-web/src/main/js/agents/agent-manager.js
new file mode 100644
index 0000000..10d3a56
--- /dev/null
+++ b/modules/control-center-web/src/main/js/agents/agent-manager.js
@@ -0,0 +1,283 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var WebSocketServer = require('ws').Server;
+
+var apacheIgnite = require('apache-ignite');
+
+var db = require('../db');
+
+var AgentServer = require('./agent-server').AgentServer;
+
+/**
+ * @constructor
+ */
+function AgentManager(srv) {
+    this._clients = {};
+
+    this._server = srv;
+
+    this._wss = new WebSocketServer({ server: this._server });
+
+    var self = this;
+
+    this._wss.on('connection', function(ws) {
+        var client = new Client(ws, self);
+    });
+}
+
+/**
+ * @param userId
+ * @param {Client} client
+ */
+AgentManager.prototype._removeClient = function(userId, client) {
+    var connections = this._clients[userId];
+
+    if (connections) {
+        removeFromArray(connections, client);
+
+        if (connections.length == 0)
+            delete this._clients[userId];
+    }
+};
+
+/**
+ * @param userId
+ * @param {Client} client
+ */
+AgentManager.prototype._addClient = function(userId, client) {
+    var existingConnections = this._clients[userId];
+
+    if (!existingConnections) {
+        existingConnections = [];
+
+        this._clients[userId] = existingConnections;
+    }
+
+    existingConnections.push(client);
+};
+
+/**
+ * @param userId
+ * @return {Client}
+ */
+AgentManager.prototype.findClient = function(userId) {
+    var clientsList = this._clients[userId];
+
+    if (!clientsList)
+        return null;
+
+    return clientsList[0];
+};
+
+/**
+ * For tests only!!!
+ * @return {Client}
+ */
+AgentManager.prototype.getOneClient = function() {
+    for (var userId in this._clients) {
+        if (this._clients.hasOwnProperty(userId)) {
+            var m = this._clients[userId];
+
+            if (m.length > 0)
+                return m[0];
+        }
+    }
+
+    return null;
+};
+
+
+/**
+ * @constructor
+ * @param {AgentManager} manager
+ * @param {WebSocket} ws
+ */
+function Client(ws, manager) {
+    var self = this;
+
+    this._manager = manager;
+    this._ws = ws;
+
+    ws.on('close', function() {
+        if (self.user) {
+            self._manager._removeClient(self.user._id, self);
+        }
+    });
+
+    ws.on('message', function (msg) {
+        self._handleMessage(JSON.parse(msg))
+    });
+
+    this._restCounter = 0;
+
+    this._cbMap = {};
+}
+
+/**
+ * @param {String|Object} msg
+ * @param {Function} cb
+ */
+Client.prototype.sendMessage = function(msg, cb) {
+    if (typeof msg == 'object') {
+        msg = JSON.stringify(msg);
+    }
+
+    this._ws.send(msg, cb);
+};
+
+/**
+ * @param {String} path
+ * @param {Object} params
+ * @param {Function} cb
+ * @param {String} method
+ * @param {String} body
+ * @param {Object} headers
+ */
+Client.prototype.invokeRest = function(path, params, cb, method, body, headers) {
+    var self = this;
+
+    if (typeof(params) != 'object')
+        throw "'params' argument must be an object";
+
+    if (typeof(cb) != 'function')
+        throw "callback must be a function";
+
+    if (body && typeof(body) != 'string')
+        throw "body must be a string";
+
+    if (headers && typeof(headers) != 'object')
+        throw "headers must be an object";
+
+    if (!method)
+        method = 'GET';
+    else
+        method = method.toUpperCase();
+
+    if (method != 'GET' && method != 'POST')
+        throw "Unknown HTTP method: " + method;
+
+    var reqId = this._restCounter++;
+
+    this._cbMap[reqId] = cb;
+
+    this.sendMessage({
+        id: reqId,
+        type: 'RestRequest',
+        method: method,
+        params: params,
+        path: path,
+        body: body,
+        headers: headers
+    }, function(err) {
+        if (err) {
+            delete self._cbMap[reqId];
+
+            cb(err)
+        }
+    })
+};
+
+/**
+ * @param {Object} msg
+ */
+Client.prototype._handleMessage = function(msg) {
+    var self = this;
+
+    switch (msg.type) {
+        case 'AuthMessage':
+            var account = db.Account.findByUsername(msg.login, function(err, account) {
+                if (err) {
+                    ws.send("{type: 'AuthResult', success: false}");
+                }
+                else {
+                    account.authenticate(msg.password, function(err, user, res) {
+                        if (!user) {
+                            self._ws.send(JSON.stringify({type: 'AuthResult', success: false, message: res.message}));
+                        }
+                        else {
+                            self._ws.send("{type: 'AuthResult', success: true}");
+
+                            self._user = account;
+
+                            self._manager._addClient(account._id, self);
+
+                            self._ignite = new apacheIgnite.Ignite(new AgentServer(self));
+                        }
+                    });
+                }
+            });
+
+            break;
+
+        case 'RestResult':
+            var cb = this._cbMap[msg.requestId];
+
+            if (!cb)
+                break;
+
+            delete this._cbMap[msg.requestId];
+
+            if (!msg.executed) {
+                cb(msg.message)
+            }
+            else {
+                cb(null, msg.code, msg.message)
+            }
+
+            break;
+
+        default:
+            this._ws.close()
+    }
+};
+
+/**
+ * @return {Ignite}
+ */
+Client.prototype.ignite = function() {
+    return this._ignite;
+};
+
+function removeFromArray(arr, val) {
+    var idx;
+
+    while ((idx = arr.indexOf(val)) !== -1) {
+        arr.splice(idx, 1);
+    }
+}
+
+exports.AgentManager = AgentManager;
+
+/**
+ * @type {AgentManager}
+ */
+var manager = null;
+
+exports.createManager = function(srv) {
+    if (manager)
+        throw "Agent manager already cleared!";
+
+    manager = new AgentManager(srv);
+};
+
+/**
+ * @return {AgentManager}
+ */
+exports.getAgentManager = function() {
+    return manager;
+};

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e24f3b74/modules/control-center-web/src/main/js/agents/agent-server.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/agents/agent-server.js b/modules/control-center-web/src/main/js/agents/agent-server.js
new file mode 100644
index 0000000..31dee5a
--- /dev/null
+++ b/modules/control-center-web/src/main/js/agents/agent-server.js
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Creates an instance of server for Ignite
+ *
+ * @constructor
+ * @this {AgentServer}
+ * @param {Client} client connected client
+ */
+function AgentServer(client) {
+    this._client = client;
+}
+
+/**
+ * Run http request
+ *
+ * @this {AgentServer}
+ * @param {Command} cmd Command
+ * @param {callback} callback on finish
+ */
+AgentServer.prototype.runCommand = function(cmd, callback) {
+    var params = {cmd: cmd.name()};
+
+    for (var p of cmd._params) {
+        params[p.key] = p.value;
+    }
+
+    var body = undefined;
+
+    var headers = undefined;
+
+    if (cmd._isPost()) {
+        body = cmd.postData();
+
+        headers = {'Content-Length': body.length, 'JSONObject': 'application/json'};
+    }
+
+    this._client.invokeRest("ignite", params, function(error, code, message) {
+        if (error) {
+            callback(error);
+            return
+        }
+
+        if (code !== 200) {
+            if (code === 401) {
+                callback.call(null, "Authentication failed. Status code 401.");
+            }
+            else {
+                callback.call(null, "Request failed. Status code " + code);
+            }
+
+            return;
+        }
+
+        var igniteResponse;
+
+        try {
+            igniteResponse = JSON.parse(message);
+        }
+        catch (e) {
+            callback.call(null, e, null);
+
+            return;
+        }
+
+        if (igniteResponse.successStatus) {
+            callback.call(null, igniteResponse.error, null)
+        }
+        else {
+            callback.call(null, null, igniteResponse.response);
+        }
+    }, cmd._method(), body, headers);
+};
+
+exports.AgentServer = AgentServer;

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e24f3b74/modules/control-center-web/src/main/js/app.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app.js b/modules/control-center-web/src/main/js/app.js
index 930c798..7741822 100644
--- a/modules/control-center-web/src/main/js/app.js
+++ b/modules/control-center-web/src/main/js/app.js
@@ -26,6 +26,7 @@ var session = require('express-session');
 var mongoStore = require('connect-mongo')(session);
 
 var publicRoutes = require('./routes/public');
+var notebooksRoutes = require('./routes/notebooks');
 var clustersRouter = require('./routes/clusters');
 var cachesRouter = require('./routes/caches');
 var metadataRouter = require('./routes/metadata');
@@ -123,8 +124,11 @@ app.use('/configuration/clusters', clustersRouter);
 app.use('/configuration/caches', cachesRouter);
 app.use('/configuration/metadata', metadataRouter);
 app.use('/configuration/summary', summary);
-app.use('/sql', sqlRouter);
-app.use('/agent', agentRouter);
+
+app.use('/notebooks', mustAuthenticated, notebooksRoutes);
+app.use('/sql', mustAuthenticated, sqlRouter);
+
+app.use('/agent', mustAuthenticated, agentRouter);
 
 // Catch 404 and forward to error handler.
 app.use(function (req, res, next) {

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e24f3b74/modules/control-center-web/src/main/js/controllers/common-module.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/controllers/common-module.js b/modules/control-center-web/src/main/js/controllers/common-module.js
index df2ff19..8d3efed 100644
--- a/modules/control-center-web/src/main/js/controllers/common-module.js
+++ b/modules/control-center-web/src/main/js/controllers/common-module.js
@@ -481,4 +481,28 @@ controlCenterModule.controller('auth', [
                     $alert({placement: 'top', container: '#errors-container', title: $scope.errorMessage(data)});
                 });
         };
-    }]);
\ No newline at end of file
+    }]);
+
+// Navigation bar controller.
+controlCenterModule.controller('notebooks', ['$scope', '$http','$common', function ($scope, $http, $common) {
+    $scope.notebooks = [];
+
+    // When landing on the page, get clusters and show them.
+    $http.post('/notebooks/list')
+        .success(function (data) {
+            $scope.notebooks = data;
+
+            if ($scope.notebooks.length > 0) {
+                $scope.notebookDropdown = [
+                    { text: 'Create new notebook', href: '/notebooks/new', target: '_self' },
+                    { divider: true }
+                ];
+
+                for (notebook of $scope.notebooks)
+                    $scope.notebookDropdown.push({text: notebook.name, href: '/sql/' + notebook._id, target: '_self'});
+            }
+        })
+        .error(function (errMsg) {
+            $common.showError(errMsg);
+        });
+}]);
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e24f3b74/modules/control-center-web/src/main/js/controllers/sql-controller.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/controllers/sql-controller.js b/modules/control-center-web/src/main/js/controllers/sql-controller.js
index b4b4335..1e67a08 100644
--- a/modules/control-center-web/src/main/js/controllers/sql-controller.js
+++ b/modules/control-center-web/src/main/js/controllers/sql-controller.js
@@ -15,7 +15,11 @@
  * limitations under the License.
  */
 
-controlCenterModule.controller('sqlController', ['$scope', '$http', '$common', function ($scope, $http, $common) {
+controlCenterModule.controller('sqlController', ['$scope', '$controller', '$http', '$common',
+    function ($scope, $controller, $http, $common) {
+    // Initialize the super class and extend it.
+    angular.extend(this, $controller('notebooks', {$scope: $scope}));
+
     $scope.joinTip = $common.joinTip;
 
     $scope.pageSizes = [50, 100, 200, 400, 800, 1000];
@@ -26,6 +30,22 @@ controlCenterModule.controller('sqlController', ['$scope', '$http', '$common', f
         {value: 'LOCAL', label: 'LOCAL'}
     ];
 
+    var loadNotebook = function() {
+        $http.post('/notebooks/get', {nodeId: $scope.nodeId})
+            .success(function (notebook) {
+                $scope.notebook = notebook;
+            })
+            .error(function (errMsg) {
+                $common.showError(errMsg);
+            });
+    };
+
+    loadNotebook();
+
+    $scope.addParagraph = function(notebook) {
+        notebook.paragraphs.push({});
+    };
+
     $scope.tabs = [];
 
     $scope.addTab = function() {

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e24f3b74/modules/control-center-web/src/main/js/db.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/db.js b/modules/control-center-web/src/main/js/db.js
index 5232e24..401beff 100644
--- a/modules/control-center-web/src/main/js/db.js
+++ b/modules/control-center-web/src/main/js/db.js
@@ -355,6 +355,18 @@ var PersistenceSchema = new Schema({
 // Define persistence model.
 exports.Persistence = mongoose.model('Persistence', PersistenceSchema);
 
+// Define persistence schema.
+var NotebookSchema = new Schema({
+    space: {type: ObjectId, ref: 'Space'},
+    name: String,
+    paragraph: [{
+        query: String
+    }]
+});
+
+// Define persistence model.
+exports.Notebook = mongoose.model('Notebook', NotebookSchema);
+
 exports.upsert = function (model, data, cb) {
     if (data._id) {
         var id = data._id;

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e24f3b74/modules/control-center-web/src/main/js/keys/test.crt
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/keys/test.crt b/modules/control-center-web/src/main/js/keys/test.crt
new file mode 100644
index 0000000..50c6d5c
--- /dev/null
+++ b/modules/control-center-web/src/main/js/keys/test.crt
@@ -0,0 +1,13 @@
+-----BEGIN CERTIFICATE-----
+MIIB6zCCAVQCCQDcAphbU6UcLjANBgkqhkiG9w0BAQsFADA6MRIwEAYDVQQDDAls
+b2NhbGhvc3QxJDAiBgkqhkiG9w0BCQEWFXNldmRva2ltb3ZAYXBhY2hlLm9yZzAe
+Fw0xNTA3MTQxMzAyNTNaFw0xODA2MjMxMzAyNTNaMDoxEjAQBgNVBAMMCWxvY2Fs
+aG9zdDEkMCIGCSqGSIb3DQEJARYVc2V2ZG9raW1vdkBhcGFjaGUub3JnMIGfMA0G
+CSqGSIb3DQEBAQUAA4GNADCBiQKBgQDP/zpJrdHqCj6lPpeFF6LQtzKef6UiyBBo
+rbuOtCCgW8KMJJciluBWk2126qLt9smBN4jBpSNU3pq0r9gBMUTd/LSe7aY4D5ED
+Pjp7XsypNVKeHaHbFi7KhfHy0LYxsWiNPmmHJv4dtYOp+pGK25rkXNfyJxxjgxN6
+wo34+MnZIQIDAQABMA0GCSqGSIb3DQEBCwUAA4GBAFk9XEjcdyihws+fVmdGGUFo
+bVxI9YGH6agiNbU3WNF4B4VRzcPPW8z2mEo7eF9kgYmq/YzH4T8tgi/qkL/u8eZV
+Wmi9bg6RThLN6/hj3wVoOFKykbDQ05FFdhIJXN5UOjPmxYM97EKqg6J0W2HAb8SG
++UekPnmAo/2HTKsLykH8
+-----END CERTIFICATE-----

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e24f3b74/modules/control-center-web/src/main/js/keys/test.key
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/keys/test.key b/modules/control-center-web/src/main/js/keys/test.key
new file mode 100644
index 0000000..1b395c0
--- /dev/null
+++ b/modules/control-center-web/src/main/js/keys/test.key
@@ -0,0 +1,18 @@
+-----BEGIN RSA PRIVATE KEY-----
+Proc-Type: 4,ENCRYPTED
+DEK-Info: DES-EDE3-CBC,6798185330CE2EE2
+
+sOwkmD8rvjx11l09V26dJhLhl+SyPIhyeZ3TqHXrYCATKoXlzidT+uPu1jVYtrwr
+nBLA6TrIDYRrBNlEsqGZ0cSvWTIczzVW1xZKHEJo5q2vUT/W8u/Q1QQtS3P3GeKF
+dEzx496rpZqwwVw59GNbuIwyYoVvQf3iEXzfhplGmLPELYIplDFOLgNuXQyXSGx6
+rwKsCxXMLsDyrA6DCz0Odf08p2HvWk/s5Ne3DFcQlqRNtIrBVGD2O0/Fp8ZZ2I4E
+Yn2OIIWJff3HanOjLOWKdN8YAn5UleNmlEUdIHeS5qaQ68mabOxLkSef9qglV+sd
+FHTtUq0cG6t6nhxZBziexha6v1yl/xABAHHhNPOfak+HthWxRD4N9f1yFYAeTmkn
+4kwBWoSUe12XRf2pGNqhEUKN/KhDmWk85wI55i/Cu2XmNoiBFlS9BXrRYU8uVCJw
+KlxjKTDWl1opCyvxTDxJnMkt44ZT445LRePKVueGIIKSUIXNQypOE+C1I0CL0N2W
+Ts3m9nthquvLeMx92k7b8yW69BER5uac3SIlGCOJObQXsHgyk8wYiyd/zLKfjctG
+PXieaW81UKjp+GqWpvWPz3VqnKwoyUWeVOOTviurli6kYOrHuySTMqMb6hxJctw9
+grAQTT0UPiAKWcM7InLzZnRjco+v9QLLEokjVngXPba16K/CItFY16xuGlaFLW7Y
+XTc67AkL8b76HBZelMjmCsqjvSoULhuMFwTOvUMm/mSM8rMoi9asrJRLQHRMWCST
+/6RENPLzPlOMnNLBujpBbn8V3/aYzEZsHMI+6S3d27WYlTJIqpabSA==
+-----END RSA PRIVATE KEY-----

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e24f3b74/modules/control-center-web/src/main/js/routes/agent.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/routes/agent.js b/modules/control-center-web/src/main/js/routes/agent.js
new file mode 100644
index 0000000..4646c28
--- /dev/null
+++ b/modules/control-center-web/src/main/js/routes/agent.js
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var router = require('express').Router();
+var agentManager = require('../agents/agent-manager');
+
+var apacheIgnite = require('apache-ignite');
+var SqlFieldsQuery = apacheIgnite.SqlFieldsQuery;
+
+/* GET summary page. */
+router.post('/topology', function(req, res) {
+    var client = agentManager.getAgentManager().getOneClient();
+
+    if (!client)
+        return res.status(500).send("Client not found");
+
+    client.ignite().cluster().then(function (clusters) {
+        res.json(clusters.map(function (cluster) {
+            var caches = Object.keys(cluster._caches).map(function(key) {
+                return {"name" : key, "mode" : cluster._caches[key] }
+            });
+
+            return { nodeId: cluster._nodeId, caches: caches };
+        }));
+    }, function (err) {
+        res.send(err);
+    });
+});
+
+/* GET summary page. */
+router.post('/query', function(req, res) {
+    var client = agentManager.getAgentManager().getOneClient();
+
+    if (!client)
+        return res.status(500).send("Client not found");
+
+    // Create sql query.
+    var qry = new SqlFieldsQuery(req.body.query);
+
+    // Set page size for query.
+    qry.setPageSize(req.body.pageSize);
+
+    // Get query cursor.
+    client.ignite().cache(req.body.cacheName).query(qry).nextPage().then(function (cursor) {
+        res.json({meta: cursor.fieldsMetadata(), rows: cursor.page(), queryId: cursor.queryId()});
+    }, function (err) {
+        res.status(500).send(err);
+    });
+});
+
+/* GET summary page. */
+router.post('/next_page', function(req, res) {
+    var client = agentManager.getAgentManager().getOneClient();
+
+    if (!client)
+        return res.status(500).send("Client not found");
+
+    var cache = client.ignite().cache(req.body.cacheName);
+
+    var cmd = cache._createCommand("qryfetch").addParam("qryId", req.body.queryId).
+        addParam("psz", req.body.pageSize);
+
+    cache.__createPromise(cmd).then(function (page) {
+        res.json({rows: page["items"], last: page === null || page["last"]});
+    }, function (err) {
+        res.status(500).send(err);
+    });
+});
+
+module.exports = router;

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e24f3b74/modules/control-center-web/src/main/js/routes/notebooks.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/routes/notebooks.js b/modules/control-center-web/src/main/js/routes/notebooks.js
new file mode 100644
index 0000000..5b7ac8e
--- /dev/null
+++ b/modules/control-center-web/src/main/js/routes/notebooks.js
@@ -0,0 +1,102 @@
+/*
+ *
+ *  * Licensed to the Apache Software Foundation (ASF) under one or more
+ *  * contributor license agreements.  See the NOTICE file distributed with
+ *  * this work for additional information regarding copyright ownership.
+ *  * The ASF licenses this file to You under the Apache License, Version 2.0
+ *  * (the "License"); you may not use this file except in compliance with
+ *  * the License.  You may obtain a copy of the License at
+ *  *
+ *  *      http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *
+ */
+
+var router = require('express').Router();
+var db = require('../db');
+
+/**
+ * Get notebooks names accessed for user account.
+ *
+ * @param req Request.
+ * @param res Response.
+ */
+router.post('/list', function (req, res) {
+    var user_id = req.currentUserId();
+
+    // Get owned space and all accessed space.
+    db.Space.find({$or: [{owner: user_id}, {usedBy: {$elemMatch: {account: user_id}}}]}, function (err, spaces) {
+        if (err)
+            return res.status(500).send(err.message);
+
+        var space_ids = spaces.map(function (value) {
+            return value._id;
+        });
+
+        // Get all metadata for spaces.
+        db.Notebook.find({space: {$in: space_ids}}).select('_id name').sort('name').exec(function (err, notebooks) {
+            if (err)
+                return res.status(500).send(err.message);
+
+            res.json(notebooks);
+        });
+    });
+});
+
+/**
+ * Get notebook accessed for user account.
+ *
+ * @param req Request.
+ * @param res Response.
+ */
+router.post('/get', function (req, res) {
+    var user_id = req.currentUserId();
+
+    // Get owned space and all accessed space.
+    db.Space.find({$or: [{owner: user_id}, {usedBy: {$elemMatch: {account: user_id}}}]}, function (err, spaces) {
+        if (err)
+            return res.status(500).send(err.message);
+
+        var space_ids = spaces.map(function (value) {
+            return value._id;
+        });
+
+        // Get all metadata for spaces.
+        db.Notebook.findOne({$or : [{space: {$in: space_ids}}, {_id: req.body.noteId}]}).exec(function (err, notebook) {
+            if (err)
+                return res.status(500).send(err.message);
+
+            res.json(notebook);
+        });
+    });
+});
+
+/**
+ * Create new notebook for user account.
+ *
+ * @param req Request.
+ * @param res Response.
+ */
+router.get('/new', function (req, res) {
+    var user_id = req.currentUserId();
+
+    // Get owned space and all accessed space.
+    db.Space.findOne({owner: user_id}, function (err, space) {
+        if (err)
+            return res.status(500).send(err.message);
+
+        (new db.Notebook({space: space.id, name: 'Notebook', paragraph: []})).save(function (err, notebook) {
+            if (err)
+                return res.status(500).send(err.message);
+
+            return res.redirect('/sql/' + notebook._id);
+        });
+    });
+});
+
+module.exports = router;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e24f3b74/modules/control-center-web/src/main/js/routes/sql.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/routes/sql.js b/modules/control-center-web/src/main/js/routes/sql.js
index ce4565d..d11be69 100644
--- a/modules/control-center-web/src/main/js/routes/sql.js
+++ b/modules/control-center-web/src/main/js/routes/sql.js
@@ -17,8 +17,8 @@
 
 var router = require('express').Router();
 var db = require('../db');
-router.get('/', function(req, res) {
-    res.render('sql/sql');
+router.get('/:noteId', function (req, res) {
+    res.render('sql/sql', {noteId: req.params.noteId});
 });
 
 module.exports = router;

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e24f3b74/modules/control-center-web/src/main/js/views/includes/header.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/views/includes/header.jade b/modules/control-center-web/src/main/js/views/includes/header.jade
index bfd5275..49ea592 100644
--- a/modules/control-center-web/src/main/js/views/includes/header.jade
+++ b/modules/control-center-web/src/main/js/views/includes/header.jade
@@ -29,11 +29,14 @@ header.header(id='header')
             ul.nav.navbar-nav(ng-controller='activeLink' ng-show='user')
                 +header-item('/configuration', '/configuration/clusters', 'Configuration')
                 //+header-item('/monitoring', '/monitoring', 'Monitoring')
-                +header-item('/sql', '/sql', 'SQL')
+                li(ng-controller='notebooks')
+                    a.dropdown-toggle(ng-hide='notebooks.length == 0' data-toggle='dropdown' bs-dropdown='notebookDropdown' data-placement='bottom-right') SQL
+                        span.caret
+                    a(ng-hide='notebooks.length > 0' ng-class='{active: isActive("/sql")}' href='/notebooks/new') SQL
                 //+header-item('/deploy', '/deploy', 'Deploy')
             ul.nav.navbar-nav.pull-right
                 li(ng-if='user')
-                    a.dropdown-toggle(data-toggle='dropdown' bs-dropdown='userDropdown' data-placement='bottom-right') {{user.username}}
+                    a.dropdown-toggle(data-toggle='dropdown' bs-dropdown='userDropdown' data-placement='bottom-right' data-ng-bind='::user.username')
                         span.caret
                 li.nav-login(ng-if='!user')
                     a(ng-click='login()' href='#') Log In
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e24f3b74/modules/control-center-web/src/main/js/views/sql/sql.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/views/sql/sql.jade b/modules/control-center-web/src/main/js/views/sql/sql.jade
index 2ce6958..53e6639 100644
--- a/modules/control-center-web/src/main/js/views/sql/sql.jade
+++ b/modules/control-center-web/src/main/js/views/sql/sql.jade
@@ -11,6 +11,7 @@
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     See the License for the specific language governing permissions and
     limitations under the License.
+
 extends ../templates/layout
 
 append scripts
@@ -27,7 +28,7 @@ block container
                 .docs-header
                     h1 Connect to Ignite and Execute SQL Queries
                     hr
-                .docs-body(ng-controller='sqlController')
+                .docs-body(ng-controller='sqlController' ng-init='noteId = #{JSON.stringify(noteId)};')
                     - var tab = 'tabs[tabs.activeIdx]'
 
                     .block-callout-parent.block-callout-border.margin-bottom-dflt

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e24f3b74/modules/control-center-web/src/test/js/routes/agent.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/test/js/routes/agent.js b/modules/control-center-web/src/test/js/routes/agent.js
new file mode 100644
index 0000000..c8bfd82
--- /dev/null
+++ b/modules/control-center-web/src/test/js/routes/agent.js
@@ -0,0 +1,94 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var request = require('supertest'),
+    should = require('should'),
+    app = require('../../app'),
+    fs = require('fs'),
+    https = require('https'),
+    config = require('../../helpers/configuration-loader.js'),
+    agentManager = require('../../agents/agent-manager');
+
+/**
+ * Create HTTP server.
+ */
+/**
+ * Start agent server.
+ */
+var agentServer = https.createServer({
+    key: fs.readFileSync(config.get('monitor:server:key')),
+    cert: fs.readFileSync(config.get('monitor:server:cert')),
+    passphrase: config.get('monitor:server:keyPassphrase')
+});
+
+agentServer.listen(config.get('monitor:server:port'));
+
+agentManager.createManager(agentServer);
+
+describe('request from agent', function() {
+    var agent = request.agent(app);
+
+    before(function (done) {
+        this.timeout(10000);
+
+        agent
+            .post('/login')
+            .send({email: 'anovikov@gridgain.com', password: 'extHB2aXgb'})
+            .expect(302)
+            .end(function (err) {
+                if (err)
+                    throw err;
+
+                setTimeout(done, 5000);
+            });
+    });
+
+    it('should return topology snapshot', function(done){
+        agent
+            .post('/agent/topology')
+            .send({})
+            .end(function(err, nodes) {
+                if (err) {
+                    console.log(err.response.text);
+
+                    throw err;
+                }
+
+                console.log(nodes);
+
+                done();
+            });
+    });
+
+    //it('should query result', function(done){
+    //    agent
+    //        .post('/agent/query')
+    //        .send({
+    //            username: 'nva',
+    //            password: 'nva.141',
+    //            host: 'localhost',
+    //            port: '5432',
+    //            dbName: 'ggmonitor'
+    //        })
+    //        .end(function(err, res) {
+    //            if (err)
+    //                throw err;
+    //
+    //            done();
+    //        });
+    //});
+});

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e24f3b74/modules/nodejs/src/main/js/cluster-node.js
----------------------------------------------------------------------
diff --git a/modules/nodejs/src/main/js/cluster-node.js b/modules/nodejs/src/main/js/cluster-node.js
index 940f123..7ef4fb3 100644
--- a/modules/nodejs/src/main/js/cluster-node.js
+++ b/modules/nodejs/src/main/js/cluster-node.js
@@ -15,15 +15,17 @@
  * limitations under the License.
  */
 
- /**
-  * @constructor
-  * @this{ClusterNode}
-  * @param {string} nodeId Node id
-  * @param {Object.<string,string>} attr Node Attributes
-  */
-function ClusterNode(nodeId, attr) {
+/**
+ * @constructor
+ * @this{ClusterNode}
+ * @param {string} nodeId Node id
+ * @param {Object.<string,string>} attr Node Attributes
+ * @param {Object.<string,string>} caches Node caches name, mode
+ */
+function ClusterNode(nodeId, attr, caches) {
     this._nodeId = nodeId;
     this._attr = attr;
+    this._caches = caches;
 }
 
 /**
@@ -40,4 +42,11 @@ ClusterNode.prototype.attributes = function() {
     return this._attr;
 }
 
+/**
+ * @returns {Object.<string,string>} Node caches name, mode
+ */
+ClusterNode.prototype.caches = function() {
+    return this._caches;
+}
+
 exports.ClusterNode = ClusterNode
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e24f3b74/modules/nodejs/src/main/js/ignite.js
----------------------------------------------------------------------
diff --git a/modules/nodejs/src/main/js/ignite.js b/modules/nodejs/src/main/js/ignite.js
index 5b68c23..47facc0 100644
--- a/modules/nodejs/src/main/js/ignite.js
+++ b/modules/nodejs/src/main/js/ignite.js
@@ -129,9 +129,8 @@ Ignite.prototype.cluster = function() {
                 else {
                     var nodes = [];
 
-                    for (var node of res) {
-                        nodes.push(new ClusterNode(node.nodeId, node.attributes));
-                    }
+                    for (var node of res)
+                        nodes.push(new ClusterNode(node.nodeId, node.attributes, node.caches));
 
                     resolve(nodes);
                 }

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e24f3b74/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyJsonConfig.java
----------------------------------------------------------------------
diff --git a/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyJsonConfig.java b/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyJsonConfig.java
index e36da80..ad6ee22 100644
--- a/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyJsonConfig.java
+++ b/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyJsonConfig.java
@@ -39,6 +39,9 @@ public class GridJettyJsonConfig extends JsonConfig {
     private static class ToStringJsonProcessor implements JsonValueProcessor {
         /** {@inheritDoc} */
         @Override public Object processArrayValue(Object val, JsonConfig jsonCfg) {
+            if (val != null && val.getClass() == UUID.class)
+                return val.toString();
+
             throw new UnsupportedOperationException("Serialize array to string is not supported: " + val);
         }
 

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e24f3b74/modules/web-control-center/src/main/js/agents/agent-manager.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/agents/agent-manager.js b/modules/web-control-center/src/main/js/agents/agent-manager.js
deleted file mode 100644
index 10d3a56..0000000
--- a/modules/web-control-center/src/main/js/agents/agent-manager.js
+++ /dev/null
@@ -1,283 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-var WebSocketServer = require('ws').Server;
-
-var apacheIgnite = require('apache-ignite');
-
-var db = require('../db');
-
-var AgentServer = require('./agent-server').AgentServer;
-
-/**
- * @constructor
- */
-function AgentManager(srv) {
-    this._clients = {};
-
-    this._server = srv;
-
-    this._wss = new WebSocketServer({ server: this._server });
-
-    var self = this;
-
-    this._wss.on('connection', function(ws) {
-        var client = new Client(ws, self);
-    });
-}
-
-/**
- * @param userId
- * @param {Client} client
- */
-AgentManager.prototype._removeClient = function(userId, client) {
-    var connections = this._clients[userId];
-
-    if (connections) {
-        removeFromArray(connections, client);
-
-        if (connections.length == 0)
-            delete this._clients[userId];
-    }
-};
-
-/**
- * @param userId
- * @param {Client} client
- */
-AgentManager.prototype._addClient = function(userId, client) {
-    var existingConnections = this._clients[userId];
-
-    if (!existingConnections) {
-        existingConnections = [];
-
-        this._clients[userId] = existingConnections;
-    }
-
-    existingConnections.push(client);
-};
-
-/**
- * @param userId
- * @return {Client}
- */
-AgentManager.prototype.findClient = function(userId) {
-    var clientsList = this._clients[userId];
-
-    if (!clientsList)
-        return null;
-
-    return clientsList[0];
-};
-
-/**
- * For tests only!!!
- * @return {Client}
- */
-AgentManager.prototype.getOneClient = function() {
-    for (var userId in this._clients) {
-        if (this._clients.hasOwnProperty(userId)) {
-            var m = this._clients[userId];
-
-            if (m.length > 0)
-                return m[0];
-        }
-    }
-
-    return null;
-};
-
-
-/**
- * @constructor
- * @param {AgentManager} manager
- * @param {WebSocket} ws
- */
-function Client(ws, manager) {
-    var self = this;
-
-    this._manager = manager;
-    this._ws = ws;
-
-    ws.on('close', function() {
-        if (self.user) {
-            self._manager._removeClient(self.user._id, self);
-        }
-    });
-
-    ws.on('message', function (msg) {
-        self._handleMessage(JSON.parse(msg))
-    });
-
-    this._restCounter = 0;
-
-    this._cbMap = {};
-}
-
-/**
- * @param {String|Object} msg
- * @param {Function} cb
- */
-Client.prototype.sendMessage = function(msg, cb) {
-    if (typeof msg == 'object') {
-        msg = JSON.stringify(msg);
-    }
-
-    this._ws.send(msg, cb);
-};
-
-/**
- * @param {String} path
- * @param {Object} params
- * @param {Function} cb
- * @param {String} method
- * @param {String} body
- * @param {Object} headers
- */
-Client.prototype.invokeRest = function(path, params, cb, method, body, headers) {
-    var self = this;
-
-    if (typeof(params) != 'object')
-        throw "'params' argument must be an object";
-
-    if (typeof(cb) != 'function')
-        throw "callback must be a function";
-
-    if (body && typeof(body) != 'string')
-        throw "body must be a string";
-
-    if (headers && typeof(headers) != 'object')
-        throw "headers must be an object";
-
-    if (!method)
-        method = 'GET';
-    else
-        method = method.toUpperCase();
-
-    if (method != 'GET' && method != 'POST')
-        throw "Unknown HTTP method: " + method;
-
-    var reqId = this._restCounter++;
-
-    this._cbMap[reqId] = cb;
-
-    this.sendMessage({
-        id: reqId,
-        type: 'RestRequest',
-        method: method,
-        params: params,
-        path: path,
-        body: body,
-        headers: headers
-    }, function(err) {
-        if (err) {
-            delete self._cbMap[reqId];
-
-            cb(err)
-        }
-    })
-};
-
-/**
- * @param {Object} msg
- */
-Client.prototype._handleMessage = function(msg) {
-    var self = this;
-
-    switch (msg.type) {
-        case 'AuthMessage':
-            var account = db.Account.findByUsername(msg.login, function(err, account) {
-                if (err) {
-                    ws.send("{type: 'AuthResult', success: false}");
-                }
-                else {
-                    account.authenticate(msg.password, function(err, user, res) {
-                        if (!user) {
-                            self._ws.send(JSON.stringify({type: 'AuthResult', success: false, message: res.message}));
-                        }
-                        else {
-                            self._ws.send("{type: 'AuthResult', success: true}");
-
-                            self._user = account;
-
-                            self._manager._addClient(account._id, self);
-
-                            self._ignite = new apacheIgnite.Ignite(new AgentServer(self));
-                        }
-                    });
-                }
-            });
-
-            break;
-
-        case 'RestResult':
-            var cb = this._cbMap[msg.requestId];
-
-            if (!cb)
-                break;
-
-            delete this._cbMap[msg.requestId];
-
-            if (!msg.executed) {
-                cb(msg.message)
-            }
-            else {
-                cb(null, msg.code, msg.message)
-            }
-
-            break;
-
-        default:
-            this._ws.close()
-    }
-};
-
-/**
- * @return {Ignite}
- */
-Client.prototype.ignite = function() {
-    return this._ignite;
-};
-
-function removeFromArray(arr, val) {
-    var idx;
-
-    while ((idx = arr.indexOf(val)) !== -1) {
-        arr.splice(idx, 1);
-    }
-}
-
-exports.AgentManager = AgentManager;
-
-/**
- * @type {AgentManager}
- */
-var manager = null;
-
-exports.createManager = function(srv) {
-    if (manager)
-        throw "Agent manager already cleared!";
-
-    manager = new AgentManager(srv);
-};
-
-/**
- * @return {AgentManager}
- */
-exports.getAgentManager = function() {
-    return manager;
-};

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e24f3b74/modules/web-control-center/src/main/js/agents/agent-server.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/agents/agent-server.js b/modules/web-control-center/src/main/js/agents/agent-server.js
deleted file mode 100644
index 31dee5a..0000000
--- a/modules/web-control-center/src/main/js/agents/agent-server.js
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * Creates an instance of server for Ignite
- *
- * @constructor
- * @this {AgentServer}
- * @param {Client} client connected client
- */
-function AgentServer(client) {
-    this._client = client;
-}
-
-/**
- * Run http request
- *
- * @this {AgentServer}
- * @param {Command} cmd Command
- * @param {callback} callback on finish
- */
-AgentServer.prototype.runCommand = function(cmd, callback) {
-    var params = {cmd: cmd.name()};
-
-    for (var p of cmd._params) {
-        params[p.key] = p.value;
-    }
-
-    var body = undefined;
-
-    var headers = undefined;
-
-    if (cmd._isPost()) {
-        body = cmd.postData();
-
-        headers = {'Content-Length': body.length, 'JSONObject': 'application/json'};
-    }
-
-    this._client.invokeRest("ignite", params, function(error, code, message) {
-        if (error) {
-            callback(error);
-            return
-        }
-
-        if (code !== 200) {
-            if (code === 401) {
-                callback.call(null, "Authentication failed. Status code 401.");
-            }
-            else {
-                callback.call(null, "Request failed. Status code " + code);
-            }
-
-            return;
-        }
-
-        var igniteResponse;
-
-        try {
-            igniteResponse = JSON.parse(message);
-        }
-        catch (e) {
-            callback.call(null, e, null);
-
-            return;
-        }
-
-        if (igniteResponse.successStatus) {
-            callback.call(null, igniteResponse.error, null)
-        }
-        else {
-            callback.call(null, null, igniteResponse.response);
-        }
-    }, cmd._method(), body, headers);
-};
-
-exports.AgentServer = AgentServer;

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e24f3b74/modules/web-control-center/src/main/js/keys/test.crt
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/keys/test.crt b/modules/web-control-center/src/main/js/keys/test.crt
deleted file mode 100644
index 50c6d5c..0000000
--- a/modules/web-control-center/src/main/js/keys/test.crt
+++ /dev/null
@@ -1,13 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIB6zCCAVQCCQDcAphbU6UcLjANBgkqhkiG9w0BAQsFADA6MRIwEAYDVQQDDAls
-b2NhbGhvc3QxJDAiBgkqhkiG9w0BCQEWFXNldmRva2ltb3ZAYXBhY2hlLm9yZzAe
-Fw0xNTA3MTQxMzAyNTNaFw0xODA2MjMxMzAyNTNaMDoxEjAQBgNVBAMMCWxvY2Fs
-aG9zdDEkMCIGCSqGSIb3DQEJARYVc2V2ZG9raW1vdkBhcGFjaGUub3JnMIGfMA0G
-CSqGSIb3DQEBAQUAA4GNADCBiQKBgQDP/zpJrdHqCj6lPpeFF6LQtzKef6UiyBBo
-rbuOtCCgW8KMJJciluBWk2126qLt9smBN4jBpSNU3pq0r9gBMUTd/LSe7aY4D5ED
-Pjp7XsypNVKeHaHbFi7KhfHy0LYxsWiNPmmHJv4dtYOp+pGK25rkXNfyJxxjgxN6
-wo34+MnZIQIDAQABMA0GCSqGSIb3DQEBCwUAA4GBAFk9XEjcdyihws+fVmdGGUFo
-bVxI9YGH6agiNbU3WNF4B4VRzcPPW8z2mEo7eF9kgYmq/YzH4T8tgi/qkL/u8eZV
-Wmi9bg6RThLN6/hj3wVoOFKykbDQ05FFdhIJXN5UOjPmxYM97EKqg6J0W2HAb8SG
-+UekPnmAo/2HTKsLykH8
------END CERTIFICATE-----

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e24f3b74/modules/web-control-center/src/main/js/keys/test.key
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/keys/test.key b/modules/web-control-center/src/main/js/keys/test.key
deleted file mode 100644
index 1b395c0..0000000
--- a/modules/web-control-center/src/main/js/keys/test.key
+++ /dev/null
@@ -1,18 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-Proc-Type: 4,ENCRYPTED
-DEK-Info: DES-EDE3-CBC,6798185330CE2EE2
-
-sOwkmD8rvjx11l09V26dJhLhl+SyPIhyeZ3TqHXrYCATKoXlzidT+uPu1jVYtrwr
-nBLA6TrIDYRrBNlEsqGZ0cSvWTIczzVW1xZKHEJo5q2vUT/W8u/Q1QQtS3P3GeKF
-dEzx496rpZqwwVw59GNbuIwyYoVvQf3iEXzfhplGmLPELYIplDFOLgNuXQyXSGx6
-rwKsCxXMLsDyrA6DCz0Odf08p2HvWk/s5Ne3DFcQlqRNtIrBVGD2O0/Fp8ZZ2I4E
-Yn2OIIWJff3HanOjLOWKdN8YAn5UleNmlEUdIHeS5qaQ68mabOxLkSef9qglV+sd
-FHTtUq0cG6t6nhxZBziexha6v1yl/xABAHHhNPOfak+HthWxRD4N9f1yFYAeTmkn
-4kwBWoSUe12XRf2pGNqhEUKN/KhDmWk85wI55i/Cu2XmNoiBFlS9BXrRYU8uVCJw
-KlxjKTDWl1opCyvxTDxJnMkt44ZT445LRePKVueGIIKSUIXNQypOE+C1I0CL0N2W
-Ts3m9nthquvLeMx92k7b8yW69BER5uac3SIlGCOJObQXsHgyk8wYiyd/zLKfjctG
-PXieaW81UKjp+GqWpvWPz3VqnKwoyUWeVOOTviurli6kYOrHuySTMqMb6hxJctw9
-grAQTT0UPiAKWcM7InLzZnRjco+v9QLLEokjVngXPba16K/CItFY16xuGlaFLW7Y
-XTc67AkL8b76HBZelMjmCsqjvSoULhuMFwTOvUMm/mSM8rMoi9asrJRLQHRMWCST
-/6RENPLzPlOMnNLBujpBbn8V3/aYzEZsHMI+6S3d27WYlTJIqpabSA==
------END RSA PRIVATE KEY-----

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e24f3b74/modules/web-control-center/src/main/js/routes/agent.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/routes/agent.js b/modules/web-control-center/src/main/js/routes/agent.js
deleted file mode 100644
index 4646c28..0000000
--- a/modules/web-control-center/src/main/js/routes/agent.js
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-var router = require('express').Router();
-var agentManager = require('../agents/agent-manager');
-
-var apacheIgnite = require('apache-ignite');
-var SqlFieldsQuery = apacheIgnite.SqlFieldsQuery;
-
-/* GET summary page. */
-router.post('/topology', function(req, res) {
-    var client = agentManager.getAgentManager().getOneClient();
-
-    if (!client)
-        return res.status(500).send("Client not found");
-
-    client.ignite().cluster().then(function (clusters) {
-        res.json(clusters.map(function (cluster) {
-            var caches = Object.keys(cluster._caches).map(function(key) {
-                return {"name" : key, "mode" : cluster._caches[key] }
-            });
-
-            return { nodeId: cluster._nodeId, caches: caches };
-        }));
-    }, function (err) {
-        res.send(err);
-    });
-});
-
-/* GET summary page. */
-router.post('/query', function(req, res) {
-    var client = agentManager.getAgentManager().getOneClient();
-
-    if (!client)
-        return res.status(500).send("Client not found");
-
-    // Create sql query.
-    var qry = new SqlFieldsQuery(req.body.query);
-
-    // Set page size for query.
-    qry.setPageSize(req.body.pageSize);
-
-    // Get query cursor.
-    client.ignite().cache(req.body.cacheName).query(qry).nextPage().then(function (cursor) {
-        res.json({meta: cursor.fieldsMetadata(), rows: cursor.page(), queryId: cursor.queryId()});
-    }, function (err) {
-        res.status(500).send(err);
-    });
-});
-
-/* GET summary page. */
-router.post('/next_page', function(req, res) {
-    var client = agentManager.getAgentManager().getOneClient();
-
-    if (!client)
-        return res.status(500).send("Client not found");
-
-    var cache = client.ignite().cache(req.body.cacheName);
-
-    var cmd = cache._createCommand("qryfetch").addParam("qryId", req.body.queryId).
-        addParam("psz", req.body.pageSize);
-
-    cache.__createPromise(cmd).then(function (page) {
-        res.json({rows: page["items"], last: page === null || page["last"]});
-    }, function (err) {
-        res.status(500).send(err);
-    });
-});
-
-module.exports = router;

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e24f3b74/modules/web-control-center/src/test/js/routes/agent.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/test/js/routes/agent.js b/modules/web-control-center/src/test/js/routes/agent.js
deleted file mode 100644
index 6a7fa2c..0000000
--- a/modules/web-control-center/src/test/js/routes/agent.js
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-var request = require('supertest'),
-    should = require('should'),
-    app = require('../../app'),
-    fs = require('fs'),
-    https = require('https'),
-    config = require('../../helpers/configuration-loader.js'),
-    agentManager = require('../../agents/agent-manager');
-
-/**
- * Create HTTP server.
- */
-/**
- * Start agent server.
- */
-var agentServer = https.createServer({
-    key: fs.readFileSync(config.get('monitor:server:key')),
-    cert: fs.readFileSync(config.get('monitor:server:cert')),
-    passphrase: config.get('monitor:server:keyPassphrase')
-});
-
-agentServer.listen(config.get('monitor:server:port'));
-
-agentManager.createManager(agentServer);
-
-describe('request from agent', function() {
-    var agent = request.agent(app);
-
-    before(function (done) {
-        this.timeout(10000);
-
-        agent
-            .post('/login')
-            .send({email: 'anovikov@gridgain.com', password: 'extHB2aXgb'})
-            .expect(302)
-            .end(function (err) {
-                if (err)
-                    throw err;
-
-                setTimeout(done, 5000);
-            });
-    });
-
-    it('should return topology snapshot', function(done){
-        agent
-            .post('/agent/topology')
-            .send({})
-            .end(function(err, nodes) {
-                if (err) {
-                    console.log(err.response.text);
-
-                    throw err;
-                }
-
-                console.log(nodes);
-
-                done();
-            });
-    });
-
-    //it('should query result', function(done){
-    //    agent
-    //        .post('/agent/query')
-    //        .send({
-    //            username: 'nva',
-    //            password: 'nva.141',
-    //            host: 'localhost',
-    //            port: '5432',
-    //            dbName: 'ggmonitor'
-    //        })
-    //        .end(function(err, res) {
-    //            if (err)
-    //                throw err;
-    //
-    //            done();
-    //        });
-    //});
-});
\ No newline at end of file


[27/41] incubator-ignite git commit: # ignite-843 Rename

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/web-control-center/src/main/js/views/configuration/metadata.jade
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/views/configuration/metadata.jade b/modules/web-control-center/src/main/js/views/configuration/metadata.jade
deleted file mode 100644
index e0cc76f..0000000
--- a/modules/web-control-center/src/main/js/views/configuration/metadata.jade
+++ /dev/null
@@ -1,121 +0,0 @@
-//-
-    Licensed to the Apache Software Foundation (ASF) under one or more
-    contributor license agreements.  See the NOTICE file distributed with
-    this work for additional information regarding copyright ownership.
-    The ASF licenses this file to You under the Apache License, Version 2.0
-    (the "License"); you may not use this file except in compliance with
-    the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
-
-extends sidebar
-
-append scripts
-    script(src='/metadata-controller.js')
-
-include ../includes/controls
-
-block content
-    .docs-header
-        h1 Create and Configure Cache Type Metadata
-        hr
-    .docs-body(ng-controller='metadataController')
-        +block-callout('{{screenTip.workflowTitle}}', 'joinTip(screenTip.workflowContent)', '{{screenTip.whatsNextTitle}}', 'joinTip(screenTip.whatsNextContent)')
-        div(ng-hide='metadatas.length == 0')
-            .padding-dflt
-                lable.labelHeader Types metadata:
-                table.links(st-table='metadatas')
-                    tbody
-                        tr(ng-repeat='row in metadatas track by row._id')
-                            td.col-sm-6(ng-class='{active: row._id == selectedItem._id}')
-                                a(event-focus='click' event-focus-id='defaultFocusId' ng-click='selectItem(row)') {{$index + 1}}) {{row.name}}
-        .padding-top-dflt
-            button.btn.btn-primary(event-focus='click' event-focus-id='defaultFocusId' ng-click='panels.activePanel = [0]; createItem()') &nbspAdd metadata
-            label(style='margin-left: 6px; margin-right: 10px') For:
-            button.btn.btn-default(ng-model='template' data-template='/select' data-placeholder='Choose metadata type' bs-options='item.value as item.label for item in templates' bs-select)
-            i.tiplabel.fa.fa-question-circle(bs-tooltip data-title='{{joinTip(templateTip)}}' type='button')
-        hr
-        .panel-group(bs-collapse ng-model='panels.activePanel' data-allow-multiple='false')
-            .panel.panel-default(ng-show='selectedItem || backupItem')
-                .panel-heading
-                    h3
-                        a(bs-collapse-toggle) Manual
-                .panel-collapse(role='tabpanel' bs-collapse-target)
-                    .panel-body
-                        form.form-horizontal(name='manualForm' ng-if='backupItem' novalidate)
-                            .settings-row(ng-repeat='field in metadataManual')
-                                +form-row
-                            button.btn.btn-primary(ng-disabled='manualForm.$invalid' ng-click='saveItem()') Save
-                            button.btn.btn-primary(ng-show='backupItem._id' ng-disabled='inputForm.$invalid' ng-click='saveItemAs()') Copy
-                            button.btn.btn-primary.btn-second(ng-show='backupItem._id' ng-click='removeItem()') Remove
-            .panel.panel-default
-                .panel-heading
-                    h3
-                        a(bs-collapse-toggle) Load from database
-                .panel-collapse(bs-collapse-target)
-                    .panel-body
-                        form.form-horizontal(name='dbForm' novalidate)
-                            .settings-row(ng-repeat='field in metadataDb')
-                                +form-row
-                        div(ng-hide='data.tables.length == 0')
-                            table.table-bordered.table-condensed.links-edit-small-padding.col-sm-12(st-table='data.tables')
-                                thead
-                                    tr
-                                        th.col-sm-3 Schema/Table
-                                        th Key class
-                                        th Value class
-                                tbody
-                                    tr(ng-repeat='row in data.tables')
-                                        td(colspan='{{row.tableName ? 1 : 3}}')
-                                            div.checkbox(ng-if='!row.tableName')
-                                                label(ng-click='selectSchema($index)')
-                                                    input(type='checkbox' ng-checked='row.use')
-                                                    | {{row.schemaName}}
-                                            div.checkbox(ng-if='row.tableName')
-                                                label(style='padding-left: 30px' ng-click='selectTable($index)')
-                                                    input(type='checkbox' ng-checked = 'row.use')
-                                                    | {{row.tableName}}
-                                        td(ng-if='row.tableName')
-                                            a(ng-show='data.curTableIdx != $index' ng-click='selectTable($index)') {{row.keyClass}}
-                                            input.form-control(type='text' ng-show='data.curTableIdx == $index' ng-model='data.curKeyClass' placeholder='Key class full name')
-                                        td(ng-if='row.tableName')
-                                            a(ng-show='data.curTableIdx != $index' ng-click='selectTable($index)') {{row.valueClass}}
-                                            input.form-control(type='text' ng-show='data.curTableIdx == $index' ng-model='data.curValueClass' placeholder='Value class full name')
-                        //div(ng-hide='data.curTableIdx < 0')
-                        //    table.table-bordered.table-condensed.links-edit-small-padding.col-sm-12(st-table='data.tables[data.curTableIdx].fields')
-                        //        thead
-                        //            tr
-                        //                th(style='width:45px') Use
-                        //                th(style='width:45px') Key
-                        //                th(style='width:45px') Ak
-                        //                th DB Name
-                        //                th DB Type
-                        //                th Java Name
-                        //                th Java Type
-                        //        tbody
-                        //            tr(ng-repeat='row in data.tables[data.curTableIdx].fields')
-                        //                td
-                        //                    +dbcheck('row.use')
-                        //                td
-                        //                    +dbcheck('row.key')
-                        //                td
-                        //                    +dbcheck('row.ak')
-                        //                td
-                        //                    label {{row.databaseName}}
-                        //                td
-                        //                    label {{row.databaseType}}
-                        //                td
-                        //                    a(ng-show='data.curFieldIdx != $index' ng-click='selectField($index)') {{row.javaName}}
-                        //                    input.form-control(type='text' ng-show='data.curFieldIdx == $index' ng-model='data.curJavaName' placeholder='Field Java name')
-                        //                td
-                        //                    a(ng-show='data.curFieldIdx != $index' ng-click='selectField($index)') {{row.javaType}}
-                        //                    input.form-control(type='text' ng-show='data.curFieldIdx == $index' ng-model='data.curJavaType' placeholder='Field Java type')
-                        button.btn.btn-primary(ng-disabled='dbForm.$invalid' ng-click='saveItem()') Save
-                        button.btn.btn-primary.btn-second(ng-show='backupItem._id' ng-click='removeItem()') Remove
-                        button.btn.btn-primary.btn-second(ng-click='reloadMetadata()') Reload
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/web-control-center/src/main/js/views/configuration/sidebar.jade
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/views/configuration/sidebar.jade b/modules/web-control-center/src/main/js/views/configuration/sidebar.jade
deleted file mode 100644
index 7289f3e..0000000
--- a/modules/web-control-center/src/main/js/views/configuration/sidebar.jade
+++ /dev/null
@@ -1,39 +0,0 @@
-//-
-    Licensed to the Apache Software Foundation (ASF) under one or more
-    contributor license agreements.  See the NOTICE file distributed with
-    this work for additional information regarding copyright ownership.
-    The ASF licenses this file to You under the Apache License, Version 2.0
-    (the "License"); you may not use this file except in compliance with
-    the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
-
-extends ../templates/layout
-
-mixin sidebar-item(ref, num, txt)
-    li
-        a(ng-class='{active: isActive("#{ref}")}' href='#{ref}')
-            span.fa-stack
-                i.fa.fa-circle-thin.fa-stack-2x
-                i.fa.fa-stack-1x #{num}
-            | #{txt}
-
-block container
-    .row
-        .col-sm-2.border-right.section-left.greedy
-            .sidebar-nav(bs-affix)
-                ul.menu(ng-controller='activeLink')
-                    +sidebar-item('/configuration/clusters', 1, 'Clusters')
-                    +sidebar-item('/configuration/metadata', 2, 'Metadata')
-                    +sidebar-item('/configuration/caches', 3, 'Caches')
-                    +sidebar-item('/configuration/summary', 4, 'Summary')
-
-        .col-sm-10.border-left.section-right
-            .docs-content
-                block content
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/web-control-center/src/main/js/views/configuration/summary.jade
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/views/configuration/summary.jade b/modules/web-control-center/src/main/js/views/configuration/summary.jade
deleted file mode 100644
index ba63343..0000000
--- a/modules/web-control-center/src/main/js/views/configuration/summary.jade
+++ /dev/null
@@ -1,113 +0,0 @@
-//-
-    Licensed to the Apache Software Foundation (ASF) under one or more
-    contributor license agreements.  See the NOTICE file distributed with
-    this work for additional information regarding copyright ownership.
-    The ASF licenses this file to You under the Apache License, Version 2.0
-    (the "License"); you may not use this file except in compliance with
-    the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
-
-extends sidebar
-
-append scripts
-    script(src='/summary-controller.js')
-
-    script(src='//cdn.jsdelivr.net/angularjs/1.3.15/angular-animate.min.js')
-    script(src='//cdn.jsdelivr.net/angularjs/1.3.15/angular-sanitize.min.js')
-
-    script(src='//cdnjs.cloudflare.com/ajax/libs/ace/1.2.0/theme-chrome.js')
-    script(src='//cdnjs.cloudflare.com/ajax/libs/ace/1.2.0/mode-xml.js')
-    script(src='//cdnjs.cloudflare.com/ajax/libs/ace/1.2.0/mode-java.js')
-    script(src='//cdnjs.cloudflare.com/ajax/libs/ace/1.2.0/mode-dockerfile.js')
-
-append css
-
-include ../includes/controls
-
-mixin hard-link(ref, txt)
-    a(style='color:#ec1c24' href=ref target='_blank') #{txt}
-
-block content
-    .docs-header
-        h1 Configurations Summary
-        hr
-    .docs-body(ng-controller='summaryController')
-        +block-callout('{{screenTip.workflowTitle}}', 'joinTip(screenTip.workflowContent)', '{{screenTip.whatsNextTitle}}', 'joinTip(screenTip.whatsNextContent)')
-        .padding-dflt(ng-if='clusters.length == 0')
-            | No cluster configured. You can&nbsp;
-            a(href='clusters') configure
-            | &nbsp;it.
-        .padding-dflt(ng-if='clusters.length > 0')
-            lable.labelHeader Clusters:
-            table.links(st-table='clusters')
-                tbody
-                    tr(ng-repeat='row in clusters track by row._id')
-                        td.col-sm-6(ng-class='{active: row._id == selectedItem._id}')
-                            a(ng-click='selectItem(row)') {{$index + 1}}) {{row.name}}
-        div(ng-show='selectedItem' role='tab' method='post' action='summary/download')
-            .padding-dflt(bs-collapse data-start-collapsed='false')
-                .panel.panel-default
-                    form.panel-heading(role='tab' method='post' action='summary/download')
-                        input(type='hidden' name='_id' value='{{selectedItem._id}}')
-                        input(type='hidden' name='os' value='{{os}}')
-                        input(type='hidden' name='javaClass' value='{{javaClassServer}}')
-                        h3
-                            a(bs-collapse-toggle) Server
-                            button.btn.btn-primary.pull-right(type='submit' style='margin-top: -5px') Download
-                    .panel-collapse(role='tabpanel' bs-collapse-target)
-                        div(ng-show='selectedItem' bs-tabs style='margin-top: 0.65em')
-                            div(title='<img src="/images/xml.png" width="16px" height="16px"/> XML' bs-pane)
-                                div(ui-ace='{ onLoad: aceInit, mode: "xml" }' ng-model='xmlServer')
-                            div(title='<img src="/images/java.png" width="16px" height="16px"/> Java' bs-pane)
-                                .details-row
-                                    .col-sm-1
-                                        label Generate:
-                                    .col-sm-3
-                                        button.form-control(type='button' ng-model='configServer.javaClassServer'  bs-select data-placeholder='{{detail.placeholder}}' bs-options='item.value as item.label for item in javaClassItems' data-sort='false')
-                                div(ui-ace='{ onLoad: aceInit, mode: "java" }' ng-model='javaServer')
-                            div(title='<img src="/images/docker.png" width="16px" height="16px"/> Dockerfile' bs-pane)
-                                .details-row
-                                    p
-                                        +hard-link('https://docs.docker.com/reference/builder', 'Docker')
-                                        | &nbsp;file is a text file with instructions to create Docker image.<br/>
-                                        | To build image you have to store following Docker file with your Ignite XML configuration to the same directory.<br>
-                                        | Also you could use predefined&nbsp;
-                                        +hard-link('https://ignite.incubator.apache.org/download.html#docker', 'Apache Ignite docker image')
-                                        | . For more information about using Ignite with Docker please read&nbsp;
-                                        +hard-link('http://apacheignite.readme.io/docs/docker-deployment', 'documentation')
-                                        |.
-                                    .col-sm-2
-                                        label(for='os') Operation System:
-                                    .col-sm-4
-                                        input#os.form-control(type='text' ng-model='configServer.os' placeholder='debian:8' data-min-length='0' data-html='1' data-auto-select='true' data-animation='am-flip-x' bs-typeahead bs-options='os for os in oss')
-                                div(ui-ace='{ onLoad: aceInit, mode: "dockerfile" }' ng-model='dockerServer')
-            .padding-dflt(bs-collapse data-start-collapsed='false')
-                .panel.panel-default
-                    form.panel-heading(role='tab' method='post' action='summary/download')
-                        input(type='hidden' name='_id' value='{{selectedItem._id}}')
-                        input(type='hidden' name='javaClass' value='{{javaClassClient}}')
-                        input(type='hidden' name='clientNearConfiguration' value='{{backupItem}}')
-                        h3
-                            a(bs-collapse-toggle) Client
-                            button.btn.btn-primary.pull-right(type='submit' style='margin-top: -5px') Download
-                    .panel-collapse(role='tabpanel' bs-collapse-target)
-                        div(ng-show='selectedItem')
-                            .details-row(ng-repeat='field in clientFields')
-                                +form-row-custom(['col-sm-3'], ['col-sm-3'])
-                            div(bs-tabs style='margin-top: 0.65em')
-                                div(title='<img src="/images/xml.png" width="16px" height="16px"/> XML' bs-pane)
-                                    div(ui-ace='{ onLoad: aceInit, mode: "xml" }' ng-model='xmlClient')
-                                div(title='<img src="/images/java.png" width="16px" height="16px"/> Java' bs-pane)
-                                    .details-row
-                                        .col-sm-1
-                                            label Generate:
-                                        .col-sm-4
-                                            button.form-control(type='button' ng-model='backupItem.javaClassClient' bs-select data-placeholder='{{detail.placeholder}}' bs-options='item.value as item.label for item in javaClassItems' data-sort='false')
-                                    div(ui-ace='{ onLoad: aceInit, mode: "java" }' ng-model='javaClient')

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/web-control-center/src/main/js/views/error.jade
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/views/error.jade b/modules/web-control-center/src/main/js/views/error.jade
deleted file mode 100644
index b458fb7..0000000
--- a/modules/web-control-center/src/main/js/views/error.jade
+++ /dev/null
@@ -1,22 +0,0 @@
-//-
-    Licensed to the Apache Software Foundation (ASF) under one or more
-    contributor license agreements.  See the NOTICE file distributed with
-    this work for additional information regarding copyright ownership.
-    The ASF licenses this file to You under the Apache License, Version 2.0
-    (the "License"); you may not use this file except in compliance with
-    the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
-
-extends templates/layout
-
-block container
-  h1= message
-  h2= error.status
-  pre #{error.stack}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/web-control-center/src/main/js/views/includes/controls.jade
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/views/includes/controls.jade b/modules/web-control-center/src/main/js/views/includes/controls.jade
deleted file mode 100644
index e9fe71b..0000000
--- a/modules/web-control-center/src/main/js/views/includes/controls.jade
+++ /dev/null
@@ -1,350 +0,0 @@
-//-
-    Licensed to the Apache Software Foundation (ASF) under one or more
-    contributor license agreements.  See the NOTICE file distributed with
-    this work for additional information regarding copyright ownership.
-    The ASF licenses this file to You under the Apache License, Version 2.0
-    (the "License"); you may not use this file except in compliance with
-    the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
-
-mixin block-callout(titleWorkflow, contentWorkflow, whatsNextWorkflow, whatsNextContent)
-    .block-callout-parent.block-callout-border.margin-bottom-dflt
-        .block-callout
-            i.fa.fa-check-square
-            label #{titleWorkflow}
-            p(ng-bind-html=contentWorkflow)
-        .block-callout
-            i.fa.fa-check-square
-            label #{whatsNextWorkflow}
-            p(ng-bind-html=whatsNextContent)
-
-
-mixin tipField(lines)
-    i.tipField.fa.fa-question-circle(ng-if=lines bs-tooltip='joinTip(#{lines})' type='button')
-    i.tipField.fa.fa-question-circle.blank(ng-if='!#{lines}')
-
-mixin tipLabel(lines)
-    i.tipLabel.fa.fa-question-circle(ng-if=lines bs-tooltip='joinTip(#{lines})' type='button')
-    i.tipLabel.fa.fa-question-circle.blank(ng-if='!#{lines}')
-
-mixin ico-exclamation(mdl, err, msg)
-    i.fa.fa-exclamation-triangle.form-control-feedback(ng-show='inputForm["#{mdl}"].$error.#{err}' bs-tooltip data-title='#{msg}' type='button')
-
-mixin btn-save(show, click)
-    i.tipField.fa.fa-floppy-o(ng-show=show ng-click=click bs-tooltip data-title='Save item')
-
-mixin btn-add(click, tip, focusId)
-    i.tipField.fa.fa-plus(ng-click=click bs-tooltip=tip event-focus='click' event-focus-id=focusId)
-
-mixin btn-remove(click, tip)
-    i.tipField.fa.fa-remove(ng-click=click bs-tooltip=tip data-trigger='hover')
-
-mixin btn-up(show, click)
-    i.tipField.fa.fa-arrow-up(ng-show=show ng-click=click bs-tooltip data-title='Move item up')
-
-mixin btn-down(show, click)
-    i.tipField.fa.fa-arrow-down(ng-show=show ng-click=click bs-tooltip data-title='Move item down')
-
-mixin table-pair-edit(keyModel, valModel, keyPlaceholder, valPlaceholder, keyJavaBuildInTypes, valueJavaBuildInTypes, focusId)
-    .col-sm-6(style='float: right')
-        if valueJavaBuildInTypes
-            input.form-control(type='text' ng-model=valModel placeholder=valPlaceholder bs-typeahead data-min-length='1' bs-options='javaType for javaType in javaBuildInTypes' ng-escape='tableReset()')
-        else
-            input.form-control(type='text' ng-model=valModel placeholder=valPlaceholder ng-escape='tableReset()')
-    label.fieldSep /
-    .input-tip
-        if keyJavaBuildInTypes
-            input.form-control(id=focusId type='text' ng-model=keyModel placeholder=keyPlaceholder bs-typeahead data-min-length='1' bs-options='javaType for javaType in javaBuildInTypes' ng-escape='tableReset()')
-        else
-            input.form-control(id=focusId type='text' ng-model=keyModel placeholder=keyPlaceholder ng-escape='tableReset()')
-
-mixin table-pair(header, tblMdl, keyFld, valFld, keyPlaceholder, valPlaceholder, keyJavaBuildInTypes, valueJavaBuildInTypes)
-    .col-sm-6
-        label.table-header #{header}:
-        +tipLabel('field.tip')
-        +btn-add('tableNewItem(field)', 'field.addTip', '{{::field.focusNewItemId}}')
-        .table-details(ng-show='(#{tblMdl} && #{tblMdl}.length > 0) || tableNewItemActive(field)')
-            table.links-edit.col-sm-12(st-table=tblMdl)
-                tbody
-                    tr(ng-repeat='item in #{tblMdl}')
-                        td.col-sm-12
-                            div(ng-show='!tableEditing(field, $index)')
-                                a.labelFormField(event-focus='click' event-focus-id='{{::field.focusCurItemId}}' ng-click='curPair = tableStartEdit(backupItem, field, $index); curKey = curPair.#{keyFld}; curValue = curPair.#{valFld}') {{$index + 1}}) {{item.#{keyFld}}} / {{item.#{valFld}}}
-                                +btn-remove('tableRemove(backupItem, field, $index)', 'field.removeTip')
-                            div(ng-if='tableEditing(field, $index)')
-                                label.labelField {{$index + 1}})
-                                +btn-save('tablePairSaveVisible(curKey, curValue)', 'tablePairSave(tablePairValid, backupItem, field, curKey, curValue, $index)')
-                                +table-pair-edit('curKey', 'curValue', keyPlaceholder, valPlaceholder, keyJavaBuildInTypes, valueJavaBuildInTypes, '{{::field.focusCurItemId}}')
-                tfoot(ng-show='tableNewItemActive(field)')
-                    tr
-                        td.col-sm-12
-                            +btn-save('tablePairSaveVisible(newKey, newValue)', 'tablePairSave(tablePairValid, backupItem, field, newKey, newValue, -1)')
-                            +table-pair-edit('newKey', 'newValue', keyPlaceholder, valPlaceholder, keyJavaBuildInTypes, valueJavaBuildInTypes, '{{::field.focusNewItemId}}')
-
-mixin details-row
-    - var lblDetailClasses = ['col-sm-4', 'details-label']
-
-    - var detailMdl = 'getModel(backupItem, detail)[detail.model]';
-    - var detailCommon = {'ng-model': detailMdl, 'ng-required': 'detail.required'};
-
-    - var customValidators = {'ng-attr-ipaddress': '{{detail.ipaddress}}'}
-
-    div(ng-switch='detail.type')
-        div(ng-switch-when='label')
-            label {{::detail.label}}
-        div.checkbox(ng-switch-when='check')
-            label
-                input(type='checkbox')&attributes(detailCommon)
-                |{{::detail.label}}
-                +tipLabel('detail.tip')
-        div(ng-switch-when='text')
-            label(class=lblDetailClasses ng-class='{required: detail.required}') {{::detail.label}}:
-            .col-sm-8
-                +tipField('detail.tip')
-                .input-tip
-                    input.form-control(type='text' placeholder='{{::detail.placeholder}}')&attributes(detailCommon)
-        div(ng-switch-when='number' )
-            label(class=lblDetailClasses ng-class='{required: detail.required}') {{::detail.label}}:
-            .col-sm-8
-                +tipField('detail.tip')
-                .input-tip
-                    input.form-control(name='{{detail.model}}' type='number' placeholder='{{::detail.placeholder}}' min='{{detail.min ? detail.min : 0}}' max='{{detail.max ? detail.max : Number.MAX_VALUE}}')&attributes(detailCommon)
-                    +ico-exclamation('{{detail.model}}', 'min', 'Value is less than allowable minimum.')
-                    +ico-exclamation('{{detail.model}}', 'max', 'Value is more than allowable maximum.')
-                    +ico-exclamation('{{detail.model}}', 'number', 'Invalid value. Only numbers allowed.')
-        div(ng-switch-when='dropdown')
-            label(class=lblDetailClasses ng-class='{required: detail.required}') {{::detail.label}}:
-            .col-sm-8
-                +tipField('detail.tip')
-                .input-tip
-                    button.form-control(bs-select data-placeholder='{{::detail.placeholder}}' bs-options='item.value as item.label for item in {{detail.items}}')&attributes(detailCommon)
-        div(ng-switch-when='dropdown-multiple')
-            label(class=lblDetailClasses ng-class='{required: detail.required}') {{::detail.label}}:
-            .col-sm-8
-                button.form-control(bs-select data-multiple='1' data-placeholder='{{::detail.placeholder}}' bs-options='item.value as item.label for item in {{detail.items}}')&attributes(detailCommon)
-            +tipField('detail.tip')
-        div(ng-switch-when='table-simple')&attributes(detailCommon)
-            div(ng-if='detail.label')
-                label.table-header {{::detail.label}}:
-                +tipLabel('detail.tableTip')
-            table.col-sm-12.links-edit-details(st-table='#{detailMdl}')
-                tbody
-                    tr(ng-repeat='item in #{detailMdl} track by $index')
-                        td
-                            div(ng-show='!tableEditing(detail, $index)')
-                                a.labelFormField(event-focus='click' event-focus-id='{{::detail.focusCurItemId}}' ng-click='curValue = tableStartEdit(backupItem, detail, $index)') {{$index + 1}}) {{item}}
-                                +btn-remove('tableRemove(backupItem, detail, $index)', 'detail.removeTip')
-                                +btn-down('detail.reordering && tableSimpleDownVisible(backupItem, detail, $index)', 'tableSimpleDown(backupItem, detail, $index)')
-                                +btn-up('detail.reordering && $index > 0', 'tableSimpleUp(backupItem, detail, $index)')
-                            div(ng-if='tableEditing(detail, $index)')
-                                label.labelField {{$index + 1}})
-                                +btn-save('tableSimpleSaveVisible(curValue)', 'tableSimpleSave(tableSimpleValid, backupItem, detail, curValue, $index)')
-                                .input-tip.form-group.has-feedback
-                                    input.form-control(id='{{::detail.focusCurItemId}}' name='{{detail.model}}.edit' type='text' ng-model='curValue' placeholder='{{::detail.placeholder}}' ng-escape='tableReset()')&attributes(customValidators)
-                                    +ico-exclamation('{{detail.model}}.edit', 'ipaddress', 'Invalid address, see help for format description.')
-            button.btn.btn-primary.fieldButton(ng-disabled='!newValue' ng-click='tableSimpleSave(tableSimpleValid, backupItem, detail, newValue, -1)') Add
-            +tipField('detail.tip')
-            .input-tip.form-group.has-feedback
-                input.form-control(name='{{detail.model}}' type='text' ng-model='newValue' ng-focus='tableNewItem(detail)' placeholder='{{::detail.placeholder}}')&attributes(customValidators)
-                +ico-exclamation('{{detail.model}}', 'ipaddress', 'Invalid address, see help for format description.')
-
-mixin table-db-field-edit(databaseName, databaseType, javaName, javaType)
-    div(style='width: 22%; float: right')
-        button.form-control(ng-model=javaType bs-select data-placeholder='Java type' bs-options='item.value as item.label for item in {{javaTypes}}')
-    label.fieldSep /
-    div(style='width: 20%; float: right')
-        input.form-control(type='text' ng-model=javaName placeholder='Java name' ng-escape='tableReset()')
-    label.fieldSep /
-    div(style='width: 22%; float: right')
-        button.form-control(ng-model=databaseType bs-select data-placeholder='JDBC type' bs-options='item.value as item.label for item in {{jdbcTypes}}')
-    label.fieldSep /
-    .input-tip
-        input.form-control(type='text' ng-model=databaseName placeholder='DB name' ng-escape='tableReset()')
-
-mixin table-group-item-edit(fieldName, className, direction, focusId)
-    div(style='width: 15%; float: right')
-        button.form-control(ng-model=direction bs-select data-placeholder='Sort' bs-options='item.value as item.label for item in {{sortDirections}}')
-    label.fieldSep /
-    div(style='width: 38%; float: right')
-        input.form-control(type='text' ng-model=className placeholder='Class name' bs-typeahead data-min-length='1' bs-options='javaType for javaType in javaBuildInTypes' ng-escape='tableReset()')
-    label.fieldSep /
-    .input-tip
-        input.form-control(id=focusId type='text' ng-model=fieldName placeholder='Field name' ng-escape='tableReset()')
-
-mixin form-row
-    +form-row-custom(['col-sm-2'], ['col-sm-4'])
-
-mixin form-row-custom(lblClasses, fieldClasses)
-    - var fieldMdl = 'getModel(backupItem, field)[field.model]';
-    - var fieldCommon = {'ng-model': fieldMdl, 'ng-required': 'field.required || required(field)'};
-    - var fieldRequiredClass = '{true: "required"}[field.required || required(field)]'
-    - var fieldHide = '{{field.hide}}'
-
-    div(ng-switch='field.type')
-        div.col-sm-6(ng-switch-when='label')
-            label {{::field.label}}
-        div.checkbox.col-sm-6(ng-switch-when='check' ng-hide=fieldHide)
-            label
-                input(type='checkbox')&attributes(fieldCommon)
-                | {{::field.label}}
-                +tipLabel('field.tip')
-        div(ng-switch-when='text' ng-hide=fieldHide)
-            label(class=lblClasses ng-class=fieldRequiredClass) {{::field.label}}:
-            div(class=fieldClasses)
-                +tipField('field.tip')
-                .input-tip
-                    input.form-control(id='{{::field.id}}' type='text' placeholder='{{::field.placeholder}}')&attributes(fieldCommon)
-        div(ng-switch-when='withJavaBuildInTypes' ng-hide=fieldHide)
-            label(class=lblClasses ng-class=fieldRequiredClass) {{::field.label}}:
-            div(class=fieldClasses)
-                +tipField('field.tip')
-                .input-tip
-                    input.form-control(type='text' placeholder='{{::field.placeholder}}' bs-typeahead data-min-length='1' bs-options='javaType for javaType in javaBuildInTypes')&attributes(fieldCommon)
-        div(ng-switch-when='password' ng-hide=fieldHide)
-            label(class=lblClasses ng-class=fieldRequiredClass) {{::field.label}}:
-            div(class=fieldClasses)
-                +tipField('field.tip')
-                .input-tip
-                    input.form-control(type='password' placeholder='{{::field.placeholder}}')&attributes(fieldCommon)
-        div(ng-switch-when='number' ng-hide=fieldHide)
-            label(class=lblClasses ng-class=fieldRequiredClass) {{::field.label}}:
-            div(class=fieldClasses)
-                +tipField('field.tip')
-                .input-tip
-                    input.form-control(name='{{field.model}}' type='number' placeholder='{{::field.placeholder}}' min='{{field.min ? field.min : 0}}' max='{{field.max ? field.max : Number.MAX_VALUE}}')&attributes(fieldCommon)
-                    +ico-exclamation('{{field.model}}', 'min', 'Value is less than allowable minimum.')
-                    +ico-exclamation('{{field.model}}', 'max', 'Value is more than allowable maximum.')
-                    +ico-exclamation('{{field.model}}', 'number', 'Invalid value. Only numbers allowed.')
-        div(ng-switch-when='dropdown' ng-hide=fieldHide)
-            label(class=lblClasses ng-class=fieldRequiredClass) {{::field.label}}:
-            div(class=fieldClasses)
-                +tipField('field.tip')
-                .input-tip
-                    button.form-control(bs-select data-placeholder='{{::field.placeholder}}' bs-options='item.value as item.label for item in {{field.items}}')&attributes(fieldCommon)
-        div(ng-switch-when='dropdown-multiple' ng-hide=fieldHide)
-            label(class=lblClasses ng-class=fieldRequiredClass) {{::field.label}}:
-            div(class=fieldClasses)
-                +tipField('field.tip')
-                .input-tip
-                    button.form-control(bs-select ng-disabled='{{field.items}}.length == 0' data-multiple='1' data-placeholder='{{::field.placeholder}}' bs-options='item.value as item.label for item in {{field.items}}')&attributes(fieldCommon)
-            a.customize(ng-show='field.addLink' ng-href='{{field.addLink.ref}}') {{field.addLink.label}}
-        div(ng-switch-when='dropdown-details' ng-hide=fieldHide)
-            - var expanded = 'field.details[' + fieldMdl + '].expanded'
-
-            label(class=lblClasses ng-class=fieldRequiredClass) {{::field.label}}:
-            div(class=fieldClasses)
-                +tipField('field.tip')
-                .input-tip
-                    button.form-control(bs-select data-placeholder='{{::field.placeholder}}' bs-options='item.value as item.label for item in {{field.items}}')&attributes(fieldCommon)
-            a.customize(ng-show='#{fieldMdl} && field.details[#{fieldMdl}].fields' ng-click='#{expanded} = !#{expanded}') {{#{expanded} ? "Hide settings" : "Show settings"}}
-            .col-sm-6.panel-details(ng-show='#{expanded} && #{fieldMdl}')
-                .details-row(ng-repeat='detail in field.details[#{fieldMdl}].fields')
-                    +details-row
-        div(ng-switch-when='table-simple' ng-hide=fieldHide)&attributes(fieldCommon)
-            .col-sm-6
-                label.table-header {{::field.label}}:
-                +tipLabel('field.tableTip')
-                +btn-add('tableNewItem(field)', 'field.addTip', '{{::field.focusNewItemId}}')
-            .col-sm-12(ng-show='(#{fieldMdl} && #{fieldMdl}.length > 0) || tableNewItemActive(field)')
-                .col-sm-6
-                    .table-details
-                        table.links-edit.col-sm-12(st-table='#{fieldMdl}')
-                            tbody
-                                tr(ng-repeat='item in #{fieldMdl} track by $index')
-                                    td.col-sm-12
-                                        div(ng-show='!tableEditing(field, $index)')
-                                            a.labelFormField(event-focus='click' event-focus-id='{{::field.focusCurItemId}}' ng-click='curValue = tableStartEdit(backupItem, field, $index)') {{$index + 1}}) {{item | compact}}
-                                            +btn-remove('tableRemove(backupItem, field, $index)', 'field.removeTip')
-                                            +btn-down('field.reordering && tableSimpleDownVisible(backupItem, field, $index)', 'tableSimpleDown(backupItem, field, $index)')
-                                            +btn-up('field.reordering && $index > 0', 'tableSimpleUp(backupItem, field, $index)')
-                                        div(ng-if='tableEditing(field, $index)')
-                                            label.labelField {{$index + 1}})
-                                            +btn-save('tableSimpleSaveVisible(curValue)', 'tableSimpleSave(tableSimpleValid, backupItem, field, curValue, $index)')
-                                            .input-tip
-                                                input.form-control(id='{{::field.focusCurItemId}}' type='text' ng-model='curValue' placeholder='{{::field.placeholder}}' ng-enter='tableSimpleSaveVisible(curValue) && tableSimpleSave(tableSimpleValid, backupItem, field, curValue, $index)' ng-escape='tableReset()')
-                            tfoot(ng-show='tableNewItemActive(field)')
-                                tr
-                                    td.col-sm-12
-                                        +btn-save('tableSimpleSaveVisible(newValue)', 'tableSimpleSave(tableSimpleValid, backupItem, field, newValue, -1)')
-                                        .input-tip
-                                            input.form-control(id='{{::field.focusNewItemId}}' type='text' ng-model='newValue' placeholder='{{::field.placeholder}}' ng-enter='tableSimpleSaveVisible(newValue) && tableSimpleSave(tableSimpleValid, backupItem, field, newValue, -1)' ng-escape='tableReset()')
-        div(ng-switch-when='indexedTypes')
-            +table-pair('Index key-value type pairs', fieldMdl, 'keyClass', 'valueClass', 'Key class full name', 'Value class full name', true, false)
-        div(ng-switch-when='queryFields' ng-hide=fieldHide)
-            +table-pair('{{::field.label}}', fieldMdl, 'name', 'className', 'Field name', 'Field class full name', false, true)
-        div(ng-switch-when='dbFields' ng-hide=fieldHide)
-            .col-sm-6
-                label.table-header {{::field.label}}:
-                +tipLabel('field.tip')
-                +btn-add('tableNewItem(field)', 'field.addTip', 'field.focusNewItemId')
-            .col-sm-12(ng-show='(#{fieldMdl} && #{fieldMdl}.length > 0) || tableNewItemActive(field)')
-                .col-sm-6
-                    .table-details
-                        table.links-edit.col-sm-12(st-table=fieldMdl)
-                            tbody
-                                tr(ng-repeat='item in #{fieldMdl}')
-                                    td.col-sm-12
-                                        div(ng-show='!tableEditing(field, $index)')
-                                            a.labelFormField(ng-click='curField = tableStartEdit(backupItem, field, $index); curDatabaseName = curField.databaseName; curDatabaseType = curField.databaseType; curJavaName = curField.javaName; curJavaType = curField.javaType') {{$index + 1}}) {{item.databaseName}} / {{item.databaseType}} / {{item.javaName}} / {{item.javaType}}
-                                            +btn-remove('tableRemove(backupItem, field, $index)', 'field.removeTip')
-                                        div(ng-if='tableEditing(field, $index)')
-                                            label.labelField {{$index + 1}})
-                                            +btn-save('tableDbFieldSaveVisible(curDatabaseName, curDatabaseType, curJavaName, curJavaType)', 'tableDbFieldSave(field, curDatabaseName, curDatabaseType, curJavaName, curJavaType, $index)')
-                                            +table-db-field-edit('curDatabaseName', 'curDatabaseType', 'curJavaName', 'curJavaType')
-                            tfoot(ng-show='tableNewItemActive(field)')
-                                tr
-                                    td.col-sm-12
-                                        +btn-save('tableDbFieldSaveVisible(newDatabaseName, newDatabaseType, newJavaName, newJavaType)', 'tableDbFieldSave(field, newDatabaseName, newDatabaseType, newJavaName, newJavaType, -1)')
-                                        +table-db-field-edit('newDatabaseName', 'newDatabaseType', 'newJavaName', 'newJavaType')
-        div(ng-switch-when='queryGroups' ng-hide=fieldHide)
-            .col-sm-6
-                label.table-header {{::field.label}}:
-                +tipLabel('field.tip')
-                +btn-add('tableNewItem(field)', 'field.addTip', 'newGroupId')
-            .col-sm-12(ng-show='(#{fieldMdl} && #{fieldMdl}.length > 0) || tableNewItemActive(field)')
-                .col-sm-6
-                    .table-details
-                        table.links-edit.col-sm-12(st-table=fieldMdl ng-init='newDirection = false')
-                            tbody
-                                tr(ng-repeat='group in #{fieldMdl}')
-                                    td.col-sm-12
-                                        div
-                                            .col-sm-12(ng-show='!tableEditing(field, $index)')
-                                                a.labelFormField(event-focus='click' event-focus-id='curGroupId' ng-click='curGroup = tableStartEdit(backupItem, field, $index); curGroupName = curGroup.name; curFields = curGroup.fields') {{$index + 1}}) {{group.name}}
-                                                +btn-remove('tableRemove(backupItem, field, $index)', 'field.removeTip')
-                                                +btn-add('tableGroupNewItem($index)', 'field.addItemTip', 'newGroupItemId')
-                                            div(ng-if='tableEditing(field, $index)')
-                                                label.labelField {{$index + 1}})
-                                                +btn-save('tableGroupSaveVisible(curGroupName)', 'tableGroupSave(curGroupName, $index)')
-                                                .input-tip
-                                                    input#curGroupId.form-control(type='text' ng-model='curGroupName' placeholder='Index name' ng-enter='tableGroupSaveVisible(curGroupName) && tableGroupSave(curGroupName, $index)' ng-escape='tableReset()')
-                                            div
-                                                table.links-edit.col-sm-12(st-table='group.fields' ng-init='groupIndex = $index')
-                                                    tbody
-                                                        tr(ng-repeat='groupItem in group.fields')
-                                                            td
-                                                                div(ng-show='!tableGroupItemEditing(groupIndex, $index)')
-                                                                    a.labelFormField(event-focus='click' event-focus-id='curGroupItemId' ng-click='curGroupItem = tableGroupItemStartEdit(groupIndex, $index); curFieldName = curGroupItem.name; curClassName = curGroupItem.className; curDirection = curGroupItem.direction') {{$index + 1}}) {{groupItem.name}} / {{groupItem.className}} / {{groupItem.direction ? "DESC" : "ASC"}}
-                                                                    +btn-remove('tableRemoveGroupItem(group, $index)', 'field.removeItemTip')
-                                                                div(ng-if='tableGroupItemEditing(groupIndex, $index)')
-                                                                    label.labelField {{$index + 1}})
-                                                                    +btn-save('tableGroupItemSaveVisible(curFieldName, curClassName)', 'tableGroupItemSave(curFieldName, curClassName, curDirection, groupIndex, $index)')
-                                                                    +table-group-item-edit('curFieldName', 'curClassName', 'curDirection', 'curGroupItemId')
-                                                    tfoot(ng-if='tableGroupNewItemActive(groupIndex)')
-                                                        tr.col-sm-12(style='padding-left: 18px')
-                                                            td
-                                                                +btn-save('tableGroupItemSaveVisible(newFieldName, newClassName)', 'tableGroupItemSave(newFieldName, newClassName, newDirection, groupIndex, -1)')
-                                                                +table-group-item-edit('newFieldName', 'newClassName', 'newDirection', 'newGroupItemId')
-                            tfoot(ng-show='tableNewItemActive(field)')
-                                tr
-                                    td.col-sm-12
-                                        +btn-save('tableGroupSaveVisible(newGroupName)', 'tableGroupSave(newGroupName, -1)')
-                                        .input-tip
-                                            input#newGroupId.form-control(type='text' ng-model='newGroupName' placeholder='Group name' ng-enter='tableGroupSaveVisible(newGroupName) && tableGroupSave(newGroupName, -1)' ng-escape='tableReset()')
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/web-control-center/src/main/js/views/includes/footer.jade
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/views/includes/footer.jade b/modules/web-control-center/src/main/js/views/includes/footer.jade
deleted file mode 100644
index d8ff5d7..0000000
--- a/modules/web-control-center/src/main/js/views/includes/footer.jade
+++ /dev/null
@@ -1,22 +0,0 @@
-//-
-    Licensed to the Apache Software Foundation (ASF) under one or more
-    contributor license agreements.  See the NOTICE file distributed with
-    this work for additional information regarding copyright ownership.
-    The ASF licenses this file to You under the Apache License, Version 2.0
-    (the "License"); you may not use this file except in compliance with
-    the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
-
-.container.container-footer
-    footer
-        center
-            p Apache Ignite Control Center, version 1.0.0
-            p © 2015 The Apache Software Foundation.
-            p Apache, Apache Ignite, the Apache feather and the Apache Ignite logo are trademarks of The Apache Software Foundation.
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/web-control-center/src/main/js/views/includes/header.jade
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/views/includes/header.jade b/modules/web-control-center/src/main/js/views/includes/header.jade
deleted file mode 100644
index bfd5275..0000000
--- a/modules/web-control-center/src/main/js/views/includes/header.jade
+++ /dev/null
@@ -1,39 +0,0 @@
-//-
-    Licensed to the Apache Software Foundation (ASF) under one or more
-    contributor license agreements.  See the NOTICE file distributed with
-    this work for additional information regarding copyright ownership.
-    The ASF licenses this file to You under the Apache License, Version 2.0
-    (the "License"); you may not use this file except in compliance with
-    the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
-mixin header-item(active, ref, txt)
-    li
-        a(ng-class='{active: isActive("#{active}")}' href='#{ref}') #{txt}
-
-header.header(id='header')
-    .viewedUser(ng-show='becomeUsed') Currently assuming "
-        strong {{user.username}}
-        | ",&nbsp;&nbsp;
-        a(href='/admin/become') revert to your identity.
-    .container
-        h1.navbar-brand
-            a(href='/') Apache Ignite Web Configurator
-        .navbar-collapse.collapse(ng-controller='auth')
-            ul.nav.navbar-nav(ng-controller='activeLink' ng-show='user')
-                +header-item('/configuration', '/configuration/clusters', 'Configuration')
-                //+header-item('/monitoring', '/monitoring', 'Monitoring')
-                +header-item('/sql', '/sql', 'SQL')
-                //+header-item('/deploy', '/deploy', 'Deploy')
-            ul.nav.navbar-nav.pull-right
-                li(ng-if='user')
-                    a.dropdown-toggle(data-toggle='dropdown' bs-dropdown='userDropdown' data-placement='bottom-right') {{user.username}}
-                        span.caret
-                li.nav-login(ng-if='!user')
-                    a(ng-click='login()' href='#') Log In
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/web-control-center/src/main/js/views/index.jade
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/views/index.jade b/modules/web-control-center/src/main/js/views/index.jade
deleted file mode 100644
index 999c4f8..0000000
--- a/modules/web-control-center/src/main/js/views/index.jade
+++ /dev/null
@@ -1,30 +0,0 @@
-//-
-    Licensed to the Apache Software Foundation (ASF) under one or more
-    contributor license agreements.  See the NOTICE file distributed with
-    this work for additional information regarding copyright ownership.
-    The ASF licenses this file to You under the Apache License, Version 2.0
-    (the "License"); you may not use this file except in compliance with
-    the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
-
-extends templates/layout
-
-block container
-    .row
-        .docs-content
-            div
-                p
-                    | Apache Ignite<sup>tm</sup> In-Memory Data Fabric is a high-performance,
-                    | integrated and distributed in-memory platform for computing and transacting on large-scale data
-                    | sets in real-time, orders of magnitude faster than possible with traditional disk-based or flash technologies.
-        .block-image.block-display-image
-                img(ng-src='https://www.filepicker.io/api/file/lydEeGB6Rs9hwbpcQxiw' alt='Apache Ignite stack')
-        .text-center(ng-controller='auth')
-            button.btn.btn-primary(ng-click='login()' href='#') Configure Now

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/web-control-center/src/main/js/views/login.jade
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/views/login.jade b/modules/web-control-center/src/main/js/views/login.jade
deleted file mode 100644
index a580c01..0000000
--- a/modules/web-control-center/src/main/js/views/login.jade
+++ /dev/null
@@ -1,55 +0,0 @@
-//-
-    Licensed to the Apache Software Foundation (ASF) under one or more
-    contributor license agreements.  See the NOTICE file distributed with
-    this work for additional information regarding copyright ownership.
-    The ASF licenses this file to You under the Apache License, Version 2.0
-    (the "License"); you may not use this file except in compliance with
-    the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
-
-mixin lbl(txt)
-    label.col-sm-3.required #{txt}
-
-.modal.center(role='dialog')
-    .modal-dialog
-        .modal-content
-            .modal-header.header
-                div(id='errors-container')
-                button.close(type='button' ng-click='$hide()' aria-hidden='true') &times;
-                h1.navbar-brand
-                    a(href='/') Apache Ignite Web Configurator
-                h4.modal-title(style='padding-right: 55px') Authentication
-                p(style='padding-right: 55px') Log in or register in order to collaborate
-            form.form-horizontal(name='loginForm')
-                .modal-body.row
-                    .col-sm-9.login.col-sm-offset-1
-                        .details-row(ng-show='action == "register"')
-                            +lbl('Full Name:')
-                            .col-sm-9
-                                input.form-control(type='text' ng-model='user_info.username' placeholder='John Smith' focus-me='action=="register"' ng-required='action=="register"')
-                        .details-row
-                            +lbl('Email:')
-                            .col-sm-9
-                                input.form-control(type='email' ng-model='user_info.email' placeholder='you@domain.com' focus-me='action=="login"' required)
-                        .details-row
-                            +lbl('Password:')
-                            .col-sm-9
-                                input.form-control(type='password' ng-model='user_info.password' placeholder='Password' required ng-enter='action == "login" && auth(action, user_info)')
-                        .details-row(ng-show='action == "register"')
-                            +lbl('Confirm:')
-                            .col-sm-9.input-tip.has-feedback
-                                input.form-control(type='password' ng-model='user_info.confirm' match='user_info.password' placeholder='Confirm password' required ng-enter='auth(action, user_info)')
-
-            .modal-footer
-                a.show-signup.ng-hide(ng-show='action != "login"' ng-click='action = "login";') log in
-                a.show-signup(ng-show='action != "register"' ng-click='action = "register"') sign up
-                | &nbsp;or&nbsp;
-                button.btn.btn-primary(ng-show='action == "login"' ng-click='auth(action, user_info)') Log In
-                button.btn.btn-primary(ng-show='action == "register"' ng-disabled='loginForm.$invalid || user_info.password != user_info.confirm' ng-click='auth(action, user_info)') Sign Up

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/web-control-center/src/main/js/views/settings/admin.jade
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/views/settings/admin.jade b/modules/web-control-center/src/main/js/views/settings/admin.jade
deleted file mode 100644
index 8345bb9..0000000
--- a/modules/web-control-center/src/main/js/views/settings/admin.jade
+++ /dev/null
@@ -1,58 +0,0 @@
-//-
-    Licensed to the Apache Software Foundation (ASF) under one or more
-    contributor license agreements.  See the NOTICE file distributed with
-    this work for additional information regarding copyright ownership.
-    The ASF licenses this file to You under the Apache License, Version 2.0
-    (the "License"); you may not use this file except in compliance with
-    the License.  You may obtain a copy of the License at
-         http://www.apache.org/licenses/LICENSE-2.0
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
-
-extends ../templates/layout
-
-append scripts
-    script(src='/admin-controller.js')
-
-block container
-    .row(ng-controller='adminController')
-        .docs-content
-            .docs-header
-                h1 List of registered users
-                hr
-            .docs-body
-                table.table.table-striped.admin(st-table='displayedUsers' st-safe-src='users')
-                    thead
-                        tr
-                            th.header(colspan='5')
-                                .col-sm-2.pull-right
-                                    input.form-control(type='text' st-search='' placeholder='Filter users...')
-                        tr
-                            th(st-sort='username') User name
-                            th(st-sort='email') Email
-                            th.col-sm-2(st-sort='lastLogin') Last login
-                            th(width='1%'  st-sort='admin') Admin
-                            th(width='1%') Actions
-                    tbody
-                        tr(ng-repeat='row in displayedUsers')
-                            td {{row.username}}
-                            td
-                                a(ng-href='mailto:{{row.email}}') {{row.email}}
-                            td
-                                span {{row.lastLogin | date:'medium'}}
-                            td(style='text-align: center;')
-                                input(type='checkbox' ng-disabled='row.adminChanging || row._id == user._id'
-                                    ng-model='row.admin' ng-change='toggleAdmin(row)')
-                            td(style='text-align: center;')
-                                a(ng-click='removeUser(row)' ng-show='row._id != user._id' bs-tooltip data-title='Remove user')
-                                    i.fa.fa-remove
-                                a(style='margin-left: 5px' ng-href='admin/become?viewedUserId={{row._id}}' ng-show='row._id != user._id' bs-tooltip data-title='Become this user')
-                                    i.fa.fa-eye
-                    tfoot
-                        tr
-                            td.text-right(colspan='5')
-                                div(st-pagination st-items-by-page='15' st-displayed-pages='5')
-

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/web-control-center/src/main/js/views/settings/profile.jade
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/views/settings/profile.jade b/modules/web-control-center/src/main/js/views/settings/profile.jade
deleted file mode 100644
index 6ddcafa..0000000
--- a/modules/web-control-center/src/main/js/views/settings/profile.jade
+++ /dev/null
@@ -1,58 +0,0 @@
-//-
-    Licensed to the Apache Software Foundation (ASF) under one or more
-    contributor license agreements.  See the NOTICE file distributed with
-    this work for additional information regarding copyright ownership.
-    The ASF licenses this file to You under the Apache License, Version 2.0
-    (the "License"); you may not use this file except in compliance with
-    the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
-
-extends ../templates/layout
-
-mixin lbl(txt)
-    label.col-sm-2.required.labelFormField #{txt}
-
-append scripts
-    script(src='/profile-controller.js')
-
-block container
-    .row(ng-controller='profileController')
-        .docs-content
-            .docs-header
-                h1 User profile
-                hr
-            .docs-body
-                form.form-horizontal(name='profileForm' novalidate)
-                    .col-sm-10(style='padding: 0')
-                        .details-row
-                            +lbl('User name:')
-                            .col-sm-4
-                                input.form-control(type='text' ng-model='profileUser.username' placeholder='Input name' required)
-                        .details-row
-                            +lbl('Email:')
-                            .col-sm-4
-                                input.form-control(type='email' ng-model='profileUser.email' placeholder='you@domain.com' required)
-                        .details-row
-                            .checkbox
-                                label
-                                    input(type='checkbox' ng-model='profileUser.changePassword')
-                                    | Change password
-                        div(ng-show='profileUser.changePassword')
-                            .details-row
-                                +lbl('New password:')
-                                .col-sm-4
-                                    input.form-control(type='password' ng-model='profileUser.newPassword' placeholder='New password' ng-required='profileUser.changePassword')
-                            .details-row
-                                +lbl('Confirm:')
-                                .col-sm-4
-                                    input.form-control(type='password' ng-model='profileUser.confirmPassword' match='profileUser.newPassword' placeholder='Confirm new password' ng-required='profileUser.changePassword')
-                    .col-sm-12.details-row
-                        button.btn.btn-primary(ng-disabled='profileForm.$invalid' ng-click='saveUser()') Save
-

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/web-control-center/src/main/js/views/sql/sql.jade
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/views/sql/sql.jade b/modules/web-control-center/src/main/js/views/sql/sql.jade
deleted file mode 100644
index 97d34de..0000000
--- a/modules/web-control-center/src/main/js/views/sql/sql.jade
+++ /dev/null
@@ -1,85 +0,0 @@
-//-
-    Licensed to the Apache Software Foundation (ASF) under one or more
-    contributor license agreements.  See the NOTICE file distributed with
-    this work for additional information regarding copyright ownership.
-    The ASF licenses this file to You under the Apache License, Version 2.0
-    (the "License"); you may not use this file except in compliance with
-    the License.  You may obtain a copy of the License at
-         http://www.apache.org/licenses/LICENSE-2.0
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
-extends ../templates/layout
-
-append scripts
-    script(src='/sql-controller.js')
-
-    script(src='//cdnjs.cloudflare.com/ajax/libs/ace/1.2.0/theme-chrome.js')
-    script(src='//cdnjs.cloudflare.com/ajax/libs/ace/1.2.0/mode-sql.js')
-    script(src='//cdnjs.cloudflare.com/ajax/libs/ace/1.2.0/ext-language_tools.js')
-
-block container
-    .row
-        .col-sm-12
-            .docs-content
-                .docs-header
-                    h1 Connect to Ignite and Execute SQL Queries
-                    hr
-                .docs-body(ng-controller='sqlController')
-                    - var tab = 'tabs[tabs.activeIdx]'
-
-                    .block-callout-parent.block-callout-border.margin-bottom-dflt
-                        .block-callout
-                            p(ng-bind-html='joinTip(screenTip)')
-                    .tabs-below(bs-tabs bs-active-pane='tabs.activeIdx' data-template='/tab')
-                        div(ng-repeat='tab in tabs' title='Query' bs-pane)
-                    .row
-                        .col-sm-9(style='border-right: 1px solid #eee')
-                            div(style='height: 200px' ui-ace='{ theme: "chrome", mode: "sql",' +
-                                'require: ["ace/ext/language_tools"],' +
-                                'rendererOptions: {showPrintMargin: false, highlightGutterLine: false, fontSize: 14},' +
-                                'advanced: {enableSnippets: false, enableBasicAutocompletion: true, enableLiveAutocompletion: true}}' ng-model='#{tab}.query')
-                        .col-sm-3
-                            div(ng-hide='caches.length == 0' style='margin-top: 0.65em')
-                                lable.labelHeader Caches:
-                                table.links(st-table='caches')
-                                    tbody
-                                        tr(ng-repeat='row in caches track by row._id')
-                                            td.col-sm-6(ng-class='{active: row._id == #{tab}.selectedItem._id}')
-                                                a(ng-click='#{tab}.selectedItem = row') {{$index + 1}}) {{row.name}}, {{row.mode | displayValue:modes:'Cache mode not set'}}
-                    hr(style='margin: 0')
-                    .settings-row
-                        label Page Size:&nbsp;
-                        button.btn.btn-default.base-control(ng-init='pageSize = pageSizes[0]' ng-model='pageSize' bs-options='item for item in pageSizes' bs-select)
-                    .settings-row
-                        button.btn.btn-primary(ng-click='') Explain
-                        button.btn.btn-primary(ng-click='') Execute
-                        button.btn.btn-primary(ng-click='' disabled) Scan
-
-                    div(ng-show='#{tab}.rows.length > 0' style='margin-top: 0.65em')
-                        hr
-                        div
-                            table.table.table-striped.col-sm-12.sql-results(st-table='rows' st-safe-src='#{tab}.rows')
-                                thead
-                                    tr(style='border-size: 0')
-                                        td(colspan='{{#{tab}.cols.length}}')
-                                            .col-sm-8
-                                                lable Page #:&nbsp;
-                                                b {{#{tab}.page}}&nbsp;&nbsp;&nbsp;
-                                                | Results:&nbsp;
-                                                b {{#{tab}.rows.length + #{tab}.total}}
-                                            .col-sm-4
-                                                button.btn.btn-primary.fieldButton(ng-click='') Next page
-                                                .input-tip
-                                                    input.form-control(type='text' st-search='' placeholder='Filter...')
-
-                                    tr
-                                        th(ng-repeat='column in #{tab}.cols' st-sort='{{column}}') {{column}}
-                                tbody
-                                    //tr
-                                    //    td(colspan='{{#{tab}.cols.length}}')
-                                    //        .loading-indicator
-                                    tr(ng-repeat='row in rows')
-                                        td(ng-repeat='column in #{tab}.cols') {{row[column]}}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/web-control-center/src/main/js/views/templates/confirm.jade
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/views/templates/confirm.jade b/modules/web-control-center/src/main/js/views/templates/confirm.jade
deleted file mode 100644
index 949318a..0000000
--- a/modules/web-control-center/src/main/js/views/templates/confirm.jade
+++ /dev/null
@@ -1,27 +0,0 @@
-//-
-    Licensed to the Apache Software Foundation (ASF) under one or more
-    contributor license agreements.  See the NOTICE file distributed with
-    this work for additional information regarding copyright ownership.
-    The ASF licenses this file to You under the Apache License, Version 2.0
-    (the "License"); you may not use this file except in compliance with
-    the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
-
-.modal(tabindex='-1' role='dialog')
-    .modal-dialog
-        .modal-content
-            .modal-header
-                button.close(type='button' ng-click='$hide()') &times;
-                h4.modal-title Confirmation
-            .modal-body(ng-show='content')
-                p(ng-bind-html='content' style='text-align: center;')
-            .modal-footer
-                button.btn.btn-default(type='button' ng-click='$hide()') Cancel
-                button.btn.btn-primary(type='button' ng-click='ok()') Confirm
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/web-control-center/src/main/js/views/templates/copy.jade
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/views/templates/copy.jade b/modules/web-control-center/src/main/js/views/templates/copy.jade
deleted file mode 100644
index 2ba9096..0000000
--- a/modules/web-control-center/src/main/js/views/templates/copy.jade
+++ /dev/null
@@ -1,31 +0,0 @@
-//-
-    Licensed to the Apache Software Foundation (ASF) under one or more
-    contributor license agreements.  See the NOTICE file distributed with
-    this work for additional information regarding copyright ownership.
-    The ASF licenses this file to You under the Apache License, Version 2.0
-    (the "License"); you may not use this file except in compliance with
-    the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
-
-.modal(tabindex='-1' role='dialog')
-    .modal-dialog
-        .modal-content
-            .modal-header
-                button.close(type='button' ng-click='$hide()') &times;
-                h4.modal-title Copy
-            form.form-horizontal(name='inputForm' novalidate)
-                .modal-body.row
-                    .col-sm-9.login.col-sm-offset-1
-                        label.required.labelFormField() New name:&nbsp;
-                        .col-sm-9
-                            input.form-control(type='text' ng-model='newName' required)
-            .modal-footer
-                button.btn.btn-default(type='button' ng-click='$hide()') Cancel
-                button.btn.btn-primary(type='button' ng-disabled='inputForm.$invalid' ng-click='ok(newName)') Confirm
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/web-control-center/src/main/js/views/templates/layout.jade
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/views/templates/layout.jade b/modules/web-control-center/src/main/js/views/templates/layout.jade
deleted file mode 100644
index 71d8936..0000000
--- a/modules/web-control-center/src/main/js/views/templates/layout.jade
+++ /dev/null
@@ -1,61 +0,0 @@
-//-
-    Licensed to the Apache Software Foundation (ASF) under one or more
-    contributor license agreements.  See the NOTICE file distributed with
-    this work for additional information regarding copyright ownership.
-    The ASF licenses this file to You under the Apache License, Version 2.0
-    (the "License"); you may not use this file except in compliance with
-    the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
-
-doctype html
-html(ng-app='ignite-web-control-center' ng-init='user = #{JSON.stringify(user)}; becomeUsed = #{becomeUsed}')
-    head
-        title= title
-
-        block css
-            // Bootstrap
-            link(rel='stylesheet', href='//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.4/css/bootstrap.css')
-
-            // Font Awesome Icons
-            link(rel='stylesheet', href='//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.css')
-
-            // Font
-            link(rel='stylesheet', href='//fonts.googleapis.com/css?family=Roboto+Slab:700:serif|Roboto+Slab:400:serif')
-
-            link(rel='stylesheet', href='/stylesheets/style.css')
-
-        block scripts
-            script(src='//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.js')
-
-            script(src='//cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.0/lodash.min.js')
-
-            script(src='//ajax.googleapis.com/ajax/libs/angularjs/1.4.2/angular.js')
-            script(src='//cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.2/angular-sanitize.js')
-            script(src='//cdnjs.cloudflare.com/ajax/libs/angular-strap/2.3.0/angular-strap.js')
-            script(src='//cdnjs.cloudflare.com/ajax/libs/angular-strap/2.3.0/angular-strap.tpl.min.js')
-
-            script(src='//cdnjs.cloudflare.com/ajax/libs/angular-smart-table/2.0.3/smart-table.js')
-
-            script(src='//cdnjs.cloudflare.com/ajax/libs/ace/1.2.0/ace.js')
-            script(src='//angular-ui.github.io/ui-ace/dist/ui-ace.min.js')
-
-            script(src='/common-module.js')
-            script(src='/data-structures.js')
-
-    body.theme-line.body-overlap.greedy
-        .wrapper
-            include ../includes/header
-
-            block main-container
-                .container.body-container
-                    .main-content
-                        block container
-
-            include ../includes/footer

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/web-control-center/src/main/js/views/templates/select.jade
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/views/templates/select.jade b/modules/web-control-center/src/main/js/views/templates/select.jade
deleted file mode 100644
index b219f13..0000000
--- a/modules/web-control-center/src/main/js/views/templates/select.jade
+++ /dev/null
@@ -1,26 +0,0 @@
-//-
-    Licensed to the Apache Software Foundation (ASF) under one or more
-    contributor license agreements.  See the NOTICE file distributed with
-    this work for additional information regarding copyright ownership.
-    The ASF licenses this file to You under the Apache License, Version 2.0
-    (the "License"); you may not use this file except in compliance with
-    the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
-
-ul.select.dropdown-menu(tabindex='-1' ng-show='$isVisible()' role='select')
-    li(role='presentation' ng-repeat='match in $matches')
-        hr(ng-if='match.value == undefined' style='margin: 5px 0')
-        a(style='cursor: default; padding: 3px 6px;' role='menuitem' tabindex='-1' ng-class='{active: $isActive($index)}' ng-click='$select($index, $event)')
-            i(class='{{$iconCheckmark}}' ng-if='$isActive($index)' ng-class='{active: $isActive($index)}' style='color: #ec1c24; margin-left: 15px; line-height: 20px; float: right;background-color: transparent;')
-            span(ng-bind='match.label')
-    li(ng-if='$showAllNoneButtons || ($isMultiple && $matches.length > 5)')
-        hr(style='margin: 5px 0')
-        a(ng-click='$selectAll()') {{$allText}}
-        a(ng-click='$selectNone()') {{$noneText}}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/web-control-center/src/main/js/views/templates/tab.jade
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/views/templates/tab.jade b/modules/web-control-center/src/main/js/views/templates/tab.jade
deleted file mode 100644
index 6c7afc5..0000000
--- a/modules/web-control-center/src/main/js/views/templates/tab.jade
+++ /dev/null
@@ -1,26 +0,0 @@
-//-
-    Licensed to the Apache Software Foundation (ASF) under one or more
-    contributor license agreements.  See the NOTICE file distributed with
-    this work for additional information regarding copyright ownership.
-    The ASF licenses this file to You under the Apache License, Version 2.0
-    (the "License"); you may not use this file except in compliance with
-    the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
-
-ul.nav(ng-class='$navClass', role='tablist')
-    li(role='presentation' ng-repeat='$pane in $panes track by $index' ng-class='[ $isActive($pane, $index) ? $activeClass : "", $pane.disabled ? "disabled" : "" ]')
-        a(ng-if='$index == 0' role='tab' data-toggle='tab' ng-click='!$pane.disabled && $setActive($pane.name || $index)' data-index='{{ $index }}' aria-controls='$pane.title') {{$pane.title}}
-            i.fa.fa-remove(ng-click='removeTab($index)' ng-if='$index > 0' style='margin-left: 5px')
-        a(ng-if='$index > 0' role='tab' data-toggle='tab' ng-click='!$pane.disabled && $setActive($pane.name || $index)' data-index='{{ $index }}' aria-controls='$pane.title') {{$pane.title}}: {{$index}}
-            i.fa.fa-remove(ng-click='removeTab($index)' style='margin-left: 5px')
-    li.pull-right(bs-tooltip data-title='Add new query')
-        a(role='tab' data-toggle='tab' ng-click='addTab()')
-            i.fa.fa-plus
-.tab-content(ng-transclude)


[03/41] incubator-ignite git commit: Merge branch 'ignite-961' of https://git-wip-us.apache.org/repos/asf/incubator-ignite into ignite-1121

Posted by an...@apache.org.
Merge branch 'ignite-961' of https://git-wip-us.apache.org/repos/asf/incubator-ignite into ignite-1121


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

Branch: refs/heads/ignite-1121
Commit: 126185fc0feab18630bda9f64604b2fbb4a044e4
Parents: ac005f3 8201b48
Author: Andrey <an...@gridgain.com>
Authored: Fri Jul 24 13:52:08 2015 +0700
Committer: Andrey <an...@gridgain.com>
Committed: Fri Jul 24 13:52:08 2015 +0700

----------------------------------------------------------------------
 .../ignite/examples/ExampleNodeStartup.java     |   2 +-
 .../examples/js/ExampleJsNodeStartup.java       |   2 +-
 examples/src/main/js/cache-query-example.js     |  24 +-
 .../main/js/cache-sql-fields-query-example.js   |  95 +--
 modules/apache-license-gen/pom.xml              |  13 -
 .../JettyRestProcessorAbstractSelfTest.java     | 676 +++++++++++--------
 .../java/org/apache/ignite/IgniteCache.java     |   3 +-
 .../apache/ignite/IgniteSystemProperties.java   |   8 +
 .../AffinityNodeAddressHashResolver.java        |   8 +-
 .../affinity/AffinityNodeHashResolver.java      |   5 +
 .../affinity/AffinityNodeIdHashResolver.java    |   6 +
 .../rendezvous/RendezvousAffinityFunction.java  |  22 +-
 .../store/jdbc/CacheJdbcBlobStoreFactory.java   |   2 +-
 .../configuration/CacheConfiguration.java       |   4 +-
 .../configuration/IgniteConfiguration.java      |  26 +
 .../apache/ignite/internal/IgniteKernal.java    |  45 +-
 .../ignite/internal/IgniteNodeAttributes.java   |   3 +
 .../processors/cache/GridCacheAdapter.java      |   2 +-
 .../processors/cache/GridCacheAttributes.java   |   8 +-
 .../processors/cache/GridCacheMvccManager.java  |  14 +
 .../processors/cache/GridCacheProcessor.java    | 113 ++--
 .../processors/cache/IgniteCacheProxy.java      |   2 +-
 .../processors/cache/IgniteInternalCache.java   |   4 +-
 .../distributed/dht/GridDhtTxFinishFuture.java  |  13 +-
 .../distributed/dht/GridDhtTxPrepareFuture.java |  16 +-
 .../GridDhtPartitionsExchangeFuture.java        |  10 +-
 .../near/GridNearOptimisticTxPrepareFuture.java |   4 +-
 .../GridNearPessimisticTxPrepareFuture.java     |   2 +-
 .../near/GridNearTxFinishFuture.java            |  17 +-
 .../cache/transactions/IgniteTxManager.java     |   5 +-
 .../processors/query/GridQueryProcessor.java    |   2 +-
 .../processors/rest/GridRestCommand.java        |  28 +-
 .../processors/rest/GridRestProcessor.java      |  18 +
 .../handlers/cache/GridCacheCommandHandler.java |  70 +-
 .../handlers/query/QueryCommandHandler.java     |  86 +--
 .../IgniteScriptingCommandHandler.java          |   5 +-
 .../scripting/IgniteScriptingConverter.java     |  15 +-
 .../scripting/IgniteScriptingProcessor.java     |  13 +-
 .../processors/scripting/ScriptingJsCache.java  |  15 +-
 .../ignite/internal/util/IgniteUtils.java       |  31 +-
 .../ignite/internal/util/nio/GridNioServer.java |   9 +
 .../util/nio/GridSelectorNioSessionImpl.java    |   8 +
 .../org/apache/ignite/json/JSONCacheObject.java |  95 ---
 .../ignite/spi/discovery/tcp/ServerImpl.java    |  58 +-
 .../spi/discovery/tcp/TcpDiscoverySpi.java      |   3 +-
 .../tcp/internal/TcpDiscoveryNode.java          |  18 +-
 .../IgniteClientReconnectFailoverTest.java      |   6 +
 .../cache/CacheAffinityCallSelfTest.java        |  10 +-
 .../cache/GridCachePutAllFailoverSelfTest.java  |   3 +
 .../GridCacheAbstractNodeRestartSelfTest.java   |   9 +
 ...NearDisabledOptimisticTxNodeRestartTest.java |  31 +
 .../IgniteCachePutRetryAbstractSelfTest.java    |  52 +-
 ...gniteCachePutRetryTransactionalSelfTest.java |  17 +-
 .../GridCachePartitionedFailoverSelfTest.java   |   5 -
 ...achePartitionedMultiNodeFullApiSelfTest.java |   4 +-
 ...ePartitionedOptimisticTxNodeRestartTest.java |  12 +-
 .../internal/util/nio/GridNioSelfTest.java      |  88 ++-
 .../internal/util/nio/GridNioSslSelfTest.java   |  16 +-
 .../tcp/TcpDiscoveryMultiThreadedTest.java      |   2 +
 ...DiscoveryNodeConfigConsistentIdSelfTest.java |  76 +++
 .../testframework/junits/GridAbstractTest.java  |   3 +-
 .../IgniteCacheFailoverTestSuite2.java          |   4 +
 .../testsuites/IgniteCacheRestartTestSuite.java |   5 +-
 .../IgniteSpiDiscoverySelfTestSuite.java        |   1 +
 .../processors/query/h2/sql/GridSqlAlias.java   |   4 +
 .../processors/query/h2/sql/GridSqlColumn.java  |   4 +
 .../processors/query/h2/sql/GridSqlConst.java   |   4 +
 .../processors/query/h2/sql/GridSqlElement.java |  40 +-
 .../query/h2/sql/GridSqlFunction.java           |   2 +
 .../processors/query/h2/sql/GridSqlJoin.java    |   4 +
 .../query/h2/sql/GridSqlOperation.java          |  21 +-
 .../query/h2/sql/GridSqlOperationType.java      |   2 +
 .../query/h2/sql/GridSqlParameter.java          |   4 +
 .../query/h2/sql/GridSqlPlaceholder.java        |   4 +
 .../processors/query/h2/sql/GridSqlQuery.java   |  25 +-
 .../query/h2/sql/GridSqlQueryParser.java        |  11 +-
 .../query/h2/sql/GridSqlQuerySplitter.java      | 405 ++++++-----
 .../processors/query/h2/sql/GridSqlSelect.java  |  91 +--
 .../query/h2/sql/GridSqlSubquery.java           |   4 +
 .../processors/query/h2/sql/GridSqlTable.java   |   4 +
 .../processors/query/h2/sql/GridSqlType.java    |  10 +-
 .../processors/query/h2/sql/GridSqlUnion.java   |  11 -
 .../cache/GridCacheCrossCacheQuerySelfTest.java |  77 +--
 ...QueryOffheapEvictsMultiThreadedSelfTest.java |   5 +
 .../IgniteCacheQueryNodeRestartSelfTest.java    |   5 -
 .../processors/json/IgniteJsonObject.java       |  13 +
 .../processors/json/JsonCacheObject.java        |  15 +
 .../processors/json/IgniteJsonCacheTest.java    |  25 +
 modules/nodejs/src/main/js/cache.js             |  26 +-
 modules/nodejs/src/main/js/ignite.js            |   4 +-
 modules/nodejs/src/main/js/server.js            |   2 +-
 .../ignite/internal/NodeJsCacheApiSelfTest.java |   7 -
 .../ignite/internal/NodeJsSqlQuerySelfTest.java |   3 +-
 modules/nodejs/src/test/js/test-cache-api.js    |  21 -
 modules/nodejs/src/test/js/test-compute.js      |   6 +-
 modules/rest-http/pom.xml                       |   6 +
 .../http/jetty/GridJettyRestHandler.java        |  40 +-
 .../jetty/RestGlassFishScriptingConverter.java  |  99 ++-
 .../org/apache/ignite/spark/IgniteContext.scala |  14 +
 pom.xml                                         |  12 +-
 100 files changed, 1734 insertions(+), 1268 deletions(-)
----------------------------------------------------------------------



[20/41] incubator-ignite git commit: IGNITE-843: Finished XML generation for cache type metadata groups.

Posted by an...@apache.org.
IGNITE-843: Finished XML generation for cache type metadata groups.


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

Branch: refs/heads/ignite-1121
Commit: 9018cc4bc7616828384b6e6fdef77667d57b77a1
Parents: 34cd6ec
Author: AKuznetsov <ak...@gridgain.com>
Authored: Tue Jul 28 15:31:32 2015 +0700
Committer: AKuznetsov <ak...@gridgain.com>
Committed: Tue Jul 28 15:31:32 2015 +0700

----------------------------------------------------------------------
 .../main/js/controllers/metadata-controller.js  |  4 +-
 modules/web-control-center/src/main/js/db.js    |  2 +-
 .../src/main/js/routes/generator/common.js      | 11 ++++-
 .../src/main/js/routes/generator/xml.js         | 43 +++++++++-----------
 .../src/main/js/views/includes/controls.jade    |  4 +-
 5 files changed, 34 insertions(+), 30 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/9018cc4b/modules/web-control-center/src/main/js/controllers/metadata-controller.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/controllers/metadata-controller.js b/modules/web-control-center/src/main/js/controllers/metadata-controller.js
index 47c8687..db10ddc 100644
--- a/modules/web-control-center/src/main/js/controllers/metadata-controller.js
+++ b/modules/web-control-center/src/main/js/controllers/metadata-controller.js
@@ -104,8 +104,8 @@ controlCenterModule.controller('metadataController', ['$scope', '$http', '$commo
         ];
 
         $scope.sortDirections = [
-            {value: 'ASC', label: 'ASC'},
-            {value: 'DESC', label: 'DESC'}
+            {value: false, label: 'ASC'},
+            {value: true, label: 'DESC'}
         ];
 
         $scope.data = {

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/9018cc4b/modules/web-control-center/src/main/js/db.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/db.js b/modules/web-control-center/src/main/js/db.js
index e6fb99b..5232e24 100644
--- a/modules/web-control-center/src/main/js/db.js
+++ b/modules/web-control-center/src/main/js/db.js
@@ -78,7 +78,7 @@ var CacheTypeMetadataSchema = new Schema({
     ascendingFields: [{name: String, className: String}],
     descendingFields:  [{name: String, className: String}],
     textFields: [String],
-    groups: [{name: String, fields: [{name: String, className: String, direction: String}]}]
+    groups: [{name: String, fields: [{name: String, className: String, direction: Boolean}]}]
 });
 
 exports.CacheTypeMetadata = mongoose.model('CacheTypeMetadata', CacheTypeMetadataSchema);

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/9018cc4b/modules/web-control-center/src/main/js/routes/generator/common.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/routes/generator/common.js b/modules/web-control-center/src/main/js/routes/generator/common.js
index 05405d3..a300bb5 100644
--- a/modules/web-control-center/src/main/js/routes/generator/common.js
+++ b/modules/web-control-center/src/main/js/routes/generator/common.js
@@ -174,7 +174,7 @@ exports.marshallers = {
     JdkMarshaller: new ClassDescriptor('org.apache.ignite.marshaller.jdk.JdkMarshaller', {})
 };
 
-exports.knownBuildInClasses = {
+var javaBuildInClasses = {
     BigDecimal: {className: 'java.math.Boolean'},
     Boolean: {className: 'java.lang.Boolean'},
     Byte: {className: 'java.lang.Byte'},
@@ -190,6 +190,15 @@ exports.knownBuildInClasses = {
     UUID: {className: 'java.util.UUID'}
 };
 
+exports.javaBuildInClass = function (className) {
+    var fullClassName = javaBuildInClasses[className];
+
+    if (fullClassName)
+        return fullClassName.className;
+
+    return className;
+};
+
 exports.knownClasses = {
     Oracle: new ClassDescriptor('org.apache.ignite.cache.store.jdbc.dialect.OracleDialect', {}),
     DB2: new ClassDescriptor('org.apache.ignite.cache.store.jdbc.dialect.DB2Dialect', {}),

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/9018cc4b/modules/web-control-center/src/main/js/routes/generator/xml.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/routes/generator/xml.js b/modules/web-control-center/src/main/js/routes/generator/xml.js
index c266722..dbb6935 100644
--- a/modules/web-control-center/src/main/js/routes/generator/xml.js
+++ b/modules/web-control-center/src/main/js/routes/generator/xml.js
@@ -337,7 +337,7 @@ function createEvictionPolicy(res, evictionPolicy, propertyName) {
     }
 }
 
-function addFields(res, meta, fieldsProperty) {
+function addCacheTypeMetadataDatabaseFields(res, meta, fieldsProperty) {
     var fields = meta[fieldsProperty];
 
     if (fields && fields.length > 0) {
@@ -350,11 +350,13 @@ function addFields(res, meta, fieldsProperty) {
 
             addProperty(res, field, 'databaseName');
 
-            addProperty(res, field, 'databaseType');
-            //addPropertyAsConst(res, field, databaseType, toJdbcTypeConst);
+            res.startBlock('<property name="databaseType">');
+            res.line('<util:constant static-field="java.sql.Types.' + field.databaseType + '"/>');
+            res.endBlock('</property>');
 
             addProperty(res, field, 'javaName');
-            addElement(res, 'property', 'name', 'javaType', 'value', knownBuildInClasses(field.javaType));
+
+            addElement(res, 'property', 'name', 'javaType', 'value', generatorUtils.javaBuildInClass(field.javaType));
 
             res.endBlock('</bean>');
         });
@@ -364,16 +366,7 @@ function addFields(res, meta, fieldsProperty) {
     }
 }
 
-function knownBuildInClasses(className) {
-    var fullClassName = generatorUtils.knownBuildInClasses[className];
-
-    if (fullClassName)
-        return fullClassName.className;
-
-    return className;
-}
-
-function addQueryFields(res, meta, fieldsProperty) {
+function addCacheTypeMetadataQueryFields(res, meta, fieldsProperty) {
     var fields = meta[fieldsProperty];
 
     if (fields && fields.length > 0) {
@@ -382,7 +375,7 @@ function addQueryFields(res, meta, fieldsProperty) {
         res.startBlock('<map>');
 
         _.forEach(fields, function (field) {
-            addElement(res, 'entry', 'key', field.name, 'value', knownBuildInClasses(field.className));
+            addElement(res, 'entry', 'key', field.name, 'value', generatorUtils.javaBuildInClass(field.className));
         });
 
         res.endBlock('</map>');
@@ -407,10 +400,12 @@ function addCacheTypeMetadataGroups(res, meta) {
 
                 _.forEach(fields, function (field) {
                     res.startBlock('<entry key="' + field.name + '">');
+
                     res.startBlock('<bean class="org.apache.ignite.lang.IgniteBiTuple">');
-                    res.line('<constructor-arg value="java.lang.String"/>');
-                    res.line('<constructor-arg value="false"/>');
+                    res.line('<constructor-arg value="' + generatorUtils.javaBuildInClass(field.className) + '"/>');
+                    res.line('<constructor-arg value="' + field.direction + '"/>');
                     res.endBlock('</bean>');
+
                     res.endBlock('</entry>');
                 });
 
@@ -436,12 +431,12 @@ function generateCacheTypeMetadataConfiguration(metaCfg, res) {
     addProperty(res, metaCfg, 'keyType');
     addProperty(res, metaCfg, 'valueType');
 
-    addFields(res, metaCfg, 'keyFields');
-    addFields(res, metaCfg, 'valueFields');
+    addCacheTypeMetadataDatabaseFields(res, metaCfg, 'keyFields');
+    addCacheTypeMetadataDatabaseFields(res, metaCfg, 'valueFields');
 
-    addQueryFields(res, metaCfg, 'queryFields');
-    addQueryFields(res, metaCfg, 'ascendingFields');
-    addQueryFields(res, metaCfg, 'descendingFields');
+    addCacheTypeMetadataQueryFields(res, metaCfg, 'queryFields');
+    addCacheTypeMetadataQueryFields(res, metaCfg, 'ascendingFields');
+    addCacheTypeMetadataQueryFields(res, metaCfg, 'descendingFields');
 
     addListProperty(res, metaCfg, 'textFields');
 
@@ -511,8 +506,8 @@ function generateCacheConfiguration(cacheCfg, res) {
         for (var i = 0; i < cacheCfg.indexedTypes.length; i++) {
             var pair = cacheCfg.indexedTypes[i];
 
-            res.line('<value>' + knownBuildInClasses(pair.keyClass) + '</value>');
-            res.line('<value>' + knownBuildInClasses(pair.valueClass) + '</value>');
+            res.line('<value>' + generatorUtils.javaBuildInClass(pair.keyClass) + '</value>');
+            res.line('<value>' + generatorUtils.javaBuildInClass(pair.valueClass) + '</value>');
         }
 
         res.endBlock('</list>');

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/9018cc4b/modules/web-control-center/src/main/js/views/includes/controls.jade
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/views/includes/controls.jade b/modules/web-control-center/src/main/js/views/includes/controls.jade
index 340a612..5bca8fc 100644
--- a/modules/web-control-center/src/main/js/views/includes/controls.jade
+++ b/modules/web-control-center/src/main/js/views/includes/controls.jade
@@ -173,7 +173,7 @@ mixin table-group-item-edit(fieldName, className, direction)
         button.form-control(ng-model=direction bs-select data-placeholder='Sort' bs-options='item.value as item.label for item in {{sortDirections}}')
     label.fieldSep /
     div(style='width: 38%; float: right')
-        input.form-control(type='text' ng-model=className placeholder='Class name')
+        input.form-control(type='text' ng-model=className placeholder='Class name' bs-typeahead data-min-length='1' bs-options='javaType for javaType in javaBuildInTypes')
     label.fieldSep /
     .input-tip
         input.form-control(type='text' ng-model=fieldName placeholder='Field name')
@@ -330,7 +330,7 @@ mixin form-row-custom(lblClasses, fieldClasses)
                                                     tr(ng-repeat='groupItem in group.fields')
                                                         td
                                                             div(ng-show='!tableGroupItemEditing(groupIndex, $index)')
-                                                                a.labelFormField(ng-click='curGroupItem = tableGroupItemStartEdit(groupIndex, $index); curFieldName = curGroupItem.name; curClassName = curGroupItem.className; curDirection = curGroupItem.direction') {{$index + 1}}) {{groupItem.name}} / {{groupItem.className}} / {{groupItem.direction}}
+                                                                a.labelFormField(ng-click='curGroupItem = tableGroupItemStartEdit(groupIndex, $index); curFieldName = curGroupItem.name; curClassName = curGroupItem.className; curDirection = curGroupItem.direction') {{$index + 1}}) {{groupItem.name}} / {{groupItem.className}} / {{groupItem.direction ? "DESC" : "ASC"}}
                                                                 +btn-remove('tableRemoveGroupItem(group, $index)', 'field.removeItemTip')
                                                             div(ng-show='tableGroupItemEditing(groupIndex, $index)')
                                                                 label.labelField {{$index + 1}})


[04/41] incubator-ignite git commit: Merge remote-tracking branch 'origin/ignite-1121' into ignite-1121

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

# Conflicts:
#	modules/web-control-center/src/main/js/package.json


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

Branch: refs/heads/ignite-1121
Commit: f965f6bf7c3c2d7d410c544047bea0d363f3f69f
Parents: 126185f 3e8a935
Author: Andrey <an...@gridgain.com>
Authored: Mon Jul 27 08:45:37 2015 +0700
Committer: Andrey <an...@gridgain.com>
Committed: Mon Jul 27 08:45:37 2015 +0700

----------------------------------------------------------------------
 .../main/java/org/apache/ignite/agent/Agent.java  |  5 ++---
 .../org/apache/ignite/agent/AgentCommandLine.java |  2 +-
 .../apache/ignite/agent/messages/AuthMessage.java |  8 ++++----
 .../apache/ignite/agent/messages/AuthResult.java  |  6 +++---
 .../apache/ignite/agent/messages/RestRequest.java |  2 +-
 .../apache/ignite/agent/messages/RestResult.java  |  4 ++--
 .../src/main/js/controllers/caches-controller.js  | 14 ++++++++++++++
 .../main/js/controllers/clusters-controller.js    |  6 ++----
 .../src/main/js/controllers/models/caches.json    | 14 ++++++++++++++
 .../src/main/js/controllers/models/metadata.json  |  8 +++++++-
 modules/web-control-center/src/main/js/db.js      |  2 ++
 .../src/main/js/routes/caches.js                  | 18 ++++++++++++++----
 .../src/main/js/views/includes/controls.jade      |  4 ++--
 13 files changed, 68 insertions(+), 25 deletions(-)
----------------------------------------------------------------------



[31/41] incubator-ignite git commit: # ignite-843 Rename

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/web-control-center/src/main/js/controllers/caches-controller.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/controllers/caches-controller.js b/modules/web-control-center/src/main/js/controllers/caches-controller.js
deleted file mode 100644
index e995233..0000000
--- a/modules/web-control-center/src/main/js/controllers/caches-controller.js
+++ /dev/null
@@ -1,349 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-controlCenterModule.controller('cachesController', ['$scope', '$http', '$common', '$confirm', '$copy', '$table', function ($scope, $http, $common, $confirm, $copy, $table) {
-        $scope.joinTip = $common.joinTip;
-        $scope.getModel = $common.getModel;
-        $scope.javaBuildInTypes = $common.javaBuildInTypes;
-
-        $scope.tableReset = $table.tableReset;
-        $scope.tableNewItem = $table.tableNewItem;
-        $scope.tableNewItemActive = $table.tableNewItemActive;
-        $scope.tableEditing = $table.tableEditing;
-        $scope.tableStartEdit = $table.tableStartEdit;
-        $scope.tableRemove = $table.tableRemove;
-
-        $scope.tableSimpleSave = $table.tableSimpleSave;
-        $scope.tableSimpleSaveVisible = $table.tableSimpleSaveVisible;
-        $scope.tableSimpleUp = $table.tableSimpleUp;
-        $scope.tableSimpleDown = $table.tableSimpleDown;
-        $scope.tableSimpleDownVisible = $table.tableSimpleDownVisible;
-
-        $scope.tablePairSave = $table.tablePairSave;
-        $scope.tablePairSaveVisible = $table.tablePairSaveVisible;
-
-        $scope.atomicities = [
-            {value: 'ATOMIC', label: 'ATOMIC'},
-            {value: 'TRANSACTIONAL', label: 'TRANSACTIONAL'}
-        ];
-
-        $scope.modes = [
-            {value: 'PARTITIONED', label: 'PARTITIONED'},
-            {value: 'REPLICATED', label: 'REPLICATED'},
-            {value: 'LOCAL', label: 'LOCAL'}
-        ];
-
-        $scope.atomicWriteOrderModes = [
-            {value: 'CLOCK', label: 'CLOCK'},
-            {value: 'PRIMARY', label: 'PRIMARY'}
-        ];
-
-        $scope.memoryModes = [
-            {value: 'ONHEAP_TIERED', label: 'ONHEAP_TIERED'},
-            {value: 'OFFHEAP_TIERED', label: 'OFFHEAP_TIERED'},
-            {value: 'OFFHEAP_VALUES', label: 'OFFHEAP_VALUES'}
-        ];
-
-        $scope.evictionPolicies = [
-            {value: 'LRU', label: 'LRU'},
-            {value: 'RND', label: 'Random'},
-            {value: 'FIFO', label: 'FIFO'},
-            {value: 'SORTED', label: 'Sorted'},
-            {value: undefined, label: 'Not set'}
-        ];
-
-        $scope.rebalanceModes = [
-            {value: 'SYNC', label: 'SYNC'},
-            {value: 'ASYNC', label: 'ASYNC'},
-            {value: 'NONE', label: 'NONE'}
-        ];
-
-        $scope.cacheStoreFactories = [
-            {value: 'CacheJdbcPojoStoreFactory', label: 'JDBC POJO store factory'},
-            {value: 'CacheJdbcBlobStoreFactory', label: 'JDBC BLOB store factory'},
-            {value: 'CacheHibernateBlobStoreFactory', label: 'Hibernate BLOB store factory'},
-            {value: undefined, label: 'Not set'}
-        ];
-
-        $scope.cacheStoreJdbcDialects = [
-            {value: 'Oracle', label: 'Oracle'},
-            {value: 'DB2', label: 'IBM DB2'},
-            {value: 'SQLServer', label: 'Microsoft SQL Server'},
-            {value: 'MySQL', label: 'My SQL'},
-            {value: 'PostgreSQL', label: 'Postgre SQL'},
-            {value: 'H2', label: 'H2 database'}
-        ];
-
-        $scope.general = [];
-        $scope.advanced = [];
-
-        $http.get('/models/caches.json')
-            .success(function (data) {
-                $scope.screenTip = data.screenTip;
-                $scope.general = data.general;
-                $scope.advanced = data.advanced;
-            })
-            .error(function (errMsg) {
-                $common.showError(errMsg);
-            });
-
-        $scope.caches = [];
-        $scope.queryMetadata = [];
-        $scope.storeMetadata = [];
-
-        $scope.required = function (field) {
-            var model = $common.isDefined(field.path) ? field.path + '.' + field.model : field.model;
-
-            var backupItem = $scope.backupItem;
-
-            var memoryMode = backupItem.memoryMode;
-
-            var onHeapTired = memoryMode == 'ONHEAP_TIERED';
-            var offHeapTired = memoryMode == 'OFFHEAP_TIERED';
-
-            var offHeapMaxMemory = backupItem.offHeapMaxMemory;
-
-            if (model == 'offHeapMaxMemory' && offHeapTired)
-                return true;
-
-            if (model == 'evictionPolicy.kind' && onHeapTired)
-                return backupItem.swapEnabled || ($common.isDefined(offHeapMaxMemory) && offHeapMaxMemory >= 0);
-
-            return false;
-        };
-
-        $scope.tableSimpleValid = function (item, field, fx, index) {
-            var model = item[field.model];
-
-            if ($common.isDefined(model)) {
-                var idx = _.indexOf(model, fx);
-
-                // Found itself.
-                if (index >= 0 && index == idx)
-                    return true;
-
-                // Found duplicate.
-                if (idx >= 0) {
-                    $common.showError('SQL function such class name already exists!');
-
-                    return false;
-                }
-            }
-
-            return true;
-        };
-
-        $scope.tablePairValid = function (item, field, keyCls, valCls, index) {
-            var model = item[field.model];
-
-            if ($common.isDefined(model)) {
-                var idx = _.findIndex(model, function (pair) {
-                    return pair.keyClass == keyCls
-                });
-
-                // Found itself.
-                if (index >= 0 && index == idx)
-                    return true;
-
-                // Found duplicate.
-                if (idx >= 0) {
-                    $common.showError('Indexed type with such key class already exists!');
-
-                    return false;
-                }
-            }
-
-            return true;
-        };
-
-        // When landing on the page, get caches and show them.
-        $http.post('caches/list')
-            .success(function (data) {
-                $scope.spaces = data.spaces;
-                $scope.caches = data.caches;
-
-                _.forEach(data.metadatas, function (meta) {
-                    var kind = meta.kind;
-
-                    if (kind == 'query' || kind == 'both')
-                        $scope.queryMetadata.push(meta);
-
-                    if (kind == 'store' || kind == 'both')
-                        $scope.storeMetadata.push(meta);
-                });
-
-                var restoredItem = angular.fromJson(sessionStorage.cacheBackupItem);
-
-                if (restoredItem) {
-                    if (restoredItem._id) {
-                        var idx = _.findIndex($scope.caches, function (cache) {
-                            return cache._id == restoredItem._id;
-                        });
-
-                        if (idx >= 0) {
-                            $scope.selectedItem = $scope.caches[idx];
-                            $scope.backupItem = restoredItem;
-                        }
-                        else
-                            sessionStorage.removeItem('cacheBackupItem');
-                    }
-                    else
-                        $scope.backupItem = restoredItem;
-                }
-                else if ($scope.caches.length > 0)
-                    $scope.selectItem($scope.caches[0]);
-
-                $scope.$watch('backupItem', function (val) {
-                    if (val)
-                        sessionStorage.cacheBackupItem = angular.toJson(val);
-                }, true);
-            })
-            .error(function (errMsg) {
-                $common.showError(errMsg);
-            });
-
-        $scope.selectItem = function (item) {
-            $table.tableReset();
-
-            $scope.selectedItem = item;
-            $scope.backupItem = angular.copy(item);
-        };
-
-        // Add new cache.
-        $scope.createItem = function () {
-            $table.tableReset();
-
-            $scope.backupItem = {mode: 'PARTITIONED', atomicityMode: 'ATOMIC', readFromBackup: true, copyOnRead: true};
-            $scope.backupItem.queryMetadata = [];
-            $scope.backupItem.spaceMetadata = [];
-            $scope.backupItem.space = $scope.spaces[0]._id;
-        };
-
-        // Check cache logical consistency.
-        function validate(item) {
-            var cacheStoreFactorySelected = item.cacheStoreFactory && item.cacheStoreFactory.kind;
-
-            if (cacheStoreFactorySelected && !(item.readThrough || item.writeThrough)) {
-                $common.showError('Store is configured but read/write through are not enabled!');
-
-                return false;
-            }
-
-            if ((item.readThrough || item.writeThrough) && !cacheStoreFactorySelected) {
-                $common.showError('Read / write through are enabled but store is not configured!');
-
-                return false;
-            }
-
-            if (item.writeBehindEnabled && !cacheStoreFactorySelected) {
-                $common.showError('Write behind enabled but store is not configured!');
-
-                return false;
-            }
-
-            return true;
-        }
-
-        // Save cache into database.
-        function save(item) {
-            $http.post('caches/save', item)
-                .success(function (_id) {
-                    var idx = _.findIndex($scope.caches, function (cache) {
-                        return cache._id == _id;
-                    });
-
-                    if (idx >= 0)
-                        angular.extend($scope.caches[idx], item);
-                    else {
-                        item._id = _id;
-
-                        $scope.caches.push(item);
-                    }
-
-                    $scope.selectItem(item);
-
-                    $common.showInfo('Cache "' + item.name + '" saved.');
-                })
-                .error(function (errMsg) {
-                    $common.showError(errMsg);
-                });
-        }
-
-        // Save cache.
-        $scope.saveItem = function () {
-            $table.tableReset();
-
-            var item = $scope.backupItem;
-
-            if (validate(item))
-                save(item);
-        };
-
-        // Save cache with new name.
-        $scope.saveItemAs = function () {
-            $table.tableReset();
-
-            if (validate($scope.backupItem))
-                $copy.show($scope.backupItem.name).then(function (newName) {
-                    var item = angular.copy($scope.backupItem);
-
-                    item._id = undefined;
-                    item.name = newName;
-
-                    save(item);
-                });
-        };
-
-        // Remove cache from db.
-        $scope.removeItem = function () {
-            $table.tableReset();
-
-            var selectedItem = $scope.selectedItem;
-
-            $confirm.show('Are you sure you want to remove cache: "' + selectedItem.name + '"?').then(
-                function () {
-                    var _id = selectedItem._id;
-
-                    $http.post('caches/remove', {_id: _id})
-                        .success(function () {
-                            $common.showInfo('Cache has been removed: ' + selectedItem.name);
-
-                            var caches = $scope.caches;
-
-                            var idx = _.findIndex(caches, function (cache) {
-                                return cache._id == _id;
-                            });
-
-                            if (idx >= 0) {
-                                caches.splice(idx, 1);
-
-                                if (caches.length > 0)
-                                    $scope.selectItem(caches[0]);
-                                else {
-                                    $scope.selectedItem = undefined;
-                                    $scope.backupItem = undefined;
-                                }
-                            }
-                        })
-                        .error(function (errMsg) {
-                            $common.showError(errMsg);
-                        });
-                }
-            );
-        };
-    }]
-);
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/web-control-center/src/main/js/controllers/clusters-controller.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/controllers/clusters-controller.js b/modules/web-control-center/src/main/js/controllers/clusters-controller.js
deleted file mode 100644
index 0b18868..0000000
--- a/modules/web-control-center/src/main/js/controllers/clusters-controller.js
+++ /dev/null
@@ -1,308 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-controlCenterModule.controller('clustersController', ['$scope', '$http', '$common', '$confirm', '$copy', '$table', function ($scope, $http, $common, $confirm, $copy, $table) {
-        $scope.joinTip = $common.joinTip;
-        $scope.getModel = $common.getModel;
-
-        $scope.tableReset = $table.tableReset;
-        $scope.tableNewItem = $table.tableNewItem;
-        $scope.tableNewItemActive = $table.tableNewItemActive;
-        $scope.tableEditing = $table.tableEditing;
-        $scope.tableStartEdit = $table.tableStartEdit;
-        $scope.tableRemove = $table.tableRemove;
-
-        $scope.tableSimpleSave = $table.tableSimpleSave;
-        $scope.tableSimpleSaveVisible = $table.tableSimpleSaveVisible;
-        $scope.tableSimpleUp = $table.tableSimpleUp;
-        $scope.tableSimpleDown = $table.tableSimpleDown;
-        $scope.tableSimpleDownVisible = $table.tableSimpleDownVisible;
-
-        $scope.templates = [
-            {value: {discovery: {kind: 'Multicast', Vm: {addresses: ['127.0.0.1:47500..47510']}, Multicast: {}}},label: 'multicast'},
-            {value: {discovery: {kind: 'Vm', Vm: {addresses: ['127.0.0.1:47500..47510']}}}, label: 'local'}
-        ];
-
-        $scope.discoveries = [
-            {value: 'Vm', label: 'static IPs'},
-            {value: 'Multicast', label: 'multicast'},
-            {value: 'S3', label: 'AWS S3'},
-            {value: 'Cloud', label: 'apache jclouds'},
-            {value: 'GoogleStorage', label: 'google cloud storage'},
-            {value: 'Jdbc', label: 'JDBC'},
-            {value: 'SharedFs', label: 'shared filesystem'}
-        ];
-
-        $scope.swapSpaceSpis = [
-            {value: 'FileSwapSpaceSpi', label: 'File-based swap'},
-            {value: undefined, label: 'Not set'}
-        ];
-
-        $scope.events = [];
-
-        for (var eventGroupName in eventGroups) {
-            if (eventGroups.hasOwnProperty(eventGroupName)) {
-                $scope.events.push({value: eventGroupName, label: eventGroupName});
-            }
-        }
-
-        $scope.cacheModes = [
-            {value: 'LOCAL', label: 'LOCAL'},
-            {value: 'REPLICATED', label: 'REPLICATED'},
-            {value: 'PARTITIONED', label: 'PARTITIONED'}
-        ];
-
-        $scope.deploymentModes = [
-            {value: 'PRIVATE', label: 'PRIVATE'},
-            {value: 'ISOLATED', label: 'ISOLATED'},
-            {value: 'SHARED', label: 'SHARED'},
-            {value: 'CONTINUOUS', label: 'CONTINUOUS'}
-        ];
-
-        $scope.transactionConcurrency = [
-            {value: 'OPTIMISTIC', label: 'OPTIMISTIC'},
-            {value: 'PESSIMISTIC', label: 'PESSIMISTIC'}
-        ];
-
-        $scope.transactionIsolation = [
-            {value: 'READ_COMMITTED', label: 'READ_COMMITTED'},
-            {value: 'REPEATABLE_READ', label: 'REPEATABLE_READ'},
-            {value: 'SERIALIZABLE', label: 'SERIALIZABLE'}
-        ];
-
-        $scope.segmentationPolicy = [
-            {value: 'RESTART_JVM', label: 'RESTART_JVM'},
-            {value: 'STOP', label: 'STOP'},
-            {value: 'NOOP', label: 'NOOP'}
-        ];
-
-        $scope.marshallers = [
-            {value: 'OptimizedMarshaller', label: 'OptimizedMarshaller'},
-            {value: 'JdkMarshaller', label: 'JdkMarshaller'}
-        ];
-
-        $scope.tableSimpleValid = function (item, field, val, index) {
-            var model = $common.getModel(item, field)[field.model];
-
-            if ($common.isDefined(model)) {
-                var idx = _.indexOf(model, val);
-
-                // Found itself.
-                if (index >= 0 && index == idx)
-                    return true;
-
-                // Found duplicate.
-                if (idx >= 0) {
-                    var msg = 'Such IP address already exists!';
-
-                    if (field.model == 'regions')
-                        msg = 'Such region already exists!';
-                    if (field.model == 'zones')
-                        msg = 'Such zone already exists!';
-
-                    $common.showError(msg);
-
-                    return false;
-                }
-            }
-
-            return true;
-        };
-
-        $scope.clusters = [];
-
-        $http.get('/models/clusters.json')
-            .success(function (data) {
-                $scope.screenTip = data.screenTip;
-                $scope.templateTip = data.templateTip;
-
-                $scope.general = data.general;
-                $scope.advanced = data.advanced;
-            })
-            .error(function (errMsg) {
-                $common.showError(errMsg);
-            });
-
-        // When landing on the page, get clusters and show them.
-        $http.post('clusters/list')
-            .success(function (data) {
-                $scope.caches = data.caches;
-                $scope.spaces = data.spaces;
-                $scope.clusters = data.clusters;
-
-                var restoredItem = angular.fromJson(sessionStorage.clusterBackupItem);
-
-                if (restoredItem) {
-                    if (restoredItem._id) {
-                        var idx = _.findIndex($scope.clusters, function (cluster) {
-                            return cluster._id == restoredItem._id;
-                        });
-
-                        if (idx >= 0) {
-                            $scope.selectedItem = $scope.clusters[idx];
-                            $scope.backupItem = restoredItem;
-                        }
-                        else
-                            sessionStorage.removeItem('clusterBackupItem');
-                    }
-                    else
-                        $scope.backupItem = restoredItem;
-                }
-                else if ($scope.clusters.length > 0)
-                    $scope.selectItem($scope.clusters[0]);
-
-                $scope.$watch('backupItem', function (val) {
-                    if (val)
-                        sessionStorage.clusterBackupItem = angular.toJson(val);
-                }, true);
-            })
-            .error(function (errMsg) {
-                $common.showError(errMsg);
-            });
-
-        $scope.selectItem = function (item) {
-            $table.tableReset();
-
-            $scope.selectedItem = item;
-            $scope.backupItem = angular.copy(item);
-        };
-
-        // Add new cluster.
-        $scope.createItem = function () {
-            $table.tableReset();
-
-            $scope.backupItem = angular.copy($scope.create.template);
-            $scope.backupItem.caches = [];
-            $scope.backupItem.space = $scope.spaces[0]._id;
-        };
-
-        $scope.indexOfCache = function (cacheId) {
-            return _.findIndex($scope.caches, function (cache) {
-                return cache.value == cacheId;
-            });
-        };
-
-        // Check cluster logical consistency.
-        function validate(item) {
-            if (!item.swapSpaceSpi || !item.swapSpaceSpi.kind && item.caches) {
-                for (var i = 0; i < item.caches.length; i++) {
-                    var idx = $scope.indexOfCache(item.caches[i]);
-
-                    if (idx >= 0) {
-                        var cache = $scope.caches[idx];
-
-                        if (cache.swapEnabled) {
-                            $common.showError('Swap space SPI is not configured, but cache "' + cache.label + '" configured to use swap!');
-
-                            return false;
-                        }
-                    }
-                }
-            }
-
-            return true;
-        }
-
-        // Save cluster in database.
-        function save(item) {
-            $http.post('clusters/save', item)
-                .success(function (_id) {
-                    var idx = _.findIndex($scope.clusters, function (cluster) {
-                        return cluster._id == _id;
-                    });
-
-                    if (idx >= 0)
-                        angular.extend($scope.clusters[idx], item);
-                    else {
-                        item._id = _id;
-
-                        $scope.clusters.push(item);
-                    }
-
-                    $scope.selectItem(item);
-
-                    $common.showInfo('Cluster "' + item.name + '" saved.');
-                })
-                .error(function (errMsg) {
-                    $common.showError(errMsg);
-                });
-        }
-
-        // Save cluster.
-        $scope.saveItem = function () {
-            $table.tableReset();
-
-            var item = $scope.backupItem;
-
-            if (validate(item))
-                save(item);
-        };
-
-        // Save cluster with new name.
-        $scope.saveItemAs = function () {
-            $table.tableReset();
-
-            if (validate($scope.backupItem))
-                $copy.show($scope.backupItem.name).then(function (newName) {
-                    var item = angular.copy($scope.backupItem);
-
-                    item._id = undefined;
-                    item.name = newName;
-
-                    save(item);
-                });
-        };
-
-        // Remove cluster from db.
-        $scope.removeItem = function () {
-            $table.tableReset();
-
-            var selectedItem = $scope.selectedItem;
-
-            $confirm.show('Are you sure you want to remove cluster: "' + selectedItem.name + '"?').then(
-                function () {
-                    var _id = selectedItem._id;
-
-                    $http.post('clusters/remove', {_id: _id})
-                        .success(function () {
-                            $common.showInfo('Cluster has been removed: ' + selectedItem.name);
-
-                            var clusters = $scope.clusters;
-
-                            var idx = _.findIndex(clusters, function (cluster) {
-                                return cluster._id == _id;
-                            });
-
-                            if (idx >= 0) {
-                                clusters.splice(idx, 1);
-
-                                if (clusters.length > 0)
-                                    $scope.selectItem(clusters[0]);
-                                else {
-                                    $scope.selectedItem = undefined;
-                                    $scope.backupItem = undefined;
-                                }
-                            }
-                        })
-                        .error(function (errMsg) {
-                            $common.showError(errMsg);
-                        });
-                }
-            );
-        };
-    }]
-);
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/web-control-center/src/main/js/controllers/common-module.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/controllers/common-module.js b/modules/web-control-center/src/main/js/controllers/common-module.js
deleted file mode 100644
index df2ff19..0000000
--- a/modules/web-control-center/src/main/js/controllers/common-module.js
+++ /dev/null
@@ -1,484 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-var controlCenterModule = angular.module('ignite-web-control-center', ['smart-table', 'mgcrea.ngStrap', 'ui.ace', 'ngSanitize']);
-
-// Modal popup configuration.
-controlCenterModule.config(function ($modalProvider) {
-    angular.extend($modalProvider.defaults, {
-        html: true
-    });
-});
-
-// Tooltips configuration.
-controlCenterModule.config(function ($tooltipProvider) {
-    angular.extend($tooltipProvider.defaults, {
-        container: 'body',
-        placement: 'right',
-        html: 'true',
-        trigger: 'click hover'
-    });
-});
-
-// Comboboxes configuration.
-controlCenterModule.config(function ($selectProvider) {
-    angular.extend($selectProvider.defaults, {
-        maxLength: '1',
-        allText: 'Select All',
-        noneText: 'Clear All',
-        templateUrl: '/select',
-        iconCheckmark: 'fa fa-check',
-        caretHtml: '<span class="caret"></span>'
-    });
-});
-
-// Alerts configuration.
-controlCenterModule.config(function ($alertProvider) {
-    angular.extend($alertProvider.defaults, {
-        container: 'body',
-        placement: 'top-right',
-        duration: '5',
-        type: 'danger'
-    });
-});
-
-// Common functions to be used in controllers.
-controlCenterModule.service('$common', ['$alert', function ($alert) {
-    var msgModal = undefined;
-
-    function errorMessage(errMsg) {
-        return errMsg ? errMsg : 'Internal server error.';
-    }
-
-    function isDefined(v) {
-        return !(v === undefined || v === null);
-    }
-
-    return {
-        getModel: function (obj, field) {
-            var path = field.path;
-
-            if (!isDefined(path))
-                return obj;
-
-            path = path.replace(/\[(\w+)\]/g, '.$1'); // convert indexes to properties
-            path = path.replace(/^\./, '');           // strip a leading dot
-
-            var segs = path.split('.');
-            var root = obj;
-
-            while (segs.length > 0) {
-                var pathStep = segs.shift();
-
-                if (typeof root[pathStep] === 'undefined')
-                    root[pathStep] = {};
-
-                root = root[pathStep];
-            }
-
-            return root;
-        },
-        joinTip: function (arr) {
-            if (!arr) {
-                return arr;
-            }
-
-            var lines = arr.map(function (line) {
-                var rtrimmed = line.replace(/\s+$/g, '');
-
-                if (rtrimmed.indexOf('>', this.length - 1) == -1) {
-                    rtrimmed = rtrimmed + '<br/>';
-                }
-
-                return rtrimmed;
-            });
-
-            return lines.join("");
-        },
-        isDefined: isDefined,
-        isNonEmpty: function (s) {
-            return isDefined(s) && s.trim().length > 0;
-        },
-        errorMessage: errorMessage,
-        showError: function (msg) {
-            if (msgModal)
-                msgModal.hide();
-
-            msgModal = $alert({title: errorMessage(msg)});
-        },
-        showInfo: function (msg) {
-            if (msgModal)
-                msgModal.hide();
-
-            msgModal = $alert({
-                type: 'success',
-                title: msg,
-                duration: 2
-            });
-        },
-        javaBuildInTypes: [
-            'Boolean', 'Byte', 'Date', 'Double', 'Float', 'Integer', 'Long', 'Short', 'String', 'Time', 'Timestamp', 'UUID'
-        ]
-    }
-}]);
-
-// Confirm popup service.
-controlCenterModule.service('$confirm', function ($modal, $rootScope, $q) {
-    var scope = $rootScope.$new();
-
-    var deferred;
-
-    scope.ok = function () {
-        deferred.resolve();
-
-        confirmModal.hide();
-    };
-
-    var confirmModal = $modal({templateUrl: '/confirm', scope: scope, placement: 'center', show: false});
-
-    var parentShow = confirmModal.show;
-
-    confirmModal.show = function (content) {
-        scope.content = content || 'Confirm deletion?';
-
-        deferred = $q.defer();
-
-        parentShow();
-
-        return deferred.promise;
-    };
-
-    return confirmModal;
-});
-
-// "Save as" popup service.
-controlCenterModule.service('$copy', function ($modal, $rootScope, $q) {
-    var scope = $rootScope.$new();
-
-    var deferred;
-
-    scope.ok = function (newName) {
-        deferred.resolve(newName);
-
-        copyModal.hide();
-    };
-
-    var copyModal = $modal({templateUrl: '/copy', scope: scope, placement: 'center', show: false});
-
-    var parentShow = copyModal.show;
-
-    copyModal.show = function (oldName) {
-        scope.newName = oldName + '(1)';
-
-        deferred = $q.defer();
-
-        parentShow();
-
-        return deferred.promise;
-    };
-
-    return copyModal;
-});
-
-// Tables support service.
-controlCenterModule.service('$table', ['$common', function ($common) {
-    function _swapSimpleItems(a, ix1, ix2) {
-        var tmp = a[ix1];
-
-        a[ix1] = a[ix2];
-        a[ix2] = tmp;
-    }
-
-    function _model(item, field) {
-        return $common.getModel(item, field);
-    }
-
-    var table = {name: 'none', editIndex: -1};
-
-    function _tableReset() {
-        table.name = 'none';
-        table.editIndex = -1;
-    }
-
-    function _tableState(name, editIndex) {
-        table.name = name;
-        table.editIndex = editIndex;
-    }
-
-    return {
-        tableState: function (name, editIndex) {
-            _tableState(name, editIndex);
-        },
-        tableReset: function () {
-            _tableReset();
-        },
-        tableNewItem: function (field) {
-            _tableState(field.model, -1);
-        },
-        tableNewItemActive: function (field) {
-            return table.name == field.model && table.editIndex < 0;
-        },
-        tableEditing: function (field, index) {
-            return table.name == field.model && table.editIndex == index;
-        },
-        tableStartEdit: function (item, field, index) {
-            _tableState(field.model, index);
-
-            return _model(item, field)[field.model][index];
-        },
-        tableRemove: function (item, field, index) {
-            _tableReset();
-
-            _model(item, field)[field.model].splice(index, 1);
-        },
-        tableSimpleSave: function (valueValid, item, field, newValue, index) {
-            if (valueValid(item, field, newValue, index)) {
-                _tableReset();
-
-                if (index < 0) {
-                    if (_model(item, field)[field.model])
-                        _model(item, field)[field.model].push(newValue);
-                    else
-                        _model(item, field)[field.model] = [newValue];
-                }
-                else
-                    _model(item, field)[field.model][index] = newValue;
-            }
-        },
-        tableSimpleSaveVisible: function (newValue) {
-            return $common.isNonEmpty(newValue);
-        },
-        tableSimpleUp: function (item, field, index) {
-            _tableReset();
-
-            _swapSimpleItems(_model(item, field)[field.model], index, index - 1);
-        },
-        tableSimpleDown: function (item, field, index) {
-            _tableReset();
-
-            _swapSimpleItems(_model(item, field)[field.model], index, index + 1);
-        },
-        tableSimpleDownVisible: function (item, field, index) {
-            return index < _model(item, field)[field.model].length - 1;
-        },
-        tablePairSave: function (pairValid, item, field, newKey, newValue, index) {
-            if (pairValid(item, field, newKey, newValue, index)) {
-                _tableReset();
-
-                var pair = {};
-
-                if (index < 0) {
-                    pair[field.keyName] = newKey;
-                    pair[field.valueName] = newValue;
-
-                    if (item[field.model])
-                        item[field.model].push(pair);
-                    else
-                        item[field.model] = [pair];
-                }
-                else {
-                    pair = item[field.model][index];
-
-                    pair[field.keyName] = newKey;
-                    pair[field.valueName] = newValue;
-                }
-            }
-        },
-        tablePairSaveVisible: function (newKey, newValue) {
-            return $common.isNonEmpty(newKey) && $common.isNonEmpty(newValue);
-        }
-    }
-}]);
-
-
-// Filter to decode name using map(value, label).
-controlCenterModule.filter('displayValue', function () {
-    return function (v, m, dflt) {
-        var i = _.findIndex(m, function (item) {
-            return item.value == v;
-        });
-
-        if (i >= 0) {
-            return m[i].label;
-        }
-
-        if (dflt) {
-            return dflt;
-        }
-
-        return 'Unknown value';
-    }
-});
-
-/**
- * Filter for replacing all occurrences of {@code org.apache.ignite.} with {@code o.a.i.},
- * {@code org.apache.ignite.internal.} with {@code o.a.i.i.},
- * {@code org.apache.ignite.internal.visor.} with {@code o.a.i.i.v.} and
- * {@code org.apache.ignite.scalar.} with {@code o.a.i.s.}.
- *
- * @param s String to replace in.
- * @return Replaces string.
- */
-controlCenterModule.filter('compact', function () {
-    return function (s) {
-        return s.replace("org.apache.ignite.internal.visor.", "o.a.i.i.v.").
-            replace("org.apache.ignite.internal.", "o.a.i.i.").
-            replace("org.apache.ignite.scalar.", "o.a.i.s.").
-            replace("org.apache.ignite.", "o.a.i.");
-    }
-});
-
-// Directive to enable validation for IP addresses.
-controlCenterModule.directive('ipaddress', function () {
-    const ip = '(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])';
-    const port = '([0-9]{1,4}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])';
-    const portRange = '(:' + port + '(..' + port + ')?)?';
-    const host = '(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])';
-
-    return {
-        require: 'ngModel',
-        link: function (scope, elem, attrs, ctrl) {
-            ctrl.$validators.ipaddress = function (modelValue, viewValue) {
-                if (ctrl.$isEmpty(modelValue) || !attrs['ipaddress'])
-                    return true;
-
-                return viewValue.match(new RegExp('(^' + ip + portRange + '$)|(^' + host + portRange + '$)')) != null;
-            }
-        }
-    }
-});
-
-// Directive to enable validation to match specified value.
-controlCenterModule.directive('match', function ($parse) {
-    return {
-        require: 'ngModel',
-        link: function (scope, elem, attrs, ctrl) {
-            scope.$watch(function () {
-                return $parse(attrs.match)(scope) === ctrl.$modelValue;
-            }, function (currentValue) {
-                ctrl.$setValidity('mismatch', currentValue);
-            });
-        }
-    };
-});
-
-// Directive to bind ENTER key press with some user action.
-controlCenterModule.directive('ngEnter', function() {
-    return function(scope, element, attrs) {
-        element.bind('keydown keypress', function(event) {
-            if (event.which === 13) {
-                scope.$apply(function() {
-                    scope.$eval(attrs.ngEnter);
-                });
-
-                event.preventDefault();
-            }
-        });
-    };
-});
-
-// Directive to bind ESC key press with some user action.
-controlCenterModule.directive('ngEscape', function() {
-    return function(scope, element, attrs) {
-        element.bind('keydown keyup', function(event) {
-            if (event.which === 27) {
-                scope.$apply(function() {
-                    scope.$eval(attrs.ngEscape);
-                });
-
-                event.preventDefault();
-            }
-        });
-    };
-});
-
-// Factory function to focus element.
-controlCenterModule.factory('focus', function ($timeout, $window) {
-    return function (id) {
-        // Timeout makes sure that is invoked after any other event has been triggered.
-        // E.g. click events that need to run before the focus or inputs elements that are
-        // in a disabled state but are enabled when those events are triggered.
-        $timeout(function () {
-            var element = $window.document.getElementById(id);
-
-            if (element)
-                element.focus();
-        });
-    };
-});
-
-// Directive to mark elements to focus.
-controlCenterModule.directive('eventFocus', function (focus) {
-    return function (scope, elem, attr) {
-        elem.on(attr.eventFocus, function () {
-            focus(attr.eventFocusId);
-        });
-
-        // Removes bound events in the element itself when the scope is destroyed
-        scope.$on('$destroy', function () {
-            element.off(attr.eventFocus);
-        });
-    };
-});
-
-// Navigation bar controller.
-controlCenterModule.controller('activeLink', [
-    '$scope', function ($scope) {
-        $scope.isActive = function (path) {
-            return window.location.pathname.substr(0, path.length) == path;
-        };
-    }]);
-
-// Login popup controller.
-controlCenterModule.controller('auth', [
-    '$scope', '$modal', '$alert', '$http', '$window', '$common',
-    function ($scope, $modal, $alert, $http, $window, $common) {
-        $scope.errorMessage = $common.errorMessage;
-
-        $scope.action = 'login';
-
-        $scope.valid = false;
-
-        $scope.userDropdown = [{"text": "Profile", "href": "/profile"}];
-
-        if (!$scope.becomeUsed) {
-            if ($scope.user && $scope.user.admin)
-                $scope.userDropdown.push({"text": "Admin Panel", "href": "/admin"});
-
-            $scope.userDropdown.push({"text": "Log Out", "href": "/logout"});
-        }
-
-        // Pre-fetch an external template populated with a custom scope
-        var authModal = $modal({scope: $scope, templateUrl: '/login', show: false});
-
-        $scope.login = function () {
-            // Show when some event occurs (use $promise property to ensure the template has been loaded)
-            authModal.$promise.then(authModal.show);
-        };
-
-        $scope.auth = function (action, user_info) {
-            $http.post('/' + action, user_info)
-                .success(function () {
-                    authModal.hide();
-
-                    $window.location = '/configuration/clusters';
-                })
-                .error(function (data) {
-                    $alert({placement: 'top', container: '#errors-container', title: $scope.errorMessage(data)});
-                });
-        };
-    }]);
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/web-control-center/src/main/js/controllers/metadata-controller.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/controllers/metadata-controller.js b/modules/web-control-center/src/main/js/controllers/metadata-controller.js
deleted file mode 100644
index c8fad8d..0000000
--- a/modules/web-control-center/src/main/js/controllers/metadata-controller.js
+++ /dev/null
@@ -1,709 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-controlCenterModule.controller('metadataController', ['$scope', '$http', '$common', '$confirm', '$copy', '$table', function ($scope, $http, $common, $confirm, $copy, $table) {
-        $scope.joinTip = $common.joinTip;
-        $scope.getModel = $common.getModel;
-        $scope.javaBuildInTypes = $common.javaBuildInTypes;
-
-        $scope.tableReset = $table.tableReset;
-        $scope.tableNewItem = $table.tableNewItem;
-        $scope.tableNewItemActive = $table.tableNewItemActive;
-        $scope.tableEditing = $table.tableEditing;
-        $scope.tableStartEdit = $table.tableStartEdit;
-        $scope.tableRemove = $table.tableRemove;
-
-        $scope.tableSimpleSave = $table.tableSimpleSave;
-        $scope.tableSimpleSaveVisible = $table.tableSimpleSaveVisible;
-        $scope.tableSimpleUp = $table.tableSimpleUp;
-        $scope.tableSimpleDown = $table.tableSimpleDown;
-        $scope.tableSimpleDownVisible = $table.tableSimpleDownVisible;
-
-        $scope.tablePairSave = $table.tablePairSave;
-        $scope.tablePairSaveVisible = $table.tablePairSaveVisible;
-
-        $scope.templates = [
-            {value: {kind: 'query'}, label: 'query'},
-            {value: {kind: 'store'}, label: 'store'},
-            {value: {kind: 'both'}, label: 'both'}
-        ];
-
-        $scope.template = $scope.templates[0].value;
-
-        $scope.kinds = [
-            {value: 'query', label: 'query'},
-            {value: 'store', label: 'store'},
-            {value: 'both', label: 'both'}
-        ];
-
-        $scope.databases = [
-            {value: 'oracle', label: 'Oracle database'},
-            {value: 'db2', label: 'IBM DB2'},
-            {value: 'mssql', label: 'MS SQL Server'},
-            {value: 'postgre', label: 'PostgreSQL'},
-            {value: 'mysql', label: 'MySQL'},
-            {value: 'h2', label: 'H2 database'}
-        ];
-
-        $scope.jdbcTypes = [
-            {value: 'BIT', label: 'BIT'},
-            {value: 'BOOLEAN', label: 'BOOLEAN'},
-            {value: 'TINYINT', label: 'TINYINT'},
-            {value: 'SMALLINT', label: 'SMALLINT'},
-            {value: 'INTEGER', label: 'INTEGER'},
-            {value: 'BIGINT', label: 'BIGINT'},
-            {value: 'REAL', label: 'REAL'},
-            {value: 'FLOAT', label: 'FLOAT'},
-            {value: 'DOUBLE', label: 'DOUBLE'},
-            {value: 'NUMERIC', label: 'NUMERIC'},
-            {value: 'DECIMAL', label: 'DECIMAL'},
-            {value: 'CHAR', label: 'CHAR'},
-            {value: 'VARCHAR', label: 'VARCHAR'},
-            {value: 'LONGVARCHAR', label: 'LONGVARCHAR'},
-            {value: 'NCHAR', label: 'NCHAR'},
-            {value: 'NVARCHAR', label: 'NVARCHAR'},
-            {value: 'LONGNVARCHAR', label: 'LONGNVARCHAR'},
-            {value: 'DATE', label: 'DATE'},
-            {value: 'TIME', label: 'TIME'},
-            {value: 'TIMESTAMP', label: 'TIMESTAMP'}
-        ];
-
-        $scope.javaTypes = [
-            {value: 'boolean', label: 'boolean'},
-            {value: 'Boolean', label: 'Boolean'},
-            {value: 'byte', label: 'byte'},
-            {value: 'Byte', label: 'Byte'},
-            {value: 'short', label: 'short'},
-            {value: 'Short', label: 'Short'},
-            {value: 'int', label: 'int'},
-            {value: 'Integer', label: 'Integer'},
-            {value: 'long', label: 'long'},
-            {value: 'Long', label: 'Long'},
-            {value: 'float', label: 'float'},
-            {value: 'Float', label: 'Float'},
-            {value: 'double', label: 'double'},
-            {value: 'Double', label: 'Double'},
-            {value: 'BigDecimal', label: 'BigDecimal'},
-            {value: 'String', label: 'String'},
-            {value: 'Date', label: 'Date'},
-            {value: 'Time', label: 'Time'},
-            {value: 'Timestamp', label: 'Timestamp'}
-        ];
-
-        $scope.sortDirections = [
-            {value: false, label: 'ASC'},
-            {value: true, label: 'DESC'}
-        ];
-
-        $scope.data = {
-            curTableIdx: 0,
-            curFieldIdx: 0,
-            curKeyClass: '',
-            curValueClass: '',
-            curJavaName: '',
-            curJavaType: '',
-            tables: [
-                {schemaName: 'Schema1', use: true},
-                {
-                    schemaName: 'Schema1',
-                    use: true,
-                    tableName: 'Table1',
-                    keyClass: 'KeyClass1',
-                    valueClass: 'ValueClass1',
-                    fields: [
-                        {
-                            use: true,
-                            key: true,
-                            ak: true,
-                            databaseName: 'name1',
-                            databaseType: 'dbType1',
-                            javaName: 'javaName1',
-                            javaType: 'javaType1'
-                        },
-                        {
-                            use: true,
-                            key: false,
-                            ak: false,
-                            databaseName: 'name2',
-                            databaseType: 'dbType2',
-                            javaName: 'javaName2',
-                            javaType: 'javaType2'
-                        },
-                        {
-                            use: false,
-                            key: false,
-                            ak: false,
-                            databaseName: 'name3',
-                            databaseType: 'dbType3',
-                            javaName: 'javaName3',
-                            javaType: 'javaType3'
-                        }
-                    ]
-                },
-                {schemaName: 'Schema2 with very long name', use: false},
-                {
-                    schemaName: 'Schema2',
-                    use: false,
-                    tableName: 'Table2',
-                    keyClass: 'KeyClass2',
-                    valueClass: 'ValueClass2',
-                    fields: [
-                        {
-                            use: true,
-                            key: true,
-                            ak: true,
-                            databaseName: 'name4',
-                            databaseType: 'dbType4',
-                            javaName: 'javaName4',
-                            javaType: 'javaType4'
-                        },
-                        {
-                            use: true,
-                            key: false,
-                            ak: false,
-                            databaseName: 'name5',
-                            databaseType: 'dbType5',
-                            javaName: 'javaName5',
-                            javaType: 'javaType5'
-                        },
-                        {
-                            use: false,
-                            key: false,
-                            ak: false,
-                            databaseName: 'name6',
-                            databaseType: 'dbType6',
-                            javaName: 'javaName6',
-                            javaType: 'javaType6'
-                        }
-                    ]
-                },
-                {
-                    schemaName: 'Schema2',
-                    use: false,
-                    tableName: 'Table3',
-                    keyClass: 'KeyClass3',
-                    valueClass: 'ValueClass3',
-                    fields: [
-                        {
-                            use: true,
-                            key: true,
-                            ak: true,
-                            databaseName: 'name7',
-                            databaseType: 'dbType7',
-                            javaName: 'javaName7',
-                            javaType: 'javaType7'
-                        },
-                        {
-                            use: true,
-                            key: false,
-                            ak: false,
-                            databaseName: 'name8',
-                            databaseType: 'dbType8',
-                            javaName: 'javaName8',
-                            javaType: 'javaType8'
-                        },
-                        {
-                            use: false,
-                            key: false,
-                            ak: false,
-                            databaseName: 'name9',
-                            databaseType: 'dbType9',
-                            javaName: 'javaName9',
-                            javaType: 'javaType9'
-                        },
-                        {
-                            use: false,
-                            key: false,
-                            ak: false,
-                            databaseName: 'name10',
-                            databaseType: 'dbType10',
-                            javaName: 'javaName10',
-                            javaType: 'javaType10'
-                        },
-                        {
-                            use: false,
-                            key: false,
-                            ak: false,
-                            databaseName: 'name11',
-                            databaseType: 'dbType11',
-                            javaName: 'javaName11',
-                            javaType: 'javaType11'
-                        },
-                        {
-                            use: false,
-                            key: false,
-                            ak: false,
-                            databaseName: 'name12',
-                            databaseType: 'dbType12',
-                            javaName: 'javaName12',
-                            javaType: 'javaType12'
-                        }
-                    ]
-                }]
-        };
-
-        $scope.metadatas = [];
-
-        $http.get('/models/metadata.json')
-            .success(function (data) {
-                $scope.screenTip = data.screenTip;
-                $scope.templateTip = data.templateTip;
-                $scope.metadataManual = data.metadataManual;
-                $scope.metadataDb = data.metadataDb;
-            })
-            .error(function (errMsg) {
-                $common.showError(errMsg);
-            });
-
-        function selectFirstItem() {
-            if ($scope.metadatas.length > 0)
-                $scope.selectItem($scope.metadatas[0]);
-        }
-
-        function setSelectedAndBackupItem(sel, bak) {
-            $table.tableReset();
-
-            $scope.selectedItem = sel;
-            $scope.backupItem = bak;
-
-            $scope.panels.activePanel = [0];
-        }
-
-        // When landing on the page, get metadatas and show them.
-        $http.post('metadata/list')
-            .success(function (data) {
-                $scope.spaces = data.spaces;
-                $scope.metadatas = data.metadatas;
-
-                var restoredItem = angular.fromJson(sessionStorage.metadataBackupItem);
-
-                if (restoredItem) {
-                    if (restoredItem._id) {
-                        var idx = _.findIndex($scope.metadatas, function (metadata) {
-                            return metadata._id == restoredItem._id;
-                        });
-
-                        if (idx >= 0)
-                            setSelectedAndBackupItem($scope.metadatas[idx], restoredItem);
-                        else {
-                            sessionStorage.removeItem('metadataBackupItem');
-
-                            selectFirstItem();
-                        }
-                    }
-                    else
-                        setSelectedAndBackupItem(undefined, restoredItem);
-                }
-                else
-                    selectFirstItem();
-
-                $scope.$watch('backupItem', function (val) {
-                    if (val)
-                        sessionStorage.metadataBackupItem = angular.toJson(val);
-                }, true);
-            })
-            .error(function (errMsg) {
-                $common.showError(errMsg);
-            });
-
-        $scope.selectItem = function (item) {
-            setSelectedAndBackupItem(item, angular.copy(item));
-        };
-
-        // Add new metadata.
-        $scope.createItem = function () {
-            $table.tableReset();
-
-            $scope.backupItem = angular.copy($scope.template);
-            $scope.backupItem.space = $scope.spaces[0]._id;
-        };
-
-        // Check metadata logical consistency.
-        function validate(item) {
-            return true;
-        }
-
-        // Save cache type metadata into database.
-        function save(item) {
-            $http.post('metadata/save', item)
-                .success(function (_id) {
-                    $common.showInfo('Metadata "' + item.name + '" saved.');
-
-                    var idx = _.findIndex($scope.metadatas, function (metadata) {
-                        return metadata._id == _id;
-                    });
-
-                    if (idx >= 0)
-                        angular.extend($scope.metadatas[idx], item);
-                    else {
-                        item._id = _id;
-
-                        $scope.metadatas.push(item);
-                    }
-
-                    $scope.selectItem(item);
-
-                    $common.showInfo('Cache type metadata"' + item.name + '" saved.');
-                })
-                .error(function (errMsg) {
-                    $common.showError(errMsg);
-                });
-        }
-
-        // Save cache type metadata.
-        $scope.saveItem = function () {
-            $table.tableReset();
-
-            var item = $scope.backupItem;
-
-            if (validate(item))
-                save(item);
-        };
-
-        // Save cache type metadata with new name.
-        $scope.saveItemAs = function () {
-            $table.tableReset();
-
-            if (validate($scope.backupItem))
-                $copy.show($scope.backupItem.name).then(function (newName) {
-                    var item = angular.copy($scope.backupItem);
-
-                    item._id = undefined;
-                    item.name = newName;
-
-                    save(item);
-                });
-        };
-
-        $scope.removeItem = function () {
-            $table.tableReset();
-
-            var selectedItem = $scope.selectedItem;
-
-            $confirm.show('Are you sure you want to remove cache type metadata: "' + selectedItem.name + '"?').then(
-                function () {
-                    var _id = selectedItem._id;
-
-                    $http.post('metadata/remove', {_id: _id})
-                        .success(function () {
-                            $common.showInfo('Cache type metadata has been removed: ' + selectedItem.name);
-
-                            var metadatas = $scope.metadatas;
-
-                            var idx = _.findIndex(metadatas, function (metadata) {
-                                return metadata._id == _id;
-                            });
-
-                            if (idx >= 0) {
-                                metadatas.splice(idx, 1);
-
-                                if (metadatas.length > 0)
-                                    $scope.selectItem(metadatas[0]);
-                                else {
-                                    $scope.selectedItem = undefined;
-                                    $scope.backupItem = undefined;
-                                }
-                            }
-                        })
-                        .error(function (errMsg) {
-                            $common.showError(errMsg);
-                        });
-                });
-        };
-
-        $scope.tableSimpleValid = function (item, field, name, index) {
-            var model = item[field.model];
-
-            if ($common.isDefined(model)) {
-                var idx = _.indexOf(model, name);
-
-                // Found itself.
-                if (index >= 0 && index == idx)
-                    return true;
-
-                // Found duplicate.
-                if (idx >= 0) {
-                    $common.showError('Field with such name already exists!');
-
-                    return false;
-                }
-            }
-
-            return true;
-        };
-
-        $scope.tablePairValid = function (item, field, name, clsName, index) {
-            var model = item[field.model];
-
-            if ($common.isDefined(model)) {
-                var idx = _.findIndex(model, function (pair) {
-                    return pair.name == name
-                });
-
-                // Found itself.
-                if (index >= 0 && index == idx)
-                    return true;
-
-                // Found duplicate.
-                if (idx >= 0) {
-                    $common.showError('Field with such name already exists!');
-
-                    return false;
-                }
-            }
-
-            return true;
-        };
-
-        $scope.tableDbFieldSaveVisible = function (databaseName, databaseType, javaName, javaType) {
-            return $common.isNonEmpty(databaseName) && $common.isDefined(databaseType) &&
-                $common.isNonEmpty(javaName) && $common.isDefined(javaType);
-        };
-
-        $scope.tableDbFieldSave = function (field, newDatabaseName, newDatabaseType, newJavaName, newJavaType, index) {
-            var item = $scope.backupItem;
-
-            var model = item[field.model];
-
-            var newItem = {databaseName: newDatabaseName, databaseType: newDatabaseType, javaName: newJavaName, javaType: newJavaType};
-
-            if ($common.isDefined(model)) {
-                var idx = _.findIndex(model, function (dbMeta) {
-                    return dbMeta.databaseName == newDatabaseName
-                });
-
-                // Found duplicate.
-                if (idx >= 0 && index != idx) {
-                    $common.showError('DB field with such name already exists!');
-
-                    return;
-                }
-
-                if (index < 0) {
-                    if (model)
-                        model.push(newItem);
-                    else
-                        item[field.model] = [newItem];
-                }
-                else {
-                    var dbField = model[index];
-
-                    dbField.databaseName = newDatabaseName;
-                    dbField.databaseType = newDatabaseType;
-                    dbField.javaName = newJavaName;
-                    dbField.javaType = newJavaType;
-                }
-            }
-            else
-                item[field.model] = [newItem];
-
-            $table.tableReset();
-        };
-
-        $scope.tableGroupSaveVisible = function (group) {
-            return $common.isNonEmpty(group);
-        };
-
-        function tableGroupValid(groupName, index) {
-            var groups = $scope.backupItem.groups;
-
-            if ($common.isDefined(groups)) {
-                var idx = _.findIndex(groups, function (group) {
-                    return group.name == groupName;
-                });
-
-                // Found itself.
-                if (index >= 0 && index == idx)
-                    return true;
-
-                // Found duplicate.
-                if (idx >= 0) {
-                    $common.showError('Group with such name already exists!');
-
-                    return false;
-                }
-            }
-
-            return true;
-        }
-
-        $scope.tableGroupSave = function (groupName, index) {
-            if (tableGroupValid(groupName, index)) {
-                $table.tableReset();
-
-                var item = $scope.backupItem;
-
-                if (index < 0) {
-                    var newGroup = {name: groupName};
-
-                    if (item.groups)
-                        item.groups.push(newGroup);
-                    else
-                        item.groups = [newGroup];
-                }
-                else
-                    item.groups[index].name = groupName;
-            }
-        };
-
-        $scope.tableGroupNewItem = function (groupIndex) {
-            var groupName = $scope.backupItem.groups[groupIndex].name;
-
-            return $table.tableNewItem({model: groupName});
-        };
-
-        $scope.tableGroupNewItemActive = function (groupIndex) {
-            var groups = $scope.backupItem.groups;
-
-            if (groups) {
-                var group = groups[groupIndex];
-
-                if (group) {
-                    var groupName = group.name;
-
-                    return $table.tableNewItemActive({model: groupName});
-                }
-            }
-
-            return false;
-        };
-
-        $scope.tableGroupItemEditing = function (groupIndex, index) {
-            var groups = $scope.backupItem.groups;
-
-            if (groups) {
-                var group = groups[groupIndex];
-
-                if (group)
-                    return $table.tableEditing({model: group.name}, index);
-            }
-
-            return false;
-        };
-
-        $scope.tableGroupItemStartEdit = function (groupIndex, index) {
-            var groups = $scope.backupItem.groups;
-
-            $table.tableState(groups[groupIndex].name, index);
-
-            return groups[groupIndex].fields[index];
-        };
-
-        $scope.tableGroupItemSaveVisible = function (fieldName, className) {
-            return $common.isNonEmpty(fieldName) && $common.isNonEmpty(className);
-        };
-
-        function tableGroupItemValid(fieldName, groupIndex, index) {
-            var groupItems = $scope.backupItem.groups[groupIndex].fields;
-
-            if ($common.isDefined(groupItems)) {
-                var idx = _.findIndex(groupItems, function (groupItem) {
-                    return groupItem.name == fieldName;
-                });
-
-                // Found itself.
-                if (index >= 0 && index == idx)
-                    return true;
-
-                // Found duplicate.
-                if (idx >= 0) {
-                    $common.showError('Field with such name already exists in group!');
-
-                    return false;
-                }
-            }
-
-            return true;
-        }
-
-        $scope.tableGroupItemSave = function (fieldName, className, direction, groupIndex, index) {
-            if (tableGroupItemValid(fieldName, groupIndex, index)) {
-                $table.tableReset();
-
-                var group = $scope.backupItem.groups[groupIndex];
-
-                if (index < 0) {
-                    var newGroupItem = {name: fieldName, className: className, direction: direction};
-
-                    if (group.fields)
-                        group.fields.push(newGroupItem);
-                    else
-                        group.fields = [newGroupItem];
-                }
-                else {
-                    var groupItem = group.fields[index];
-
-                    groupItem.name = fieldName;
-                    groupItem.className = className;
-                    groupItem.direction = direction;
-                }
-            }
-        };
-
-        $scope.tableRemoveGroupItem = function (group, index) {
-            $table.tableReset();
-
-            group.fields.splice(index, 1);
-        };
-
-        $scope.selectSchema = function (idx) {
-            var data = $scope.data;
-            var tables = data.tables;
-            var schemaName = tables[idx].schemaName;
-            var use = tables[idx].use;
-
-            for (var i = idx + 1; i < tables.length; i++) {
-                var item = tables[i];
-
-                if (item.schemaName == schemaName && item.tableName)
-                    item.use = use;
-                else
-                    break;
-            }
-
-            data.curTableIdx = -1;
-            data.curFieldIdx = -1;
-        };
-
-        $scope.selectTable = function (idx) {
-            var data = $scope.data;
-
-            data.curTableIdx = idx;
-            data.curFieldIdx = -1;
-
-            if (idx >= 0) {
-                var tbl = data.tables[idx];
-
-                data.curKeyClass = tbl.keyClass;
-                data.curValueClass = tbl.valueClass;
-            }
-        };
-
-        $scope.selectField = function (idx) {
-            var data = $scope.data;
-
-            data.curFieldIdx = idx;
-
-            if (idx >= 0) {
-                var fld = data.tables[data.curTableIdx].fields[idx];
-
-                data.curJavaName = fld.javaName;
-                data.curJavaType = fld.javaType;
-            }
-        };
-    }]
-);
\ No newline at end of file


[35/41] incubator-ignite git commit: # ignite-843 Rename

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/control-center-web/src/main/js/controllers/models/clusters.json
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/controllers/models/clusters.json b/modules/control-center-web/src/main/js/controllers/models/clusters.json
new file mode 100644
index 0000000..36d0dd8
--- /dev/null
+++ b/modules/control-center-web/src/main/js/controllers/models/clusters.json
@@ -0,0 +1,909 @@
+{
+  "screenTip": {
+    "workflowTitle": "Use clusters view to:",
+    "workflowContent": [
+      "<ul>",
+      "  <li>Configure clusters.</li>",
+      "  <li>Associate clusters with caches.</li>",
+      "</ul>"
+    ],
+    "whatsNextTitle": "What's next:",
+    "whatsNextContent": [
+      "<ul>",
+      "  <li>Configure cache type metadata.</li>",
+      "  <li>Configure caches.</li>",
+      "  <li>Generate XML and java code on Summary view.</li>",
+      "</ul>"
+    ]
+  },
+  "templateTip": [
+    "Use following template to add a new cluster:",
+    "<ul>",
+    "  <li>multicast - cluster with multicast discovery.</li>",
+    "  <li>local - cluster with static ips discovery and pre-configured list of IP addresses.</li>",
+    "</ul>"
+  ],
+  "general": [
+    {
+      "label": "Name",
+      "type": "text",
+      "model": "name",
+      "required": true,
+      "placeholder": "Input name",
+      "id": "defaultFocusId"
+    },
+    {
+      "label": "Caches",
+      "type": "dropdown-multiple",
+      "model": "caches",
+      "placeholder": "Choose caches",
+      "items": "caches",
+      "tip": [
+        "Select caches to start in cluster or add a new cache."
+      ],
+      "addLink": {
+        "label": "Add cache(s)",
+        "ref": "/configuration/caches"
+      }
+    },
+    {
+      "label": "Discovery",
+      "type": "dropdown-details",
+      "path": "discovery",
+      "model": "kind",
+      "required": true,
+      "placeholder": "Choose discovery",
+      "items": "discoveries",
+      "tip": [
+        "Discovery allows to discover remote nodes in grid."
+      ],
+      "details": {
+        "Vm": {
+          "expanded": true,
+          "fields": [
+            {
+              "type": "table-simple",
+              "path": "discovery.Vm",
+              "model": "addresses",
+              "editIdx": -1,
+              "reordering": true,
+              "ipaddress": true,
+              "placeholder": "IP address:port",
+              "focusNewItemId": "newIpAddress",
+              "focusCurItemId": "curIpAddress",
+              "addTip": "Add new address.",
+              "removeTip": "Remove address.",
+              "tip": [
+                "Addresses may be represented as follows:",
+                "<ul>",
+                "  <li>IP address (e.g. 127.0.0.1, 9.9.9.9, etc);</li>",
+                "  <li>IP address and port (e.g. 127.0.0.1:47500, 9.9.9.9:47501, etc);</li>",
+                "  <li>IP address and port range (e.g. 127.0.0.1:47500..47510, 9.9.9.9:47501..47504, etc);</li>",
+                "  <li>Hostname (e.g. host1.com, host2, etc);</li>",
+                "  <li>Hostname and port (e.g. host1.com:47500, host2:47502, etc).</li>",
+                "  <li>Hostname and port range (e.g. host1.com:47500..47510, host2:47502..47508, etc).</li>",
+                "</ul>",
+                "If port is 0 or not provided then default port will be used (depends on discovery SPI configuration).",
+                "If port range is provided (e.g. host:port1..port2) the following should be considered:",
+                "<ul>",
+                "  <li>port1 < port2 should be true;</li>",
+                "  <li>Both port1 and port2 should be greater than 0.</li>",
+                "</ul>"
+              ]
+            }
+          ]
+        },
+        "Multicast": {
+          "expanded": false,
+          "fields": [
+            {
+              "label": "IP address",
+              "type": "text",
+              "path": "discovery.Multicast",
+              "model": "multicastGroup",
+              "placeholder": "228.1.2.4",
+              "tip": [
+                "IP address of multicast group."
+              ]
+            },
+            {
+              "label": "Port number",
+              "type": "number",
+              "path": "discovery.Multicast",
+              "model": "multicastPort",
+              "max": 65535,
+              "placeholder": 47400,
+              "tip": [
+                "Port number which multicast messages are sent to."
+              ]
+            },
+            {
+              "label": "Waits for reply",
+              "type": "number",
+              "path": "discovery.Multicast",
+              "model": "responseWaitTime",
+              "placeholder": 500,
+              "tip": [
+                "Time in milliseconds IP finder waits for reply to multicast address request."
+              ]
+            },
+            {
+              "label": "Attempts count",
+              "type": "number",
+              "path": "discovery.Multicast",
+              "model": "addressRequestAttempts",
+              "placeholder": 2,
+              "tip": [
+                "Number of attempts to send multicast address request.",
+                "IP finder re-sends request only in case if no reply for previous request is received."
+              ]
+            },
+            {
+              "label": "Local address",
+              "type": "text",
+              "path": "discovery.Multicast",
+              "model": "localAddress",
+              "tip": [
+                "Local host address used by this IP finder.",
+                "If provided address is non-loopback then multicast socket is bound to this interface.",
+                "If local address is not set or is any local address then IP finder creates multicast sockets for all found non-loopback addresses."
+              ]
+            }
+          ]
+        },
+        "S3": {
+          "expanded": true,
+          "fields": [
+            {
+              "label": "Bucket name",
+              "type": "text",
+              "required": true,
+              "path": "discovery.S3",
+              "model": "bucketName",
+              "tip": [
+                "Bucket name for IP finder."
+              ]
+            },
+            {
+              "label": "Note, AWS credentials will be generated as stubs.",
+              "type": "label"
+            }
+          ]
+        },
+        "Cloud": {
+          "expanded": true,
+          "fields": [
+            {
+              "label": "Credential",
+              "type": "text",
+              "path": "discovery.Cloud",
+              "model": "credential",
+              "tip": [
+                "Credential that is used during authentication on the cloud.",
+                "Depending on a cloud platform it can be a password or access key."
+              ]
+            },
+            {
+              "label": "Path to credential",
+              "type": "text",
+              "path": "discovery.Cloud",
+              "model": "credentialPath",
+              "tip": [
+                "Path to a credential that is used during authentication on the cloud.",
+                "Access key or private key should be stored in a plain or PEM file without a passphrase."
+              ]
+            },
+            {
+              "label": "Identity",
+              "type": "text",
+              "required": true,
+              "path": "discovery.Cloud",
+              "model": "identity",
+              "tip": [
+                "Identity that is used as a user name during a connection to the cloud.",
+                "Depending on a cloud platform it can be an email address, user name, etc."
+              ]
+            },
+            {
+              "label": "Provider",
+              "type": "text",
+              "required": true,
+              "path": "discovery.Cloud",
+              "model": "provider",
+              "tip": [
+                "Cloud provider to use."
+              ]
+            },
+            {
+              "label": "Regions",
+              "type": "table-simple",
+              "path": "discovery.Cloud",
+              "model": "regions",
+              "editIdx": -1,
+              "focusNewItemId": "newRegion",
+              "focusCurItemId": "curRegion",
+              "addTip": "Add new region.",
+              "removeTip": "Remove region.",
+              "tableTip": [
+                "List of regions where VMs are located.",
+                "If the regions are not set then every region, that a cloud provider has, will be investigated. This could lead to significant performance degradation.",
+                "Note, that some cloud providers, like Google Compute Engine, doesn't have a notion of a region. For such providers a call to this method is redundant."
+              ],
+              "tip": [
+                "Region where VMs are located."
+              ]
+            },
+            {
+              "label": "Zones",
+              "type": "table-simple",
+              "path": "discovery.Cloud",
+              "model": "zones",
+              "editIdx": -1,
+              "focusNewItemId": "newZone",
+              "focusCurItemId": "curZone",
+              "addTip": "Add new zone.",
+              "removeTip": "Remove zone.",
+              "tableTip": [
+                "List of zones where VMs are located.",
+                "If the zones are not set then every zone from regions, set by {@link #setRegions(Collection)}}, will be taken into account.",
+                "Note, that some cloud providers, like Rackspace, doesn't have a notion of a zone. For such providers a call to this method is redundant."
+              ],
+              "tip": [
+                "Zone where VMs are located."
+              ]
+            }
+          ]
+        },
+        "GoogleStorage": {
+          "expanded": true,
+          "fields": [
+            {
+              "label": "Project name",
+              "type": "text",
+              "required": true,
+              "path": "discovery.GoogleStorage",
+              "model": "projectName",
+              "tip": [
+                "Google Cloud Platforms project name.",
+                "Usually this is an auto generated project number (ex. 208709979073) that can be found in 'Overview' section of Google Developer Console."
+              ]
+            },
+            {
+              "label": "Bucket name",
+              "type": "text",
+              "required": true,
+              "path": "discovery.GoogleStorage",
+              "model": "bucketName",
+              "tip": [
+                "Google Cloud Storage bucket name.",
+                "If the bucket doesn't exist Ignite will automatically create it.",
+                "However the name must be unique across whole Google Cloud Storage and Service Account Id must be authorized to perform this operation."
+              ]
+            },
+            {
+              "label": "Private key path",
+              "type": "text",
+              "required": true,
+              "path": "discovery.GoogleStorage",
+              "model": "serviceAccountP12FilePath",
+              "tip": [
+                "Full path to the private key in PKCS12 format of the Service Account."
+              ]
+            },
+            {
+              "label": "Account id",
+              "type": "text",
+              "required": true,
+              "path": "discovery.GoogleStorage",
+              "model": "accountId",
+              "tip": [
+                "Service account ID (typically an e-mail address)."
+              ]
+            }
+          ]
+        },
+        "Jdbc": {
+          "expanded": true,
+          "fields": [
+            {
+              "label": "DB schema should be initialized by Ignite",
+              "type": "check",
+              "path": "discovery.Jdbc",
+              "model": "initSchema",
+              "tip": [
+                "Flag indicating whether DB schema should be initialized by Ignite or was explicitly created by user."
+              ]
+            }
+          ]
+        },
+        "SharedFs": {
+          "expanded": false,
+          "fields": [
+            {
+              "label": "File path",
+              "type": "text",
+              "path": "discovery.SharedFs",
+              "model": "path",
+              "placeholder": "disco/tcp"
+            }
+          ]
+        }
+      }
+    }
+  ],
+  "advanced": [
+    {
+      "label": "Atomics configuration",
+      "tip": [
+        "Configuration for atomic data structures.",
+        "Atomics are distributed across the cluster, essentially enabling performing atomic operations (such as increment-and-get or compare-and-set) with the same globally-visible value."
+      ],
+      "fields": [
+        {
+          "label": "Backups",
+          "type": "number",
+          "path": "atomicConfiguration",
+          "model": "backups",
+          "placeholder": 0,
+          "tip": [
+            "Number of backup nodes."
+          ]
+        },
+        {
+          "label": "Cache mode",
+          "type": "dropdown",
+          "path": "atomicConfiguration",
+          "model": "cacheMode",
+          "placeholder": "PARTITIONED",
+          "items": "cacheModes",
+          "tip": [
+            "Cache modes:",
+            "<ul>",
+            "  <li>Partitioned - in this mode the overall key set will be divided into partitions and all partitions will be split equally between participating nodes.</li>",
+            "  <li>Replicated - in this mode all the keys are distributed to all participating nodes.</li>",
+            "  <li>Local - in this mode caches residing on different grid nodes will not know about each other.</li>",
+            "</ul>"
+          ]
+        },
+        {
+          "label": "Sequence reserve",
+          "type": "number",
+          "path": "atomicConfiguration",
+          "model": "atomicSequenceReserveSize",
+          "placeholder": 1000,
+          "tip": [
+            "Default number of sequence values reserved for IgniteAtomicSequence instances.",
+            "After a certain number has been reserved, consequent increments of sequence will happen locally, without communication with other nodes, until the next reservation has to be made."
+          ]
+        }
+      ]
+    },
+    {
+      "label": "Communication",
+      "tip": [
+        "Cluster communication network properties."
+      ],
+      "fields": [
+        {
+          "label": "Timeout",
+          "type": "number",
+          "model": "networkTimeout",
+          "placeholder": 5000,
+          "tip": [
+            "Maximum timeout in milliseconds for network requests."
+          ]
+        },
+        {
+          "label": "Send retry delay",
+          "type": "number",
+          "model": "networkSendRetryDelay",
+          "placeholder": 1000,
+          "tip": [
+            "Interval in milliseconds between message send retries."
+          ]
+        },
+        {
+          "label": "Send retry count",
+          "type": "number",
+          "model": "networkSendRetryCount",
+          "placeholder": 3,
+          "tip": [
+            "Message send retries count."
+          ]
+        },
+        {
+          "label": "Segment check frequency",
+          "type": "number",
+          "model": "segmentCheckFrequency",
+          "placeholder": 10000,
+          "tip": [
+            "Network segment check frequency in milliseconds.",
+            "If 0, periodic segment check is disabled and segment is checked only on topology changes (if segmentation resolvers are configured)."
+          ]
+        },
+        {
+          "label": "Wait for segment on start",
+          "type": "check",
+          "model": "waitForSegmentOnStart",
+          "tip": [
+            "Wait for segment on start flag.",
+            "<ul>",
+            "  <li>If enabled, node should wait for correct segment on start.</li>",
+            "  <li>If node detects that segment is incorrect on startup and enabled, node waits until segment becomes correct.</li>",
+            "  <li>If segment is incorrect on startup and disabled, exception is thrown.</li>",
+            "</ul>"
+          ]
+        },
+        {
+          "label": "Discovery startup delay",
+          "type": "number",
+          "model": "discoveryStartupDelay",
+          "placeholder": 600000,
+          "tip": [
+            "This value is used to expire messages from waiting list whenever node discovery discrepancies happen."
+          ]
+        }
+      ]
+    },
+    {
+      "label": "Deployment",
+      "tip": [
+        "Task and resources deployment in cluster."
+      ],
+      "fields": [
+        {
+          "label": "Mode",
+          "type": "dropdown",
+          "model": "deploymentMode",
+          "placeholder": "SHARED",
+          "items": "deploymentModes",
+          "tip": [
+            "Task classes and resources sharing mode."
+          ]
+        }
+      ]
+    },
+    {
+      "label": "Events",
+      "tip": [
+        " Grid events are used for notification about what happens within the grid."
+      ],
+      "fields": [
+        {
+          "label": "Include type",
+          "type": "dropdown-multiple",
+          "model": "includeEventTypes",
+          "placeholder": "Choose recorded event types",
+          "items": "events",
+          "tip": [
+            "Array of event types, which will be recorded by GridEventStorageManager#record(Event).",
+            "Note, that either the include event types or the exclude event types can be established."
+          ]
+        }
+      ]
+    },
+    {
+      "label": "Marshaller",
+      "tip": [
+        "Marshaller allows to marshal or unmarshal objects in grid.",
+        "It provides serialization/deserialization mechanism for all instances that are sent across networks or are otherwise serialized."
+      ],
+      "fields": [
+        {
+          "label": "Marshaller",
+          "type": "dropdown-details",
+          "path": "marshaller",
+          "model": "kind",
+          "placeholder": "Choose marshaller",
+          "items": "marshallers",
+          "tip": [
+            "Instance of marshaller to use in grid. If not provided, OptimizedMarshaller will be used on Java HotSpot VM, and JdkMarshaller will be used on other VMs."
+          ],
+          "details": {
+            "OptimizedMarshaller": {
+              "expanded": false,
+              "fields": [
+                {
+                  "label": "Streams pool size",
+                  "type": "number",
+                  "path": "marshaller.OptimizedMarshaller",
+                  "model": "poolSize",
+                  "placeholder": 0,
+                  "tip": [
+                    "Specifies size of cached object streams used by marshaller.",
+                    "Object streams are cached for performance reason to avoid costly recreation for every serialization routine.",
+                    "If 0 (default), pool is not used and each thread has its own cached object stream which it keeps reusing.",
+                    "Since each stream has an internal buffer, creating a stream for each thread can lead to high memory consumption if many large messages are marshalled or unmarshalled concurrently.",
+                    "Consider using pool in this case. This will limit number of streams that can be created and, therefore, decrease memory consumption.",
+                    "NOTE: Using streams pool can decrease performance since streams will be shared between different threads which will lead to more frequent context switching."
+                  ]
+                },
+                {
+                  "label": "Require serializable",
+                  "type": "check",
+                  "path": "marshaller.OptimizedMarshaller",
+                  "model": "requireSerializable",
+                  "tip": [
+                    "Whether marshaller should require Serializable interface or not."
+                  ]
+                }
+              ]
+            }
+          }
+        },
+        {
+          "label": "Marshal local jobs",
+          "type": "check",
+          "model": "marshalLocalJobs",
+          "placeholder": "false",
+          "tip": [
+            "If this flag is enabled, jobs mapped to local node will be marshalled as if it was remote node."
+          ]
+        },
+        {
+          "label": "Keep alive time",
+          "type": "number",
+          "model": "marshallerCacheKeepAliveTime",
+          "placeholder": 10000,
+          "tip": [
+            "Keep alive time of thread pool that is in charge of processing marshaller messages."
+          ]
+        },
+        {
+          "label": "Pool size",
+          "type": "number",
+          "model": "marshallerCacheThreadPoolSize",
+          "placeholder": "max(8, availableProcessors) * 2",
+          "tip": [
+            "Default size of thread pool that is in charge of processing marshaller messages."
+          ]
+        }
+      ]
+    },
+    {
+      "label": "Metrics",
+      "tip": [
+        "Cluster runtime metrics settings."
+      ],
+      "fields": [
+        {
+          "label": "Elapsed time",
+          "type": "number",
+          "model": "metricsExpireTime",
+          "placeholder": "Long.MAX_VALUE",
+          "min": 1,
+          "tip": [
+            "Time in milliseconds after which a certain metric value is considered expired."
+          ]
+        },
+        {
+          "label": "History size",
+          "type": "number",
+          "model": "metricsHistorySize",
+          "placeholder": 10000,
+          "min": 1,
+          "tip": [
+            "Number of metrics kept in history to compute totals and averages."
+          ]
+        },
+        {
+          "label": "Log frequency",
+          "type": "number",
+          "model": "metricsLogFrequency",
+          "placeholder": 60000,
+          "tip": [
+            "Frequency of metrics log print out. To disable set to 0"
+          ]
+        },
+        {
+          "label": "Update frequency",
+          "type": "number",
+          "model": "metricsUpdateFrequency",
+          "placeholder": 60000,
+          "tip": [
+            "Job metrics update frequency in milliseconds.",
+            "<ul>",
+            "  <li>If set to -1 job metrics are never updated.</li>",
+            "  <li>If set to 0 job metrics are updated on each job start and finish.</li>",
+            "  <li>Positive value defines the actual update frequency.</li>",
+            "</ul>"
+          ]
+        }
+      ]
+    },
+    {
+      "label": "Peer Class Loading",
+      "tip": [
+        "Cluster peer class loading settings."
+      ],
+      "fields": [
+        {
+          "label": "Enable peer class loading",
+          "type": "check",
+          "model": "peerClassLoadingEnabled",
+          "tip": [
+            "Enables/disables peer class loading."
+          ]
+        },
+        {
+          "label": "Local class path exclude",
+          "type": "text",
+          "model": "peerClassLoadingLocalClassPathExclude",
+          "placeholder": "[]",
+          "tip": [
+            "List of packages separated by comma from the system classpath that need to be peer-to-peer loaded from task originating node.",
+            "'*' is supported at the end of the package name which means that all sub-packages and their classes are included like in Java package import clause."
+          ]
+        },
+        {
+          "label": "Missed resources cache size",
+          "type": "number",
+          "model": "peerClassLoadingMissedResourcesCacheSize",
+          "placeholder": 100,
+          "tip": [
+            "If size greater than 0, missed resources will be cached and next resource request ignored.",
+            "If size is 0, then request for the resource will be sent to the remote node every time this resource is requested."
+          ]
+        },
+        {
+          "label": "Pool size",
+          "type": "number",
+          "model": "peerClassLoadingThreadPoolSize",
+          "placeholder": "availableProcessors",
+          "tip": [
+            "Thread pool size to use for peer class loading."
+          ]
+        }
+      ]
+    },
+    {
+      "label": "Swap",
+      "tip": [
+        "Settings for overflow data to disk if it cannot fit in memory."
+      ],
+      "fields": [
+        {
+          "label": "Swap space SPI",
+          "type": "dropdown-details",
+          "path": "swapSpaceSpi",
+          "model": "kind",
+          "items": "swapSpaceSpis",
+          "placeholder": "Choose swap SPI",
+          "tip": [
+            "Provides a mechanism in grid for storing data on disk.",
+            "Ignite cache uses swap space to overflow data to disk if it cannot fit in memory."
+          ],
+          "details": {
+            "FileSwapSpaceSpi": {
+              "fields": [
+                {
+                  "label": "Base directory",
+                  "type": "text",
+                  "path": "swapSpaceSpi.FileSwapSpaceSpi",
+                  "model": "baseDirectory",
+                  "placeholder": "swapspace",
+                  "tip": [
+                    "Base directory where to write files."
+                  ]
+                },
+                {
+                  "label": "Read stripe size",
+                  "type": "number",
+                  "path": "swapSpaceSpi.FileSwapSpaceSpi",
+                  "model": "readStripesNumber",
+                  "placeholder": "available CPU cores",
+                  "tip": [
+                    "Read stripe size defines number of file channels to be used concurrently."
+                  ]
+                },
+                {
+                  "label": "Maximum sparsity",
+                  "type": "number",
+                  "path": "swapSpaceSpi.FileSwapSpaceSpi",
+                  "model": "maximumSparsity",
+                  "placeholder": 0.5,
+                  "tip": [
+                    "This property defines maximum acceptable wasted file space to whole file size ratio.",
+                    "When this ratio becomes higher than specified number compacting thread starts working."
+                  ]
+                },
+                {
+                  "label": "Max write queue size",
+                  "type": "number",
+                  "path": "swapSpaceSpi.FileSwapSpaceSpi",
+                  "model": "maxWriteQueueSize",
+                  "placeholder": "1024 * 1024",
+                  "tip": [
+                    "Max write queue size in bytes.",
+                    "If there are more values are waiting for being written to disk then specified size, SPI will block on store operation."
+                  ]
+                },
+                {
+                  "label": "Write buffer size",
+                  "type": "number",
+                  "path": "swapSpaceSpi.FileSwapSpaceSpi",
+                  "model": "writeBufferSize",
+                  "placeholder": "Available CPU cores",
+                  "tip": [
+                    "Write buffer size in bytes.",
+                    "Write to disk occurs only when this buffer is full."
+                  ]
+                }
+              ]
+            }
+          }
+        }
+      ]
+    },
+    {
+      "label": "Time configuration",
+      "tip": [
+        "Time settings for CLOCK write ordering mode."
+      ],
+      "fields": [
+        {
+          "label": "Samples size",
+          "type": "number",
+          "model": "clockSyncSamples",
+          "placeholder": 8,
+          "tip": [
+            "Number of samples used to synchronize clocks between different nodes.",
+            "Clock synchronization is used for cache version assignment in CLOCK order mode."
+          ]
+        },
+        {
+          "label": "Frequency",
+          "type": "number",
+          "model": "clockSyncFrequency",
+          "placeholder": 120000,
+          "tip": [
+            "Frequency at which clock is synchronized between nodes, in milliseconds.",
+            "Clock synchronization is used for cache version assignment in CLOCK order mode."
+          ]
+        },
+        {
+          "label": "Port base",
+          "type": "number",
+          "model": "timeServerPortBase",
+          "max": 65535,
+          "placeholder": 31100,
+          "tip": [
+            "Time server provides clock synchronization between nodes.",
+            "Base UPD port number for grid time server. Time server will be started on one of free ports in range."
+          ]
+        },
+        {
+          "label": "Port range",
+          "type": "number",
+          "model": "timeServerPortRange",
+          "placeholder": 100,
+          "tip": [
+            "Time server port range."
+          ]
+        }
+      ]
+    },
+    {
+      "label": "Thread pools size",
+      "tip": [
+        "Settings for node thread pools."
+      ],
+      "fields": [
+        {
+          "label": "Public",
+          "type": "number",
+          "model": "publicThreadPoolSize",
+          "placeholder": "max(8, availableProcessors) * 2",
+          "tip": [
+            "Thread pool that is in charge of processing ComputeJob, GridJobs and user messages sent to node."
+          ]
+        },
+        {
+          "label": "System",
+          "type": "number",
+          "model": "systemThreadPoolSize",
+          "placeholder": "max(8, availableProcessors) * 2",
+          "tip": [
+            "Thread pool that is in charge of processing internal system messages."
+          ]
+        },
+        {
+          "label": "Management",
+          "type": "number",
+          "model": "managementThreadPoolSize",
+          "placeholder": 4,
+          "tip": [
+            "Thread pool that is in charge of processing internal and Visor ComputeJob, GridJobs."
+          ]
+        },
+        {
+          "label": "IGFS",
+          "type": "number",
+          "model": "igfsThreadPoolSize",
+          "placeholder": "availableProcessors",
+          "tip": [
+            "Thread pool that is in charge of processing outgoing IGFS messages."
+          ]
+        }
+      ]
+    },
+    {
+      "label": "Transactions",
+      "tip": [
+        "Settings for transactions."
+      ],
+      "fields": [
+        {
+          "label": "Concurrency",
+          "type": "dropdown",
+          "path": "transactionConfiguration",
+          "model": "defaultTxConcurrency",
+          "placeholder": "PESSIMISTIC",
+          "items": "transactionConcurrency",
+          "tip": [
+            "Cache transaction concurrency to use when one is not explicitly specified."
+          ]
+        },
+        {
+          "label": "Isolation",
+          "type": "dropdown",
+          "path": "transactionConfiguration",
+          "model": "transactionIsolation",
+          "placeholder": "REPEATABLE_READ",
+          "items": "transactionIsolation",
+          "tip": [
+            "Default transaction isolation."
+          ]
+        },
+        {
+          "label": "Default timeout",
+          "type": "number",
+          "path": "transactionConfiguration",
+          "model": "defaultTxTimeout",
+          "placeholder": 0,
+          "tip": [
+            "Default transaction timeout."
+          ]
+        },
+        {
+          "label": "Pessimistic log cleanup delay",
+          "type": "number",
+          "path": "transactionConfiguration",
+          "model": "pessimisticTxLogLinger",
+          "placeholder": 10000,
+          "tip": [
+            "Delay, in milliseconds, after which pessimistic recovery entries will be cleaned up for failed node."
+          ]
+        },
+        {
+          "label": "Pessimistic log size",
+          "type": "number",
+          "path": "transactionConfiguration",
+          "model": "pessimisticTxLogSize",
+          "placeholder": 0,
+          "tip": [
+            "Size of pessimistic transactions log stored on node in order to recover transaction commit if originating node has left grid before it has sent all messages to transaction nodes."
+          ]
+        },
+        {
+          "label": "Manager lookup",
+          "type": "text",
+          "model": "txManagerLookupClassName",
+          "tip": [
+            "Class name of transaction manager finder for integration for JEE app servers."
+          ]
+        },
+        {
+          "label": "Enable serializable cache transactions",
+          "type": "check",
+          "path": "transactionConfiguration",
+          "model": "txSerializableEnabled",
+          "tip": [
+            "Flag to enable/disable isolation level for cache transactions.",
+            "Serializable level does carry certain overhead and if not used, should be disabled."
+          ]
+        }
+      ]
+    }
+  ]
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/control-center-web/src/main/js/controllers/models/metadata.json
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/controllers/models/metadata.json b/modules/control-center-web/src/main/js/controllers/models/metadata.json
new file mode 100644
index 0000000..a9b60de
--- /dev/null
+++ b/modules/control-center-web/src/main/js/controllers/models/metadata.json
@@ -0,0 +1,252 @@
+{
+  "screenTip": {
+    "workflowTitle": "Use metadata view to:",
+    "workflowContent": [
+      "<ul>",
+      "  <li>Manually configure metadata for queries and persistence.</li>",
+      "Or",
+      "  <li>Automatically configure metadata from database schema.</li>",
+      "</ul>"
+    ],
+    "whatsNextTitle": "What's next:",
+    "whatsNextContent": [
+      "<ul>",
+      "  <li>Associate caches with metadata.</li>",
+      "  <li>Generate XML and java code on Summary view.</li>",
+      "</ul>"
+    ]
+  },
+  "templateTip": [
+    "Use following template for metadata:",
+    "<ul>",
+    "  <li>query - Create cache type metadata to use with queries only.</li>",
+    "  <li>store - Create cache type metadata to use with JDBC POJO store only.</li>",
+    "  <li>both - Create cache type metadata to use with query and store.</li>",
+    "</ul>"
+  ],
+  "metadataManual": [
+    {
+      "label": "Name",
+      "type": "text",
+      "model": "name",
+      "required": true,
+      "placeholder": "Input name",
+      "id": "defaultFocusId"
+    },
+    {
+      "label": "Metadata for",
+      "type": "dropdown",
+      "model": "kind",
+      "items": "kinds",
+      "tip": [
+        "Use following template for metadata:",
+        "<ul>",
+        "  <li>query - Create cache type metadata to use with queries only.</li>",
+        "  <li>store - Create cache type metadata to use with JDBC POJO store only.</li>",
+        "  <li>both - Create cache type metadata to use with query and store.</li>",
+        "</ul>"
+      ]
+    },
+    {
+      "label": "Database schema",
+      "type": "text",
+      "model": "databaseSchema",
+      "hide": "backupItem.kind != 'both' && backupItem.kind == 'query'",
+      "placeholder": "Input DB schema name",
+      "tip": [
+        "Schema name in database."
+      ]
+    },
+    {
+      "label": "Database table",
+      "type": "text",
+      "model": "databaseTable",
+      "hide": "backupItem.kind != 'both' && backupItem.kind == 'query'",
+      "placeholder": "Input DB table name",
+      "tip": [
+        "Table name in database."
+      ]
+    },
+    {
+      "label": "Key type",
+      "type": "withJavaBuildInTypes",
+      "model": "keyType",
+      "required": true,
+      "placeholder": "Full class name for Key",
+      "tip": [
+        "Key class used to store key in cache."
+      ]
+    },
+    {
+      "label": "Value type",
+      "type": "text",
+      "model": "valueType",
+      "required": true,
+      "placeholder": "Full class name for Value",
+      "tip": [
+        "Value class used to store value in cache."
+      ]
+    },
+    {
+      "label": "Key fields",
+      "type": "dbFields",
+      "model": "keyFields",
+      "keyName": "name",
+      "valueName": "className",
+      "hide": "backupItem.kind != 'both' && backupItem.kind == 'query'",
+      "addTip": "Add key field.",
+      "removeTip": "Remove key field.",
+      "tip": [
+        "Collection of key fields descriptions for CacheJdbcPojoStore."
+      ]
+    },
+    {
+      "label": "Value fields",
+      "type": "dbFields",
+      "model": "valueFields",
+      "keyName": "name",
+      "valueName": "className",
+      "hide": "backupItem.kind != 'both' && backupItem.kind == 'query'",
+      "addTip": "Add value field.",
+      "removeTip": "Remove value field.",
+      "tip": [
+        "Collection of value fields descriptions for CacheJdbcPojoStore.."
+      ]
+    },
+    {
+      "label": "Query fields",
+      "type": "queryFields",
+      "model": "queryFields",
+      "keyName": "name",
+      "valueName": "className",
+      "hide": "backupItem.kind != 'both' && backupItem.kind != 'query'",
+      "focusNewItemId": "newQryField",
+      "focusCurItemId": "curQryField",
+      "addTip": "Add field to query.",
+      "removeTip": "Remove field.",
+      "tip": [
+        "Collection of name-to-type mappings to be queried, in addition to indexed fields."
+      ]
+    },
+    {
+      "label": "Ascending fields",
+      "type": "queryFields",
+      "model": "ascendingFields",
+      "keyName": "name",
+      "valueName": "className",
+      "hide": "backupItem.kind != 'both' && backupItem.kind != 'query'",
+      "focusNewItemId": "newAscField",
+      "focusCurItemId": "curAscField",
+      "addTip": "Add field to index in ascending order.",
+      "removeTip": "Remove field.",
+      "tip": [
+        "Collection of name-to-type mappings to index in ascending order."
+      ]
+    },
+    {
+      "label": "Descending fields",
+      "type": "queryFields",
+      "model": "descendingFields",
+      "keyName": "name",
+      "valueName": "className",
+      "hide": "backupItem.kind != 'both' && backupItem.kind != 'query'",
+      "focusNewItemId": "newDescField",
+      "focusCurItemId": "curDescField",
+      "addTip": "Add field to index in descending order.",
+      "removeTip": "Remove field.",
+      "tip": [
+        "Collection of name-to-type mappings to index in descending order."
+      ]
+    },
+    {
+      "label": "Text fields",
+      "type": "table-simple",
+      "model": "textFields",
+      "hide": "backupItem.kind != 'both' && backupItem.kind != 'query'",
+      "placeholder": "Field name",
+      "focusNewItemId": "newTextField",
+      "focusCurItemId": "curTextField",
+      "addTip": "Add field to index as text.",
+      "removeTip": "Remove field.",
+      "tableTip": [
+        "Fields to index as text."
+      ],
+      "tip": [
+        "Field to index as text."
+      ]
+    },
+    {
+      "label": "Groups",
+      "type": "queryGroups",
+      "model": "groups",
+      "hide": "backupItem.kind != 'both' && backupItem.kind != 'query'",
+      "addTip": "Add new group.",
+      "removeTip": "Remove group.",
+      "addItemTip": "Add new field to group.",
+      "removeItemTip": "Remove field from group.",
+      "tip": [
+        "Collection of group indexes."
+      ]
+    }
+  ],
+  "metadataDb": [
+    {
+      "label": "Name",
+      "type": "text",
+      "model": "name"
+    },
+    {
+      "label": "Database type",
+      "type": "dropdown",
+      "model": "rdbms",
+      "placeholder": "Choose database",
+      "items": "databases",
+      "tip": [
+        "Select database type to connect for loading tables metadata."
+      ]
+    },
+    {
+      "label": "Database name",
+      "type": "text",
+      "model": "dbName",
+      "tip": [
+        "Database name to connect for loading tables metadata."
+      ]
+    },
+    {
+      "label": "Host",
+      "type": "text",
+      "model": "host",
+      "placeholder": "IP address or host",
+      "tip": [
+        "IP address or host name where database server deployed."
+      ]
+    },
+    {
+      "label": "Port",
+      "type": "number",
+      "model": "port",
+      "max": 65535,
+      "tip": [
+        "Port number for connecting to database."
+      ]
+    },
+    {
+      "label": "User",
+      "type": "text",
+      "model": "user",
+      "tip": [
+        "User name for connecting to database."
+      ]
+    },
+    {
+      "label": "Password",
+      "type": "password",
+      "model": "password",
+      "tip": [
+        "Password for connecting to database.",
+        "Note, password would not be saved."
+      ]
+    }
+  ]
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/control-center-web/src/main/js/controllers/models/sql.json
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/controllers/models/sql.json b/modules/control-center-web/src/main/js/controllers/models/sql.json
new file mode 100644
index 0000000..bcb03e0
--- /dev/null
+++ b/modules/control-center-web/src/main/js/controllers/models/sql.json
@@ -0,0 +1,5 @@
+{
+  "screenTip": [
+    "Select cache and execute SQL queries."
+  ]
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/control-center-web/src/main/js/controllers/models/summary.json
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/controllers/models/summary.json b/modules/control-center-web/src/main/js/controllers/models/summary.json
new file mode 100644
index 0000000..29edb3d
--- /dev/null
+++ b/modules/control-center-web/src/main/js/controllers/models/summary.json
@@ -0,0 +1,163 @@
+{
+  "screenTip": {
+    "workflowTitle": "Use summary view to:",
+    "workflowContent": [
+      "<ul>",
+      "  <li>See XML and java code for server nodes configurations.</li>",
+      "  <li>See XML and java code for client nodes configurations.</li>",
+      "</ul>"
+    ],
+    "whatsNextTitle": "What's next:",
+    "whatsNextContent": [
+      "<ul>",
+      "  <li>Download XML or java code configuration.</li>",
+      "  <li>Start Ignite cluster with downloaded configuration.</li>",
+      "</ul>"
+    ]
+  },
+  "clientFields": [
+    {
+      "label": "Near cache start size",
+      "type": "number",
+      "path": "nearConfiguration",
+      "model": "nearStartSize",
+      "placeholder": 375000,
+      "tip": [
+        "Initial cache size for near cache which will be used to pre-create internal hash table after start."
+      ]
+    },
+    {
+      "label": "Near cache eviction policy",
+      "type": "dropdown-details",
+      "path": "nearConfiguration.nearEvictionPolicy",
+      "model": "kind",
+      "placeholder": "Choose eviction policy",
+      "items": "evictionPolicies",
+      "tip": [
+        "Cache expiration policy."
+      ],
+      "details": {
+        "LRU": {
+          "expanded": false,
+          "fields": [
+            {
+              "label": "Batch size",
+              "type": "number",
+              "path": "nearConfiguration.nearEvictionPolicy.LRU",
+              "model": "batchSize",
+              "placeholder": 1,
+              "tip": [
+                "Number of entries to remove on shrink."
+              ]
+            },
+            {
+              "label": "Max memory size",
+              "type": "number",
+              "path": "nearConfiguration.nearEvictionPolicy.LRU",
+              "model": "maxMemorySize",
+              "placeholder": 0,
+              "tip": [
+                "Maximum allowed cache size in bytes."
+              ]
+            },
+            {
+              "label": "Max size",
+              "type": "number",
+              "path": "nearConfiguration.nearEvictionPolicy.LRU",
+              "model": "maxSize",
+              "placeholder": 100000,
+              "tip": [
+                "Maximum allowed size of cache before entry will start getting evicted."
+              ]
+            }
+          ]
+        },
+        "RND": {
+          "expanded": false,
+          "fields": [
+            {
+              "label": "Max size",
+              "type": "number",
+              "path": "nearConfiguration.nearEvictionPolicy.RND",
+              "model": "maxSize",
+              "placeholder": 100000,
+              "tip": [
+                "Maximum allowed size of cache before entry will start getting evicted."
+              ]
+            }
+          ]
+        },
+        "FIFO": {
+          "expanded": false,
+          "fields": [
+            {
+              "label": "Batch size",
+              "type": "number",
+              "path": "nearConfiguration.nearEvictionPolicy.FIFO",
+              "model": "batchSize",
+              "placeholder": 1,
+              "tip": [
+                "Number of entries to remove on shrink."
+              ]
+            },
+            {
+              "label": "Max memory size",
+              "type": "number",
+              "path": "nearConfiguration.nearEvictionPolicy.FIFO",
+              "model": "maxMemorySize",
+              "placeholder": 0,
+              "tip": [
+                "Maximum allowed cache size in bytes."
+              ]
+            },
+            {
+              "label": "Max size",
+              "type": "number",
+              "path": "nearConfiguration.nearEvictionPolicy.FIFO",
+              "model": "maxSize",
+              "placeholder": 100000,
+              "tip": [
+                "Maximum allowed size of cache before entry will start getting evicted."
+              ]
+            }
+          ]
+        },
+        "SORTED": {
+          "expanded": false,
+          "fields": [
+            {
+              "label": "Batch size",
+              "type": "number",
+              "path": "nearConfiguration.nearEvictionPolicy.SORTED",
+              "model": "batchSize",
+              "placeholder": 1,
+              "tip": [
+                "Number of entries to remove on shrink."
+              ]
+            },
+            {
+              "label": "Max memory size",
+              "type": "number",
+              "path": "nearConfiguration.nearEvictionPolicy.SORTED",
+              "model": "maxMemorySize",
+              "placeholder": 0,
+              "tip": [
+                "Maximum allowed cache size in bytes."
+              ]
+            },
+            {
+              "label": "Max size",
+              "type": "number",
+              "path": "nearConfiguration.nearEvictionPolicy.SORTED",
+              "model": "maxSize",
+              "placeholder": 100000,
+              "tip": [
+                "Maximum allowed size of cache before entry will start getting evicted."
+              ]
+            }
+          ]
+        }
+      }
+    }
+  ]
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/control-center-web/src/main/js/controllers/profile-controller.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/controllers/profile-controller.js b/modules/control-center-web/src/main/js/controllers/profile-controller.js
new file mode 100644
index 0000000..a67df63
--- /dev/null
+++ b/modules/control-center-web/src/main/js/controllers/profile-controller.js
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+controlCenterModule.controller('profileController', ['$scope', '$http', '$common', function ($scope, $http, $common) {
+    $scope.profileUser = angular.copy($scope.user);
+
+    $scope.saveUser = function () {
+        var profile = $scope.profileUser;
+
+        if (profile) {
+            var userName = profile.username;
+            var changeUsername = userName != $scope.user.username;
+
+            var email = profile.email;
+            var changeEmail = email != $scope.user.email;
+
+            if (changeUsername || changeEmail || profile.changePassword) {
+                $http.post('/profile/saveUser', {
+                    _id: profile._id,
+                    userName: changeUsername ? userName : undefined,
+                    email: changeEmail ? email : undefined,
+                    newPassword: profile.changePassword ? profile.newPassword : undefined
+                }).success(function (user) {
+                    $common.showInfo('Profile saved.');
+
+                    if (changeUsername)
+                        $scope.user.username = userName;
+
+                    if (changeEmail)
+                        $scope.user.email = email;
+                }).error(function (err) {
+                    $common.showError('Failed to save profile: ' + $common.errorMessage(err));
+                });
+            }
+        }
+    };
+}]);
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/control-center-web/src/main/js/controllers/sql-controller.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/controllers/sql-controller.js b/modules/control-center-web/src/main/js/controllers/sql-controller.js
new file mode 100644
index 0000000..12772c6
--- /dev/null
+++ b/modules/control-center-web/src/main/js/controllers/sql-controller.js
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var demoResults = [
+    {
+        id: 256,
+        firstName: 'Ivan',
+        lastName: 'Ivanov'
+    },
+    {
+        id: 384,
+        firstName: 'Sergey',
+        lastName: 'Petrov'
+    },
+    {
+        id: 923,
+        firstName: 'Andrey',
+        lastName: 'Sidorov'
+    }
+];
+
+var demoCaches = [{_id: '1', name: 'Users', mode: 'LOCAL'}, {_id: '2', name: 'Organizations', mode: 'REPLICATED'}, {_id: '3', name: 'Cities', mode: 'PARTITIONED'}];
+
+
+
+controlCenterModule.controller('sqlController', ['$scope', '$http', '$common', function ($scope, $http, $common) {
+    $scope.joinTip = $common.joinTip;
+
+    $scope.pageSizes = [50, 100, 200, 400, 800, 1000];
+
+    $scope.tabs = [
+        {
+            query: "SELECT u.id, u.firstName, u.lastName FROM User u WHERE u.name LIKE 'aaaa'",
+            cols: Object.keys(demoResults[0]),
+            page: 1,
+            hasMore: true,
+            total: 0,
+            rows: demoResults
+        },
+        {query: "SELECT * FROM Organization"}
+    ];
+
+    $scope.addTab = function() {
+        console.log('addTab');
+
+        $scope.tabs.push({query: "SELECT "});
+    };
+
+    $scope.removeTab = function(idx) {
+        console.log('removeTab');
+
+        $scope.tabs.splice(idx, 1);
+    };
+
+    $scope.modes = [
+        {value: 'PARTITIONED', label: 'PARTITIONED'},
+        {value: 'REPLICATED', label: 'REPLICATED'},
+        {value: 'LOCAL', label: 'LOCAL'}
+    ];
+
+    $http.get('/models/sql.json')
+        .success(function (data) {
+            $scope.screenTip = data.screenTip;
+        })
+        .error(function (errMsg) {
+            $common.showError(errMsg);
+        });
+
+    $scope.caches = demoCaches;
+}]);

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/control-center-web/src/main/js/controllers/summary-controller.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/controllers/summary-controller.js b/modules/control-center-web/src/main/js/controllers/summary-controller.js
new file mode 100644
index 0000000..531dc83
--- /dev/null
+++ b/modules/control-center-web/src/main/js/controllers/summary-controller.js
@@ -0,0 +1,170 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+controlCenterModule.controller('summaryController', ['$scope', '$http', '$common', function ($scope, $http, $common) {
+    $scope.joinTip = $common.joinTip;
+    $scope.getModel = $common.getModel;
+
+    $scope.javaClassItems = [
+        {label: 'snippet', value: false},
+        {label: 'factory class', value: true}
+    ];
+
+    $scope.evictionPolicies = [
+        {value: 'LRU', label: 'LRU'},
+        {value: 'RND', label: 'Random'},
+        {value: 'FIFO', label: 'FIFO'},
+        {value: 'SORTED', label: 'Sorted'},
+        {value: undefined, label: 'Not set'}
+    ];
+
+    $scope.oss = ['debian:8', 'ubuntu:14.10'];
+
+    $scope.configServer = {javaClassServer: false, os: undefined};
+    $scope.backupItem = {javaClassClient: false};
+
+    $http.get('/models/summary.json')
+        .success(function (data) {
+            $scope.screenTip = data.screenTip;
+            $scope.clientFields = data.clientFields;
+        })
+        .error(function (errMsg) {
+            $common.showError(errMsg);
+        });
+
+    $scope.clusters = [];
+
+    $scope.aceInit = function (editor) {
+        editor.setReadOnly(true);
+        editor.setOption("highlightActiveLine", false);
+
+        var renderer = editor.renderer;
+
+        renderer.setHighlightGutterLine(false);
+        renderer.setShowPrintMargin(false);
+        renderer.setOption('fontSize', '14px');
+
+        editor.setTheme('ace/theme/chrome');
+    };
+
+    $scope.reloadServer = function () {
+        $scope.javaServer = $scope.configServer.javaClassServer ? $scope.configServer.javaClass : $scope.configServer.javaSnippet;
+
+        if ($scope.configServer.docker) {
+            var os = $scope.configServer.os ? $scope.configServer.os : $scope.oss[0];
+
+            $scope.dockerServer = $scope.configServer.docker.replace(new RegExp('\%OS\%', 'g'), os);
+        }
+    };
+
+    $scope.selectItem = function (cluster) {
+        if (!cluster)
+            return;
+
+        $scope.selectedItem = cluster;
+
+        $scope.$watch('javaClassServer', $scope.reloadServer);
+        $scope.$watch('os', $scope.reloadServer);
+
+        $scope.generateServer(cluster);
+
+        $scope.reloadServer();
+
+        $scope.$watch('configServer', function () {
+            $scope.reloadServer();
+        }, true);
+
+        $scope.$watch('backupItem', function () {
+            $scope.generateClient();
+        }, true);
+    };
+
+    $scope.generateServer = function (cluster) {
+        $http.post('summary/generator', {_id: cluster._id})
+            .success(function (data) {
+                $scope.xmlServer = data.xmlServer;
+
+                $scope.configServer.javaClass = data.javaClassServer;
+                $scope.configServer.javaSnippet = data.javaSnippetServer;
+                $scope.configServer.docker = data.docker;
+            }).error(function (errMsg) {
+                $common.showError('Failed to generate config: ' + errMsg);
+            });
+    };
+
+    $scope.generateClient = function () {
+        $http.post('summary/generator', {
+            _id: $scope.selectedItem._id, javaClass: $scope.backupItem.javaClassClient,
+            clientNearConfiguration: $scope.backupItem.nearConfiguration
+        })
+            .success(function (data) {
+                $scope.xmlClient = data.xmlClient;
+                $scope.javaClient = data.javaClient;
+            }).error(function (errMsg) {
+                $common.showError('Failed to generate config: ' + errMsg);
+            });
+    };
+
+    $scope.download = function () {
+        $http.post('summary/download', {_id: $scope.selectedItem._id, javaClass: $scope.javaClass, os: $scope.os})
+            .success(function (data) {
+                var file = document.createElement('a');
+
+                file.setAttribute('href', 'data:application/octet-stream;charset=utf-8,' + data);
+                file.setAttribute('download', $scope.selectedItem.name + '-configuration.zip');
+
+                file.style.display = 'none';
+
+                document.body.appendChild(file);
+
+                file.click();
+
+                document.body.removeChild(file);
+            })
+            .error(function (errMsg) {
+                $common.showError('Failed to generate zip: ' + errMsg);
+            });
+    };
+
+    $http.post('clusters/list').success(function (data) {
+        $scope.clusters = data.clusters;
+
+        if ($scope.clusters.length > 0) {
+            var restoredId = sessionStorage.summarySelectedId;
+
+            var selectIdx = 0;
+
+            if (restoredId) {
+                var idx = _.findIndex($scope.clusters, function (cluster) {
+                    return cluster._id == restoredId;
+                });
+
+                if (idx >= 0)
+                    selectIdx = idx;
+                else
+                    delete sessionStorage.summarySelectedId;
+            }
+
+            $scope.selectItem($scope.clusters[selectIdx]);
+
+            $scope.$watch('selectedItem', function (val) {
+                if (val)
+                    sessionStorage.summarySelectedId = val._id;
+            }, true);
+        }
+    });
+}]);

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/control-center-web/src/main/js/db.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/db.js b/modules/control-center-web/src/main/js/db.js
new file mode 100644
index 0000000..5232e24
--- /dev/null
+++ b/modules/control-center-web/src/main/js/db.js
@@ -0,0 +1,370 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var config = require('./helpers/configuration-loader.js');
+
+// Mongoose for mongodb.
+var mongoose = require('mongoose'),
+    Schema = mongoose.Schema,
+    ObjectId = mongoose.Schema.Types.ObjectId,
+    passportLocalMongoose = require('passport-local-mongoose');
+
+var deepPopulate = require('mongoose-deep-populate');
+
+// Connect to mongoDB database.
+mongoose.connect(config.get('mongoDB:url'), {server: {poolSize: 4}});
+
+// Define account model.
+var AccountSchema = new Schema({
+    username: String,
+    email: String,
+    lastLogin: Date,
+    admin: Boolean
+});
+
+AccountSchema.plugin(passportLocalMongoose, {usernameField: 'email', limitAttempts: true, lastLoginField: 'lastLogin',
+    usernameLowerCase: true});
+
+AccountSchema.set('toJSON', {
+    transform: function(doc, ret) {
+        return {
+            _id: ret._id,
+            email: ret.email,
+            username: ret.username,
+            admin: ret.admin,
+            lastLogin: ret.lastLogin
+        };
+    }
+});
+
+exports.Account = mongoose.model('Account', AccountSchema);
+
+// Define space model.
+exports.Space = mongoose.model('Space', new Schema({
+    name: String,
+    owner: {type: ObjectId, ref: 'Account'},
+    usedBy: [{
+        permission: {type: String, enum: ['VIEW', 'FULL']},
+        account: {type: ObjectId, ref: 'Account'}
+    }]
+}));
+
+// Define cache type metadata model.
+var CacheTypeMetadataSchema = new Schema({
+    space: {type: ObjectId, ref: 'Space'},
+    name: String,
+    kind: {type: String, enum: ['query', 'store', 'both']},
+    databaseSchema: String,
+    databaseTable: String,
+    keyType: String,
+    valueType: String,
+    keyFields: [{databaseName: String, databaseType: String, javaName: String, javaType: String}],
+    valueFields: [{databaseName: String, databaseType: String, javaName: String, javaType: String}],
+    queryFields: [{name: String, className: String}],
+    ascendingFields: [{name: String, className: String}],
+    descendingFields:  [{name: String, className: String}],
+    textFields: [String],
+    groups: [{name: String, fields: [{name: String, className: String, direction: Boolean}]}]
+});
+
+exports.CacheTypeMetadata = mongoose.model('CacheTypeMetadata', CacheTypeMetadataSchema);
+
+// Define cache model.
+var CacheSchema = new Schema({
+    space: {type: ObjectId, ref: 'Space'},
+    name: String,
+    mode: {type: String, enum: ['PARTITIONED', 'REPLICATED', 'LOCAL']},
+    atomicityMode: {type: String, enum: ['ATOMIC', 'TRANSACTIONAL']},
+
+    backups: Number,
+    memoryMode: {type: String, enum: ['ONHEAP_TIERED', 'OFFHEAP_TIERED', 'OFFHEAP_VALUES']},
+    offHeapMaxMemory: Number,
+    startSize: Number,
+    swapEnabled: Boolean,
+
+    evictionPolicy: {
+        kind: {type: String, enum: ['LRU', 'RND', 'FIFO', 'Sorted']},
+        LRU: {
+            batchSize: Number,
+            maxMemorySize: Number,
+            maxSize: Number
+        },
+        RND: {
+            maxSize: Number
+        },
+        FIFO: {
+            batchSize: Number,
+            maxMemorySize: Number,
+            maxSize: Number
+        },
+        SORTED: {
+            batchSize: Number,
+            maxMemorySize: Number,
+            maxSize: Number
+        }
+    },
+
+    rebalanceMode: {type: String, enum: ['SYNC', 'ASYNC', 'NONE']},
+    rebalanceThreadPoolSize: Number,
+    rebalanceBatchSize: Number,
+    rebalanceOrder: Number,
+    rebalanceDelay: Number,
+    rebalanceTimeout: Number,
+    rebalanceThrottle: Number,
+
+    storeMetadata: [{type: ObjectId, ref: 'CacheTypeMetadata'}],
+    cacheStoreFactory: {
+        kind: {
+            type: String,
+            enum: ['CacheJdbcPojoStoreFactory', 'CacheJdbcBlobStoreFactory', 'CacheHibernateBlobStoreFactory']
+        },
+        CacheJdbcPojoStoreFactory: {
+            dataSourceBean: String,
+            dialect: {
+                type: String,
+                enum: ['Oracle', 'DB2', 'SQLServer', 'MySQL', 'PosgreSQL', 'H2']
+            }
+        },
+        CacheJdbcBlobStoreFactory: {
+            user: String,
+            dataSourceBean: String,
+            initSchema: Boolean,
+            createTableQuery: String,
+            loadQuery: String,
+            insertQuery: String,
+            updateQuery: String,
+            deleteQuery: String
+        },
+        CacheHibernateBlobStoreFactory: {
+            hibernateProperties: [String]
+        }
+    },
+    loadPreviousValue: Boolean,
+    readThrough: Boolean,
+    writeThrough: Boolean,
+
+    writeBehindEnabled: Boolean,
+    writeBehindBatchSize: Number,
+    writeBehindFlushSize: Number,
+    writeBehindFlushFrequency: Number,
+    writeBehindFlushThreadCount: Number,
+
+    invalidate: Boolean,
+    defaultLockTimeout: Number,
+    transactionManagerLookupClassName: String,
+
+    sqlEscapeAll: Boolean,
+    sqlOnheapRowCacheSize: Number,
+    longQueryWarningTimeout: Number,
+    queryMetadata: [{type: ObjectId, ref: 'CacheTypeMetadata'}],
+    indexedTypes: [{keyClass: String, valueClass: String}],
+    sqlFunctionClasses: [String],
+    statisticsEnabled: Boolean,
+    managementEnabled: Boolean,
+    readFromBackup: Boolean,
+    copyOnRead: Boolean,
+    maxConcurrentAsyncOperations: Number,
+    nearConfiguration: {
+        nearStartSize: Number,
+        nearEvictionPolicy: {
+            kind: {type: String, enum: ['LRU', 'RND', 'FIFO', 'Sorted']},
+            LRU: {
+                batchSize: Number,
+                maxMemorySize: Number,
+                maxSize: Number
+            },
+            RND: {
+                maxSize: Number
+            },
+            FIFO: {
+                batchSize: Number,
+                maxMemorySize: Number,
+                maxSize: Number
+            },
+            SORTED: {
+                batchSize: Number,
+                maxMemorySize: Number,
+                maxSize: Number
+            }
+        }
+    }
+});
+
+exports.Cache = mongoose.model('Cache', CacheSchema);
+
+// Define cluster schema.
+var ClusterSchema = new Schema({
+    space: {type: ObjectId, ref: 'Space'},
+    name: String,
+    discovery: {
+        kind: {type: String, enum: ['Vm', 'Multicast', 'S3', 'Cloud', 'GoogleStorage', 'Jdbc', 'SharedFs']},
+        Vm: {
+            addresses: [String]
+        },
+        Multicast: {
+            multicastGroup: String,
+            multicastPort: Number,
+            responseWaitTime: Number,
+            addressRequestAttempts: Number,
+            localAddress: String
+        },
+        S3: {
+            bucketName: String
+        },
+        Cloud: {
+            credential: String,
+            credentialPath: String,
+            identity: String,
+            provider: String,
+            regions: [String],
+            zones:  [String]
+        },
+        GoogleStorage: {
+            projectName: String,
+            bucketName: String,
+            serviceAccountP12FilePath: String,
+            addrReqAttempts: String
+        },
+        Jdbc: {
+            initSchema: Boolean
+        },
+        SharedFs: {
+            path: String
+        }
+    },
+    atomicConfiguration: {
+        backups: Number,
+        cacheMode: {type: String, enum: ['LOCAL', 'REPLICATED', 'PARTITIONED']},
+        atomicSequenceReserveSize: Number
+    },
+    caches: [{type: ObjectId, ref: 'Cache'}],
+    cacheSanityCheckEnabled: Boolean,
+    clockSyncSamples: Number,
+    clockSyncFrequency: Number,
+    deploymentMode: {type: String, enum: ['PRIVATE', 'ISOLATED', 'SHARED', 'CONTINUOUS']},
+    discoveryStartupDelay: Number,
+    igfsThreadPoolSize: Number,
+    includeEventTypes: [{
+        type: String, enum: ['EVTS_CHECKPOINT', 'EVTS_DEPLOYMENT', 'EVTS_ERROR', 'EVTS_DISCOVERY',
+            'EVTS_JOB_EXECUTION', 'EVTS_TASK_EXECUTION', 'EVTS_CACHE', 'EVTS_CACHE_REBALANCE', 'EVTS_CACHE_LIFECYCLE',
+            'EVTS_CACHE_QUERY', 'EVTS_SWAPSPACE', 'EVTS_IGFS']
+    }],
+    managementThreadPoolSize: Number,
+    marshaller: {
+        kind: {type: String, enum: ['OptimizedMarshaller', 'JdkMarshaller']},
+        OptimizedMarshaller: {
+            poolSize: Number,
+            requireSerializable: Boolean
+        }
+    },
+    marshalLocalJobs: Boolean,
+    marshallerCacheKeepAliveTime: Number,
+    marshallerCacheThreadPoolSize: Number,
+    metricsExpireTime: Number,
+    metricsHistorySize: Number,
+    metricsLogFrequency: Number,
+    metricsUpdateFrequency: Number,
+    networkTimeout: Number,
+    networkSendRetryDelay: Number,
+    networkSendRetryCount: Number,
+    peerClassLoadingEnabled: Boolean,
+    peerClassLoadingLocalClassPathExclude: [String],
+    peerClassLoadingMissedResourcesCacheSize: Number,
+    peerClassLoadingThreadPoolSize: Number,
+    publicThreadPoolSize: Number,
+    segmentCheckFrequency: Number,
+    segmentationPolicy: {type: String, enum: ['RESTART_JVM', 'STOP', 'NOOP']},
+    allSegmentationResolversPassRequired: Boolean,
+    segmentationResolveAttempts: Number,
+    swapSpaceSpi: {
+        kind: {type: String, enum: ['FileSwapSpaceSpi']},
+        FileSwapSpaceSpi: {
+            baseDirectory: String,
+            readStripesNumber: Number,
+            maximumSparsity: Number,
+            maxWriteQueueSize: Number,
+            writeBufferSize: Number
+        }
+    },
+    systemThreadPoolSize: Number,
+    timeServerPortBase: Number,
+    timeServerPortRange: Number,
+    transactionConfiguration: {
+        defaultTxConcurrency: {type: String, enum: ['OPTIMISTIC', 'PESSIMISTIC']},
+        transactionIsolation: {type: String, enum: ['READ_COMMITTED', 'REPEATABLE_READ', 'SERIALIZABLE']},
+        defaultTxTimeout: Number,
+        pessimisticTxLogLinger: Number,
+        pessimisticTxLogSize: Number,
+        txSerializableEnabled: Boolean
+    },
+    waitForSegmentOnStart: Boolean
+});
+
+ClusterSchema.plugin(deepPopulate, {
+    whitelist: [
+        'caches',
+        'caches.queryMetadata',
+        'caches.storeMetadata'
+    ]
+});
+
+// Define cluster model.
+exports.Cluster = mongoose.model('Cluster', ClusterSchema);
+
+// Define persistence schema.
+var PersistenceSchema = new Schema({
+    space: {type: ObjectId, ref: 'Space'},
+    name: String,
+    rdbms: {type: String, enum: ['oracle', 'db2', 'mssql', 'postgre', 'mysql', 'h2']},
+    dbName: String,
+    host: String,
+    user: String,
+    tables: [{
+        use: Boolean,
+        schemaName: String,
+        tableName: String,
+        keyClass: String,
+        valueClass: String,
+        columns: [{
+            use: Boolean,
+            pk: Boolean,
+            ak: Boolean,
+            notNull: Boolean,
+            databaseName: String,
+            databaseType: Number,
+            javaName: String,
+            javaType: String
+        }]
+    }]
+});
+
+// Define persistence model.
+exports.Persistence = mongoose.model('Persistence', PersistenceSchema);
+
+exports.upsert = function (model, data, cb) {
+    if (data._id) {
+        var id = data._id;
+
+        delete data._id;
+
+        model.findOneAndUpdate({_id: id}, data, cb);
+    }
+    else
+        new model(data).save(cb);
+};
+
+exports.mongoose = mongoose;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/control-center-web/src/main/js/helpers/configuration-loader.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/helpers/configuration-loader.js b/modules/control-center-web/src/main/js/helpers/configuration-loader.js
new file mode 100644
index 0000000..6dbb577
--- /dev/null
+++ b/modules/control-center-web/src/main/js/helpers/configuration-loader.js
@@ -0,0 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var config = require('nconf');
+
+config.file({'file': 'config/default.json'});
+
+module.exports = config;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/control-center-web/src/main/js/helpers/data-structures.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/helpers/data-structures.js b/modules/control-center-web/src/main/js/helpers/data-structures.js
new file mode 100644
index 0000000..2462708
--- /dev/null
+++ b/modules/control-center-web/src/main/js/helpers/data-structures.js
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+eventGroups = {
+    EVTS_CHECKPOINT: ['EVT_CHECKPOINT_SAVED', 'EVT_CHECKPOINT_LOADED', 'EVT_CHECKPOINT_REMOVED'],
+    EVTS_DEPLOYMENT: ['EVT_CLASS_DEPLOYED', 'EVT_CLASS_UNDEPLOYED', 'EVT_CLASS_DEPLOY_FAILED', 'EVT_TASK_DEPLOYED',
+        'EVT_TASK_UNDEPLOYED', 'EVT_TASK_DEPLOY_FAILED'],
+    EVTS_ERROR: ['EVT_JOB_TIMEDOUT', 'EVT_JOB_FAILED', 'EVT_JOB_FAILED_OVER', 'EVT_JOB_REJECTED', 'EVT_JOB_CANCELLED',
+        'EVT_TASK_TIMEDOUT', 'EVT_TASK_FAILED', 'EVT_CLASS_DEPLOY_FAILED', 'EVT_TASK_DEPLOY_FAILED',
+        'EVT_TASK_DEPLOYED', 'EVT_TASK_UNDEPLOYED', 'EVT_CACHE_REBALANCE_STARTED', 'EVT_CACHE_REBALANCE_STOPPED'],
+    EVTS_DISCOVERY: ['EVT_NODE_JOINED', 'EVT_NODE_LEFT', 'EVT_NODE_FAILED', 'EVT_NODE_SEGMENTED',
+        'EVT_CLIENT_NODE_DISCONNECTED', 'EVT_CLIENT_NODE_RECONNECTED'],
+    EVTS_JOB_EXECUTION: ['EVT_JOB_MAPPED', 'EVT_JOB_RESULTED', 'EVT_JOB_FAILED_OVER', 'EVT_JOB_STARTED',
+        'EVT_JOB_FINISHED', 'EVT_JOB_TIMEDOUT', 'EVT_JOB_REJECTED', 'EVT_JOB_FAILED', 'EVT_JOB_QUEUED',
+        'EVT_JOB_CANCELLED'],
+    EVTS_TASK_EXECUTION: ['EVT_TASK_STARTED', 'EVT_TASK_FINISHED', 'EVT_TASK_FAILED', 'EVT_TASK_TIMEDOUT',
+        'EVT_TASK_SESSION_ATTR_SET', 'EVT_TASK_REDUCED'],
+    EVTS_CACHE: ['EVT_CACHE_ENTRY_CREATED', 'EVT_CACHE_ENTRY_DESTROYED', 'EVT_CACHE_OBJECT_PUT',
+        'EVT_CACHE_OBJECT_READ', 'EVT_CACHE_OBJECT_REMOVED', 'EVT_CACHE_OBJECT_LOCKED', 'EVT_CACHE_OBJECT_UNLOCKED',
+        'EVT_CACHE_OBJECT_SWAPPED', 'EVT_CACHE_OBJECT_UNSWAPPED', 'EVT_CACHE_OBJECT_EXPIRED'],
+    EVTS_CACHE_REBALANCE: ['EVT_CACHE_REBALANCE_STARTED', 'EVT_CACHE_REBALANCE_STOPPED',
+        'EVT_CACHE_REBALANCE_PART_LOADED', 'EVT_CACHE_REBALANCE_PART_UNLOADED', 'EVT_CACHE_REBALANCE_OBJECT_LOADED',
+        'EVT_CACHE_REBALANCE_OBJECT_UNLOADED', 'EVT_CACHE_REBALANCE_PART_DATA_LOST'],
+    EVTS_CACHE_LIFECYCLE: ['EVT_CACHE_STARTED', 'EVT_CACHE_STOPPED', 'EVT_CACHE_NODES_LEFT'],
+    EVTS_CACHE_QUERY: ['EVT_CACHE_QUERY_EXECUTED', 'EVT_CACHE_QUERY_OBJECT_READ'],
+    EVTS_SWAPSPACE: ['EVT_SWAP_SPACE_CLEARED', 'EVT_SWAP_SPACE_DATA_REMOVED', 'EVT_SWAP_SPACE_DATA_READ',
+        'EVT_SWAP_SPACE_DATA_STORED', 'EVT_SWAP_SPACE_DATA_EVICTED'],
+    EVTS_IGFS: ['EVT_IGFS_FILE_CREATED', 'EVT_IGFS_FILE_RENAMED', 'EVT_IGFS_FILE_DELETED', 'EVT_IGFS_FILE_OPENED_READ',
+        'EVT_IGFS_FILE_OPENED_WRITE', 'EVT_IGFS_FILE_CLOSED_WRITE', 'EVT_IGFS_FILE_CLOSED_READ', 'EVT_IGFS_FILE_PURGED',
+        'EVT_IGFS_META_UPDATED', 'EVT_IGFS_DIR_CREATED', 'EVT_IGFS_DIR_RENAMED', 'EVT_IGFS_DIR_DELETED']
+};
+
+jdbcTypes = {
+    BIT: {value: "BIT", code: -7, label: "BIT"},
+    TINYINT: {value: "TINYINT", code: -6, label: "TINYINT"},
+    SMALLINT: {value: "SMALLINT", code: 5, label: "SMALLINT"},
+    INTEGER: {value: "INTEGER", code: 4, label: "INTEGER"},
+    BIGINT: {value: "BIGINT", code: -5, label: "BIGINT"},
+    FLOAT: {value: "FLOAT", code: 6, label: "FLOAT"},
+    REAL: {value: "REAL", code: 7, label: "REAL"},
+    DOUBLE: {value: "DOUBLE", code: 8, label: "DOUBLE"},
+    NUMERIC: {value: "NUMERIC", code: 2, label: "NUMERIC"},
+    DECIMAL: {value: "DECIMAL", code: 3, label: "DECIMAL"},
+    CHAR: {value: "CHAR", code: 1, label: "CHAR"},
+    VARCHAR: {value: "VARCHAR", code: 12, label: "VARCHAR"},
+    DATE: {value: "DATE", code: 91, label: "DATE"},
+    TIME: {value: "TIME", code: 92, label: "TIME"},
+    TIMESTAMP: {value: "TIMESTAMP", code: 93, label: "TIMESTAMP"},
+    BINARY: {value: "BINARY", code: -2, label: "BINARY"}
+};
+
+javaTypes = {
+    INTEGER: {value: "java.lang.Integer", label: "Integer"},
+    LONG: {value: "java.lang.Long", label: "Long"},
+    BIGDECIMAL: {value: "java.math.BigDecimal", label: "BigDecimal"},
+    FLOAT: {value: "java.lang.Float", label: "Float"},
+    DOUBLE: {value: "java.lang.Double", label: "Double"},
+    STRING: {value: "java.lang.String", label: "String"},
+    BOOLEAN: {value: "java.lang.Boolean", label: "Boolean"},
+    BYTE_ARRAY: {value: "byte[]", label: "byte[]"},
+    DATE: {value: "java.sql.Date", label: "Date"},
+    TIME: {value: "java.sql.Time", label: "Time"},
+    TIMESTAMP: {value: "java.sql.Timestamp", label: "Timestamp"}
+};
+
+if (typeof window === 'undefined') {
+    exports.eventGroups = eventGroups;
+    exports.jdbcTypes = jdbcTypes;
+    exports.javaTypes = javaTypes;
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/control-center-web/src/main/js/package.json
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/package.json b/modules/control-center-web/src/main/js/package.json
new file mode 100644
index 0000000..fd82196
--- /dev/null
+++ b/modules/control-center-web/src/main/js/package.json
@@ -0,0 +1,49 @@
+{
+  "name": "ignite-web-control-center",
+  "version": "1.0.0",
+  "description": "Web application for configuration, monitoring Ignite Cluster",
+  "private": true,
+  "scripts": {
+    "start": "node ./bin/www"
+  },
+  "author": "",
+  "contributors": [
+    {
+      "name": "",
+      "email": ""
+    }
+  ],
+  "license": "Apache-2.0",
+  "keywords": "grid",
+  "homepage": "https://ignite.incubator.apache.org/",
+  "engines": {
+    "node": ">=0.12.4"
+  },
+  "dependencies": {
+    "angular-ui-ace": "^0.2.3",
+    "archiver": "^0.14.4",
+    "body-parser": "~1.12.0",
+    "connect-flash": "^0.1.1",
+    "connect-mongo": "^0.8.1",
+    "cookie-parser": "~1.3.4",
+    "debug": "~2.1.1",
+    "express": "~4.12.2",
+    "express-session": "^1.11.1",
+    "jade": "~1.9.2",
+    "lodash": "3.10.0",
+    "mongoose": "^4.0.2",
+    "mongoose-deep-populate": "1.1.0",
+    "nconf": "^0.7.1",
+    "node-sass-middleware": "^0.9.0",
+    "passport": "^0.2.1",
+    "passport-local": "^1.0.0",
+    "passport-local-mongoose": "^1.0.0",
+    "serve-favicon": "~2.2.0"
+  },
+  "devDependencies": {
+    "morgan": "~1.5.1",
+    "supertest": "^1.0.1",
+    "mocha": "~2.0.1",
+    "should": "~3.1.3"
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/control-center-web/src/main/js/public/favicon.ico
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/public/favicon.ico b/modules/control-center-web/src/main/js/public/favicon.ico
new file mode 100644
index 0000000..74ec626
Binary files /dev/null and b/modules/control-center-web/src/main/js/public/favicon.ico differ

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/control-center-web/src/main/js/public/images/docker.png
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/public/images/docker.png b/modules/control-center-web/src/main/js/public/images/docker.png
new file mode 100644
index 0000000..7ec3aef
Binary files /dev/null and b/modules/control-center-web/src/main/js/public/images/docker.png differ

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/control-center-web/src/main/js/public/images/java.png
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/public/images/java.png b/modules/control-center-web/src/main/js/public/images/java.png
new file mode 100644
index 0000000..ddb3b8e
Binary files /dev/null and b/modules/control-center-web/src/main/js/public/images/java.png differ

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/control-center-web/src/main/js/public/images/logo.png
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/public/images/logo.png b/modules/control-center-web/src/main/js/public/images/logo.png
new file mode 100644
index 0000000..c3577c5
Binary files /dev/null and b/modules/control-center-web/src/main/js/public/images/logo.png differ

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/control-center-web/src/main/js/public/images/xml.png
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/public/images/xml.png b/modules/control-center-web/src/main/js/public/images/xml.png
new file mode 100644
index 0000000..029065e
Binary files /dev/null and b/modules/control-center-web/src/main/js/public/images/xml.png differ


[10/41] incubator-ignite git commit: #ignite-961: Add sql fields metadata to rest query response.

Posted by an...@apache.org.
#ignite-961:  Add sql fields metadata to rest query response.


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

Branch: refs/heads/ignite-1121
Commit: 201e208e82b0d0c8f8fdb16747d703eedc7f95db
Parents: f22de3e
Author: ivasilinets <iv...@gridgain.com>
Authored: Mon Jul 27 13:58:37 2015 +0300
Committer: ivasilinets <iv...@gridgain.com>
Committed: Mon Jul 27 13:58:37 2015 +0300

----------------------------------------------------------------------
 .../JettyRestProcessorAbstractSelfTest.java     |  41 +++++-
 .../query/CacheQueryFieldsMetaResult.java       | 133 +++++++++++++++++++
 .../rest/handlers/query/CacheQueryResult.java   |  19 +++
 .../handlers/query/QueryCommandHandler.java     |  21 +++
 4 files changed, 212 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/201e208e/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorAbstractSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorAbstractSelfTest.java b/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorAbstractSelfTest.java
index 160046c..8ce070f 100644
--- a/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorAbstractSelfTest.java
+++ b/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorAbstractSelfTest.java
@@ -650,7 +650,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
 
         jsonEquals(ret, cacheBulkPattern(true, true));
 
-        ret = content(F.asMap("cmd", "rmvall"));
+        ret = content(F.asMap("cmd", GridRestCommand.CACHE_REMOVE_ALL.key()));
 
         assertNotNull(ret);
         assertTrue(!ret.isEmpty());
@@ -1001,7 +1001,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
      * @throws Exception If failed.
      */
     public void testVersion() throws Exception {
-        String ret = content(F.asMap("cmd", "version"));
+        String ret = content(F.asMap("cmd", GridRestCommand.VERSION.key()));
 
         assertNotNull(ret);
         assertTrue(!ret.isEmpty());
@@ -1119,6 +1119,43 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
     /**
      * @throws Exception If failed.
      */
+    public void testSqlFieldsMetadataQuery() throws Exception {
+        String qry = "select firstName, lastName from Person";
+
+        Map<String, String> params = new HashMap<>();
+        params.put("cmd", GridRestCommand.EXECUTE_SQL_FIELDS_QUERY.key());
+        params.put("psz", "10");
+        params.put("cacheName", "person");
+        params.put("qry", URLEncoder.encode(qry));
+
+        String ret = content(params);
+
+        assertNotNull(ret);
+        assertTrue(!ret.isEmpty());
+
+        JSONObject json = JSONObject.fromObject(ret);
+
+        List items = (List)((Map)json.get("response")).get("items");
+
+        List meta = (List)((Map)json.get("response")).get("fieldsMetadata");
+
+        assertEquals(4, items.size());
+
+        assertEquals(2, meta.size());
+
+        JSONObject o = (JSONObject)meta.get(0);
+
+        assertEquals("FIRSTNAME", o.get("fieldName"));
+        assertEquals("java.lang.String", o.get("fieldTypeName"));
+        assertEquals("person", o.get("schemaName"));
+        assertEquals("PERSON", o.get("typeName"));
+
+        assertFalse(queryCursorFound());
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
     public void testQueryClose() throws Exception {
         String qry = "salary > ? and salary <= ?";
 

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/201e208e/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/query/CacheQueryFieldsMetaResult.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/query/CacheQueryFieldsMetaResult.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/query/CacheQueryFieldsMetaResult.java
new file mode 100644
index 0000000..8c4ddb0
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/query/CacheQueryFieldsMetaResult.java
@@ -0,0 +1,133 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.rest.handlers.query;
+
+import org.apache.ignite.internal.processors.query.*;
+import org.apache.ignite.internal.util.typedef.internal.*;
+
+import java.io.*;
+
+/**
+ * Cache query fields metadata.
+ */
+public class CacheQueryFieldsMetaResult implements Externalizable {
+    /** */
+    private static final long serialVersionUID = 0L;
+
+    /** Schema name. */
+    private String schemaName;
+
+    /** Type name. */
+    private String typeName;
+
+    /** Name. */
+    private String fieldName;
+
+    /** Type. */
+    private String fieldTypeName;
+
+    /**
+     * Empty constructor for Externalizable.
+     */
+    public CacheQueryFieldsMetaResult() {
+        // No-op.
+    }
+
+    /**
+     * @param meta Metadata
+     */
+    public CacheQueryFieldsMetaResult(GridQueryFieldMetadata meta) {
+        schemaName = meta.schemaName();
+        typeName = meta.typeName();
+        fieldName = meta.fieldName();
+        fieldTypeName = meta.fieldTypeName();
+    }
+
+    /**
+     * @return Schema name.
+     */
+    public String getSchemaName() {
+        return schemaName;
+    }
+
+    /**
+     * @param schemaName Schema name.
+     */
+    public void setSchemaName(String schemaName) {
+        this.schemaName = schemaName;
+    }
+
+    /**
+     * @return Type name.
+     */
+    public String getTypeName() {
+        return typeName;
+    }
+
+    /**
+     * @param typeName Type name.
+     */
+    public void setTypeName(String typeName) {
+        this.typeName = typeName;
+    }
+
+    /**
+     * @return Field name.
+     */
+    public String getFieldName() {
+        return fieldName;
+    }
+
+    /**
+     * @param fieldName Field name.
+     */
+    public void setFieldName(String fieldName) {
+        this.fieldName = fieldName;
+    }
+
+
+    /**
+     * @return Field type name.
+     */
+    public String getFieldTypeName() {
+        return fieldTypeName;
+    }
+
+    /**
+     * @param fieldName Field name.
+     */
+    public void setFieldTypeName(String fieldName) {
+        this.fieldName = fieldName;
+    }
+
+    /** {@inheritDoc} */
+    @Override public void writeExternal(ObjectOutput out) throws IOException {
+        U.writeString(out, schemaName);
+        U.writeString(out, typeName);
+        U.writeString(out, fieldName);
+        U.writeString(out, fieldTypeName);
+    }
+
+    /** {@inheritDoc} */
+    @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+        schemaName = U.readString(in);
+        typeName = U.readString(in);
+        fieldName = U.readString(in);
+        fieldTypeName = U.readString(in);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/201e208e/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/query/CacheQueryResult.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/query/CacheQueryResult.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/query/CacheQueryResult.java
index 3e49576..544a094 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/query/CacheQueryResult.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/query/CacheQueryResult.java
@@ -35,6 +35,9 @@ public class CacheQueryResult implements Externalizable {
     /** Result items. */
     private Collection<?> items;
 
+    /** Fields metadata. */
+    private Collection<?> fieldsMeta;
+
     /** Last flag. */
     private boolean last;
 
@@ -67,6 +70,20 @@ public class CacheQueryResult implements Externalizable {
     }
 
     /**
+     * @param fieldsMeta Fields metadata.
+     */
+    public void setFieldsMetadata(Collection<?> fieldsMeta) {
+        this.fieldsMeta = fieldsMeta;
+    }
+
+    /**
+     * @return Fields metadata.
+     */
+    public Collection<?> getFieldsMetadata() {
+        return fieldsMeta;
+    }
+
+    /**
      * @return Last flag.
      */
     public boolean getLast() {
@@ -90,6 +107,7 @@ public class CacheQueryResult implements Externalizable {
         out.writeBoolean(last);
         out.writeLong(qryId);
         U.writeCollection(out, items);
+        U.writeCollection(out, fieldsMeta);
     }
 
     /** {@inheritDoc} */
@@ -97,5 +115,6 @@ public class CacheQueryResult implements Externalizable {
         last = in.readBoolean();
         qryId = in.readLong();
         items = U.readCollection(in);
+        fieldsMeta = U.readCollection(in);
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/201e208e/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/query/QueryCommandHandler.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/query/QueryCommandHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/query/QueryCommandHandler.java
index defca37..59f95c9 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/query/QueryCommandHandler.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/query/QueryCommandHandler.java
@@ -20,6 +20,8 @@ package org.apache.ignite.internal.processors.rest.handlers.query;
 import org.apache.ignite.*;
 import org.apache.ignite.cache.query.*;
 import org.apache.ignite.internal.*;
+import org.apache.ignite.internal.processors.cache.*;
+import org.apache.ignite.internal.processors.query.*;
 import org.apache.ignite.internal.processors.rest.*;
 import org.apache.ignite.internal.processors.rest.handlers.*;
 import org.apache.ignite.internal.processors.rest.request.*;
@@ -146,6 +148,10 @@ public class QueryCommandHandler extends GridRestCommandHandlerAdapter {
 
                 CacheQueryResult res = createQueryResult(qryCurs, cur, req, qryId);
 
+                List<GridQueryFieldMetadata> fieldsMeta = ((QueryCursorImpl<?>) qryCur).fieldsMeta();
+
+                res.setFieldsMetadata(convertMetadata(fieldsMeta));
+
                 return new GridRestResponse(res);
             }
             catch (Exception e) {
@@ -154,6 +160,21 @@ public class QueryCommandHandler extends GridRestCommandHandlerAdapter {
                 return new GridRestResponse(GridRestResponse.STATUS_FAILED, e.getMessage());
             }
         }
+
+        /**
+         * @param meta Internal query field metadata.
+         * @return Rest query field metadata.
+         */
+        private Collection<CacheQueryFieldsMetaResult> convertMetadata(Collection<GridQueryFieldMetadata> meta) {
+            List<CacheQueryFieldsMetaResult> res = new ArrayList<>();
+
+            if (meta != null) {
+                for (GridQueryFieldMetadata info : meta)
+                    res.add(new CacheQueryFieldsMetaResult(info));
+            }
+
+            return res;
+        }
     }
 
     /**


[34/41] incubator-ignite git commit: # ignite-843 Rename

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/control-center-web/src/main/js/public/stylesheets/style.scss
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/public/stylesheets/style.scss b/modules/control-center-web/src/main/js/public/stylesheets/style.scss
new file mode 100644
index 0000000..e2542ce
--- /dev/null
+++ b/modules/control-center-web/src/main/js/public/stylesheets/style.scss
@@ -0,0 +1,1270 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+$logo-path: "https://www.filepicker.io/api/file/QagunjDGRFul2JgNCAli";
+$input-height: 28px;
+$ignite-red: #ec1c24;
+$ignite-block-callout-background: #f3f8f3;
+$ignite-block-callout: #50af51;
+
+hr {
+    margin: 20px 0;
+}
+
+.main-header .logo {
+    height: auto;
+}
+
+.main-sidebar {
+    padding-top: 60px;
+}
+
+.navbar-default .navbar-brand, .navbar-default .navbar-brand:hover {
+    position: absolute;
+    width: 100%;
+    left: 0;
+    text-align: center;
+}
+
+.modal-backdrop.am-fade {
+    opacity: .5;
+    transition: opacity .15s linear;
+    &.ng-enter {
+        opacity: 0;
+        &.ng-enter-active {
+            opacity: .5;
+        }
+    }
+    &.ng-leave {
+        opacity: .5;
+        &.ng-leave-active {
+            opacity: 0;
+        }
+    }
+}
+
+.modal.center .modal-dialog {
+    position: fixed;
+    top: 50%;
+    left: 50%;
+    -webkit-transform: translateX(-50%) translateY(-50%);
+    transform: translateX(-50%) translateY(-50%);
+}
+
+.border-left {
+    box-shadow: 1px 0 0 0 #eee inset;
+}
+
+.border-right {
+    box-shadow: 1px 0 0 0 #eee;
+}
+
+.theme-line {
+    background-color: #f9f9f9;
+}
+
+.theme-line header {
+    background-color: #fff;
+}
+
+.theme-line header a.btn {
+    border: 0 none;
+    padding: 10px 25px;
+    background-color: rgba(0, 0, 0, 0.15);
+}
+
+.theme-line header a.btn:hover {
+    background-color: rgba(0, 0, 0, 0.25);
+}
+
+.theme-line header a.btn.btn-link {
+    background: transparent;
+    color: rgba(255, 255, 255, 0.8);
+}
+
+.theme-line header a.btn.btn-link:hover {
+    color: #fff;
+    text-decoration: none;
+}
+
+.theme-line .navbar-nav a {
+    background-color: transparent;
+}
+
+.theme-line .navbar-nav a:hover,
+.theme-line .navbar-nav a:active,
+.theme-line .navbar-nav a:focus {
+    background-color: transparent;
+}
+
+.theme-line .main-links {
+    padding-top: 50px;
+}
+
+.theme-line .main-links h3 {
+    margin-top: 0;
+    font-size: 17px;
+}
+
+.theme-line .main-links .links a {
+    color: #888;
+}
+
+.theme-line .main-links .links a:hover {
+    text-decoration: none;
+}
+
+.theme-line #category-columns,
+.theme-solid #category-columns {
+    margin: 50px 30px 0;
+}
+
+.theme-line #category-columns h4 {
+    text-transform: uppercase;
+    font-weight: 300;
+    color: #999;
+    font-size: 14px;
+}
+
+.theme-line #category-columns ul {
+    list-style: none;
+    padding: 0;
+    margin-bottom: 15px;
+}
+
+.theme-line #category-columns ul li a {
+    padding: 5px 0;
+    display: block;
+    font-size: 16px;
+}
+
+.theme-line #category-columns ul .view-all {
+    font-size: 0.85em;
+}
+
+.theme-line .docs-header {
+    color: #999;
+    overflow: hidden;
+}
+
+.theme-line .docs-header h1 {
+    color: #444;
+    margin-top: 0;
+    font-size: 22px;
+}
+
+.theme-line .btn-primary {
+    border: 0 none;
+    background-color: $ignite-red;
+}
+
+.theme-line .btn-primary:hover {
+    background-color: #950d12;
+}
+
+.theme-line .main-content .nav-horizontal a {
+    box-shadow: 0 0;
+    border: 0 none;
+    background-color: #fff;
+    border-radius: 0;
+    color: #aaa;
+    padding: 6px;
+    margin: 0 14px;
+}
+
+.theme-line .main-content .nav-horizontal a:hover {
+    color: #999;
+    border-bottom: 5px solid #ddd;
+}
+
+.theme-line .main-content .nav-horizontal a.active {
+    border-bottom: 5px solid #888;
+}
+
+.theme-line .navbar-nav, .theme-line .sidebar-nav {
+    ul li > a.active {
+        cursor: default;
+        pointer-events: none;
+    }
+}
+
+.theme-line .sidebar-nav {
+    color: #474a54;
+    padding-bottom: 30px;
+
+    ul {
+        padding: 0;
+        list-style: none;
+        font-size: 14px;
+        margin: 3px 0 0;
+        li {
+            color: #666;
+            line-height: $input-height;
+
+            span.fa-stack {
+                margin-right: 5px;
+                font-size: 12px;
+                height: 26px;
+            }
+
+            a {
+                font-size: 18px;
+                color: #666;
+                position: relative;
+                white-space: nowrap;
+                overflow: hidden;
+                -o-text-overflow: ellipsis;
+                text-overflow: ellipsis;
+            }
+        }
+    }
+}
+
+.theme-line .sidebar-nav ul li a:hover {
+    text-decoration: none;
+}
+
+.theme-line .select,
+.theme-line .typeahead {
+    li a {
+        color: #666;
+        background-color: transparent;
+    }
+
+    li a:hover {
+        color: $ignite-red;
+    }
+
+    .active {
+        background-color: #eee;
+    }
+}
+
+.theme-line .sidebar-nav ul li .subcategory {
+    padding-left: 15px;
+}
+
+.theme-line .sidebar-nav h4 {
+    margin-top: 2em;
+    font-weight: normal;
+    text-transform: uppercase;
+    font-size: 11px;
+    margin-bottom: 10px;
+    color: #bbb;
+}
+
+.theme-line .sidebar-nav h4:first-child {
+    margin-top: 0;
+}
+
+.theme-line .sidebar-nav .ask {
+    width: 100%;
+    text-align: center;
+    padding: 10px;
+}
+
+.theme-line .border-left .sidebar-nav {
+    padding-left: 15px;
+}
+
+.theme-line .suggest {
+    padding: 5px;
+    display: inline-block;
+    font-size: 12px;
+}
+
+.header {
+    padding: 15px;
+}
+
+.header .has-github {
+    padding-right: 136px;
+}
+
+.header h1.navbar-brand {
+    height: 40px;
+    width: 200px;
+    padding: 0;
+    margin: 5px 15px 0 0;
+}
+
+.header h1.navbar-brand a {
+    text-indent: -99999px;
+    background: no-repeat center center;
+    display: block;
+    width: 100%;
+    height: 100%;
+    background-size: contain;
+}
+
+.header .nav.navbar-nav.pull-right {
+    position: relative;
+    right: -30px;
+}
+
+.header .nav.navbar-nav .not-link {
+    padding: 15px;
+    display: inline-block;
+}
+
+.header .nav.navbar-nav .stable,
+.header .nav.navbar-nav .beta,
+.header .nav.navbar-nav .private {
+    font-size: 9px;
+    padding: 3px 5px;
+    display: inline-block;
+    line-height: 8px;
+    border-radius: 3px;
+    margin-left: 6px;
+    color: #fff;
+    top: -2px;
+    position: relative;
+    opacity: 0.6;
+    -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=60)";
+    filter: alpha(opacity=60);
+}
+
+.header .nav.navbar-nav a:hover > .stable,
+.header .nav.navbar-nav a:hover > .beta,
+.header .nav.navbar-nav a:hover > .private {
+    opacity: 1;
+    -ms-filter: none;
+    filter: none;
+}
+
+.header .nav.navbar-nav .beta {
+    background-color: #59c3d1;
+}
+
+.header .nav.navbar-nav .stable {
+    background-color: #41b841;
+}
+
+.header .nav.navbar-nav .private {
+    background-color: #333;
+}
+
+.theme-line header {
+    border-bottom: 8px solid;
+}
+
+.theme-line header h2 {
+    color: #aaa;
+}
+
+.theme-line header p {
+    color: #666;
+}
+
+.theme-line header {
+    border-bottom-color: $ignite-red;
+}
+
+.theme-line .navbar-nav {
+    color: #888;
+}
+
+.theme-line .navbar-nav a {
+    color: #bbb;
+}
+
+.theme-line header a.btn {
+    background-color: $ignite-red;
+}
+
+.theme-line header a.btn:hover {
+    background-color: #950d12;
+}
+
+.theme-line header .navbar-nav .tt-cursor {
+    background-color: $ignite-red;
+}
+
+.theme-line header .navbar-nav a:hover, .theme-line header .navbar-nav .open > a {
+    color: $ignite-red;
+}
+
+.theme-line .navbar-nav .active a {
+    //font-weight: bold;
+    color: $ignite-red;
+}
+
+.theme-line .navbar-nav .active a:hover {
+    color: #950d12;
+}
+
+.theme-line .main-links .links a:hover {
+    color: $ignite-red;
+}
+
+.theme-line .main-content a {
+    color: #666;
+}
+
+.theme-line .main-content a:hover {
+    color: #950d12;
+}
+
+.theme-line .sidebar-nav ul li a.active:before {
+    background-color: $ignite-red;
+}
+
+.theme-line .sidebar-nav ul li a.active {
+    color: $ignite-red;
+}
+
+.theme-line .sidebar-nav ul li a:hover, .theme-line .sidebar-nav ul li a.active:hover {
+    color: #950d12;
+}
+
+.theme-line .main-content .nav-horizontal a.active {
+    border-color: $ignite-red;
+    color: $ignite-red;
+}
+
+.theme-line .main-content .nav-horizontal a:hover {
+    color: #950d12;
+}
+
+.theme-line .main-content .nav-horizontal a.active:hover {
+    border-color: #950d12;
+}
+
+.theme-line header .navbar-nav a.active, .theme-line #versions-list li a:hover strong, .theme-line #versions-list li a.active .current, .theme-line #versions-list li a:active .current {
+    color: $ignite-red;
+}
+
+.theme-line header .navbar-nav a {
+    font-size: 18px;
+}
+
+.theme-line.body-threes .section-right .threes-nav .btn-default:hover, .theme-line.page-docs.body-threes .section-right .threes-nav .pull-right a:hover {
+    color: $ignite-red;
+    border-color: $ignite-red;
+}
+
+.theme-line .section-right {
+    padding-left: 30px;
+}
+
+.body-overlap .main-content {
+    margin-top: 30px;
+}
+
+.body-box .main-content,
+.body-overlap .main-content {
+    padding: 30px;
+    box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.1);
+    background-color: #fff;
+}
+
+body {
+    font-weight: 400;
+    font-family: Roboto Slab, serif;;
+}
+
+h1, h2, h3, h4, h5, h6 {
+    font-weight: 700;
+    font-family: Roboto Slab, serif;
+    margin-bottom: 10px;
+}
+
+.submit-vote.submit-vote-parent.voted a.submit-vote-button, .submit-vote.submit-vote-parent a.submit-vote-button:hover {
+    background-color: $ignite-red;
+}
+
+div.submit-vote.submit-vote-parent.voted a.submit-vote-button:hover {
+    background-color: #950d12;
+}
+
+a, .link .title {
+    color: $ignite-red;
+}
+
+a:hover, .link:hover .title {
+    color: #950d12;
+}
+
+.header h1.navbar-brand a {
+    background-image: url("#{$logo-path}");
+}
+
+.header h1.navbar-brand {
+    width: 96px;
+}
+
+.block-edit-parameters {
+    text-align: right;
+    padding-bottom: 5px;
+}
+
+.container-footer {
+    margin-top: 20px;
+}
+
+/* Modal */
+.modal {
+    display: block;
+    overflow: hidden;
+}
+
+.modal .close {
+    position: absolute;
+    top: 10px;
+    right: 10px;
+    float: none;
+}
+
+// Close icon
+.modal-header .close {
+    margin-right: -2px;
+}
+
+.modal .modal-dialog {
+    width: 610px;
+}
+
+.modal .modal-content {
+    border-radius: 0;
+    background-color: #f7f7f7;
+}
+
+.modal .modal-content .modal-header {
+    background-color: #fff;
+    text-align: center;
+    color: #555;
+    padding: 15px;
+    font-family: "myriad-pro", sans-serif;
+}
+
+.modal .modal-content .modal-header h4 {
+    font-family: "myriad-pro", sans-serif;
+    font-size: 22px;
+}
+
+.modal .modal-content .modal-header h4 .fa {
+    display: block;
+    font-size: 41px;
+    color: #ddd;
+    margin-bottom: 5px;
+}
+
+.modal .modal-content .modal-header p {
+    color: #aaa;
+    font-size: 1em;
+    margin: 3px 0 0;
+}
+
+.modal .modal-content .modal-spacer {
+    padding: 10px 10px 0 10px;
+}
+
+.modal .modal-content .modal-footer {
+    margin-top: 0;
+}
+
+.modal-body {
+    padding-top: 15px;
+}
+
+h1.ignite-logo {
+    background-image: url("#{$logo-path}");
+}
+
+.block-display-image img {
+    max-width: 100%;
+    max-height: 450px;
+    margin: auto;
+    display: block;
+}
+
+.greedy {
+    min-height: 100%;
+    height: #{"calc(100vh - 290px)"};
+}
+
+@media (min-width: 768px) {
+    .navbar-nav > li > a {
+        padding-top: 18px;
+        padding-bottom: 10px;
+    }
+}
+
+.details-row {
+    padding: 0 10px;
+}
+
+.details-row, .settings-row {
+    display: block;
+    margin: 10px 0;
+
+    label.table-header {
+        line-height: $input-height;
+    }
+
+    [class*="col-"] {
+        display: inline-block;
+        vertical-align: middle;
+        float: none;
+
+        padding-left: 0 !important;
+        padding-right: 0 !important;
+    }
+
+    input[type="checkbox"] {
+        line-height: 20px;
+        margin-right: 5px;
+    }
+
+    .checkbox label {
+        line-height: 20px;
+        vertical-align: middle;
+    }
+}
+
+button {
+    margin-right: 5px;
+}
+
+h1,
+h2,
+h3 {
+    user-select: none;
+    font-weight: normal;
+    /* Makes the vertical size of the text the same for all fonts. */
+    line-height: 1;
+}
+
+h3 {
+    color: black;
+    font-size: 1.2em;
+    margin-top: 0;
+    margin-bottom: 1.5em;
+}
+
+table tr:hover {
+    cursor: pointer;
+}
+
+.btn {
+    padding: 3px 6px;
+}
+
+button .caret, .btn .caret {
+    float: right;
+    margin-left: 5px;
+    margin-top: 7px;
+}
+
+.base-control {
+    text-align: left;
+    padding: 3px 3px;
+    height: $input-height;
+}
+
+.form-control {
+    @extend .base-control;
+
+    display: inline-block;
+
+    button {
+        text-align: left;
+    }
+}
+
+.theme-line .panel-heading {
+    padding: 10px 10px;
+    margin: 0;
+
+    h3 {
+        margin-bottom: 0;
+    }
+
+    h3 > a {
+        color: black;
+    }
+}
+
+.theme-line .panel-title {
+    a {
+        color: $ignite-red;
+    }
+
+    h3 {
+        margin-bottom: 20px;
+    }
+}
+
+.theme-line .panel-body {
+    padding: 10px 20px;
+}
+
+.theme-line .main-content a.customize {
+    margin-left: 5px;
+    color: $ignite-red;
+}
+
+.theme-line .panel-collapse {
+    margin: 0;
+}
+
+.theme-line table.links {
+    display: table;
+    table-layout: fixed;
+
+    td {
+        padding-left: 18px;
+    }
+
+    .active a {
+        color: $ignite-red;
+        font-weight: bold;
+    }
+
+    a:hover {
+        color: #950d12;
+    }
+
+    a {
+        color: #666;
+    }
+}
+
+.theme-line table.links-edit {
+    @extend table.links;
+
+    margin-top: 5px;
+    margin-bottom: 5px;
+
+    label {
+        line-height: $input-height;
+        color: #666;
+    }
+}
+
+.theme-line table.links-edit-details {
+    @extend table.links;
+
+    margin-bottom: 10px;
+
+    label {
+        line-height: $input-height;
+        color: #666;
+    }
+
+    td {
+        padding: 0;
+
+        .input-tip {
+            padding: 0;
+        }
+    }
+}
+
+.theme-line table.admin {
+    tr:hover {
+        cursor: default;
+    }
+
+    thead > tr th.header {
+        padding: 0 0 10px;
+
+        div {
+            padding: 0
+        }
+    }
+
+    margin-bottom: 10px;
+
+    label {
+        line-height: $input-height;
+        color: #666;
+    }
+
+    thead > tr th, td {
+        padding: 10px 10px;
+
+        .input-tip {
+            padding: 0;
+        }
+    }
+
+    tfoot > tr > td {
+        padding: 0;
+
+        .pagination {
+            margin: 10px 0;
+
+            > .active > a {
+                color: $ignite-red;
+                font-weight: bold;
+                border-color: #ddd;
+                background-color: #eee;
+            }
+        }
+    }
+}
+
+.theme-line table.sql-results {
+    [class*="col-"] {
+        padding-left: 0 !important;
+        padding-right: 0 !important;
+    }
+
+    td {
+        padding: 3px 6px;
+    }
+
+    > thead > tr > td {
+        padding: 3px 0;
+    }
+
+    thead > tr > th {
+        padding: 3px 6px;
+
+        line-height: $input-height;
+    }
+}
+
+.panel-title a {
+    font-size: 14px;
+}
+
+.panel-details {
+    margin-top: 10px;
+
+    padding: 0;
+
+    border-radius: 5px;
+    border: thin dotted lightgrey;
+}
+
+.table-details {
+    border-radius: 5px;
+    border: thin dotted lightgrey;
+
+    margin-top: 10px;
+
+    padding-left: 10px;
+    padding-right: 5px;
+}
+
+.tooltip.right .tooltip-arrow {
+    border-right-color: $ignite-red;
+}
+
+.tooltip > .tooltip-inner {
+    max-width: 400px;
+    text-align: left;
+    background-color: $ignite-red;
+}
+
+label {
+    font-weight: normal;
+    margin-bottom: 0;
+}
+
+.form-horizontal .checkbox {
+    padding-top: 0;
+}
+
+.input-tip {
+    display: block;
+    overflow: hidden;
+}
+
+.labelField {
+    float: left;
+    margin-right: 5px;
+}
+
+.labelFormField {
+    float: left;
+    line-height: $input-height;
+}
+
+.form-horizontal .form-group {
+    margin: 0;
+}
+
+.form-horizontal .has-feedback .form-control-feedback {
+    right: 0;
+}
+
+.tipField {
+    float: right;
+    line-height: $input-height;
+    margin-left: 5px;
+}
+
+.tipLabel {
+    font-size: 14px;
+    margin-left: 5px;
+}
+
+.fieldSep {
+    float: right;
+    line-height: $input-height;
+    margin: 0 5px;
+}
+
+.fieldButton {
+    float: right;
+    margin-left: 5px;
+    margin-right: 0;
+}
+
+.fa-plus {
+    cursor: pointer;
+}
+
+.fa-remove {
+    color: $ignite-red;
+    cursor: pointer;
+}
+
+.fa-floppy-o {
+    cursor: pointer;
+}
+
+.fa-arrow-up {
+    cursor: pointer;
+}
+
+.fa-arrow-down {
+    cursor: pointer;
+}
+
+label.required:after {
+    color: $ignite-red;
+    content: ' *';
+    display: inline;
+}
+
+.blank {
+    visibility: hidden;
+}
+
+.alert {
+    outline: 0
+}
+
+.alert.bottom, .alert.bottom-left, .alert.bottom-right, .alert.top,
+.alert.top-left, .alert.top-right {
+    position: fixed;
+    z-index: 1050;
+    margin: 20px
+}
+
+.alert.top, .alert.top-left, .alert.top-right {
+    top: 50px
+}
+
+.alert.top {
+    right: 0;
+    left: 0
+}
+
+.alert.top-right {
+    right: 0
+}
+
+.alert.top-right .close {
+    padding-left: 10px
+}
+
+.alert.top-left {
+    left: 0
+}
+
+.alert.top-left .close {
+    padding-right: 10px
+}
+
+.alert.bottom, .alert.bottom-left, .alert.bottom-right {
+    bottom: 0
+}
+
+.alert.bottom {
+    right: 0;
+    left: 0
+}
+
+.alert.bottom-right {
+    right: 0
+}
+
+.alert.bottom-right .close {
+    padding-left: 10px
+}
+
+.alert.bottom-left {
+    left: 0
+}
+
+.alert.bottom-left .close {
+    padding-right: 10px
+}
+
+//  Summary page
+#cfgResult textarea {
+    font-family: monospace;
+    font-size: 12px;
+}
+
+input[type="number"]::-webkit-outer-spin-button,
+input[type="number"]::-webkit-inner-spin-button {
+    -webkit-appearance: none;
+    margin: 0;
+}
+
+input[type="number"] {
+    -moz-appearance: textfield;
+}
+
+input.ng-dirty.ng-invalid, button.ng-dirty.ng-invalid {
+    border-color: $ignite-red;
+
+    :focus {
+        border-color: $ignite-red;
+    }
+}
+
+.form-control-feedback {
+    display: inline-block;
+    color: $ignite-red;
+    right: 18px;
+    line-height: $input-height;
+    pointer-events: initial;
+}
+
+.syntaxhighlighter {
+    padding: 10px 5px;
+    border-radius: 6px;
+}
+
+.theme-line table.links-edit-small-padding {
+    @extend table.links;
+
+    label {
+        line-height: $input-height;
+        color: #666;
+    }
+
+    a {
+        line-height: $input-height;
+    }
+
+    input[type="checkbox"] {
+        line-height: 20px;
+        margin-right: 5px;
+    }
+
+    .checkbox label {
+        line-height: 20px;
+        vertical-align: middle;
+    }
+
+    th {
+        text-align: center;
+    }
+
+    td {
+        padding-left: 10px;
+    }
+
+    margin-top: 10px;
+}
+
+.nav-tabs > li > a {
+    padding: 5px 5px;
+}
+
+.viewedUser {
+    position: absolute;
+    width: 100%;
+    left: 0;
+
+    text-align: center;
+
+    margin-top: -15px;
+
+    background-color: #f8d5d8;
+}
+
+a {
+    cursor: pointer;
+}
+
+.st-sort-ascent:after {
+    content: '\25B2';
+}
+
+.st-sort-descent:after {
+    content: '\25BC';
+}
+
+.panel {
+    margin-bottom: 0;
+}
+
+.panel-group {
+    margin-bottom: 0;
+}
+
+.panel-group .panel + .panel {
+    margin-top: 20px;
+}
+
+.margin-top-dflt {
+    margin-top: 10px;
+}
+
+.margin-bottom-dflt {
+    margin-bottom: 10px;
+}
+
+.margin-dflt {
+    margin-top: 10px;
+    margin-bottom: 10px;
+}
+
+.padding-top-dflt {
+    padding-top: 10px;
+}
+
+.padding-bottom-dflt {
+    padding-bottom: 10px;
+}
+
+.padding-dflt {
+    padding-top: 10px;
+    padding-bottom: 10px;
+}
+
+.theme-line .panel-title h3 {
+    margin-top: 20px;
+    margin-bottom: 20px;
+}
+
+.block-callout-parent {
+    background-color: $ignite-block-callout-background;
+    overflow: hidden;
+}
+
+.block-callout {
+    background-color: $ignite-block-callout-background;
+    display: inline-block;
+    vertical-align: top;
+    width: 50%;
+
+    i {
+        padding: 10px 5px 0 10px;
+        color: $ignite-block-callout;
+    }
+
+    ul {
+        padding-left: 20px;
+        margin-bottom: 0;
+    }
+
+    p {
+        padding: 5px 0 10px 10px;
+        margin: 0;
+    }
+
+    label {
+        font-weight: bold;
+        color: $ignite-block-callout;
+    }
+}
+
+.block-callout-border {
+    border-left: 5px solid;
+    border-color: $ignite-block-callout;
+}
+
+.labelHeader {
+    font-weight: bold;
+}
+
+.ace_editor, #ace_document {
+    margin: 0.65em 0 0 0;
+
+    width: 100%;
+    height: 400px;
+
+    .ace_gutter {
+        background: transparent !important;
+        border: 1px #ddd;
+        border-right-style: solid;
+    }
+
+    .ace_gutter-cell, .ace_folding-enabled > .ace_gutter-cell {
+        padding-left: 0.65em;
+        padding-right: 0.9em;
+    }
+}
+
+.loading-indicator {
+    box-sizing: border-box;
+    -webkit-box-sizing: border-box;
+    -moz-box-sizing: border-box;
+    width: 100%;
+    text-align: center;
+    padding: 0.7em;
+
+    :before {
+        display: inline-block;
+        margin: 0 0.4em;
+        min-width: 1em;
+        min-height: 1em;
+        border: 4px solid #646464;
+        border-right-color: #e6e6e6;
+        border-left-color: #e6e6e6;
+        content: "";
+        -webkit-animation: halfspin 1s ease infinite;
+        -moz-animation: halfspin 1s ease infinite;
+        -o-animation: halfspin 1s ease infinite;
+        animation: halfspin 1s ease infinite;
+        border-radius: 100%;
+    }
+}
+
+@-webkit-keyframes halfspin {
+    to {
+        -webkit-transform: rotate(180deg);
+        -moz-transform: rotate(180deg);
+        transform: rotate(180deg);
+    }
+}
+
+@-moz-keyframes halfspin {
+    to {
+        -webkit-transform: rotate(180deg);
+        -moz-transform: rotate(180deg);
+        transform: rotate(180deg);
+    }
+}
+
+@keyframes halfspin {
+    to {
+        -webkit-transform: rotate(180deg);
+        -moz-transform: rotate(180deg);
+        transform: rotate(180deg);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/control-center-web/src/main/js/routes/admin.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/routes/admin.js b/modules/control-center-web/src/main/js/routes/admin.js
new file mode 100644
index 0000000..5af72f7
--- /dev/null
+++ b/modules/control-center-web/src/main/js/routes/admin.js
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var router = require('express').Router();
+var db = require('../db');
+
+router.get('/', function (req, res) {
+    res.render('settings/admin');
+});
+
+/**
+ * Get list of user accounts.
+ */
+router.post('/list', function (req, res) {
+    db.Account.find({}).sort('username').exec(function (err, users) {
+        if (err)
+            return res.status(500).send(err.message);
+
+        res.json(users);
+    });
+});
+
+router.post('/remove', function (req, res) {
+    var userId = req.body.userId;
+
+    db.Account.findByIdAndRemove(userId, function (err) {
+        if (err)
+            return res.status(500).send(err);
+
+        res.sendStatus(200);
+    });
+});
+
+router.post('/save', function (req, res) {
+    var userId = req.body.userId;
+    var adminFlag = req.body.adminFlag;
+
+    db.Account.findByIdAndUpdate(userId, {admin: adminFlag}, function (err) {
+        if (err)
+            return res.status(500).send(err.message);
+
+        res.sendStatus(200);
+    });
+});
+
+router.get('/become', function (req, res) {
+    var viewedUserId = req.query.viewedUserId;
+
+    if (!viewedUserId) {
+        req.session.viewedUser = null;
+
+        return res.redirect('/admin');
+    }
+
+    db.Account.findById(viewedUserId).exec(function (err, viewedUser) {
+        if (err)
+            return res.sendStatus(404);
+
+        req.session.viewedUser = viewedUser;
+
+        res.redirect('/');
+    })
+});
+
+module.exports = router;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/control-center-web/src/main/js/routes/caches.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/routes/caches.js b/modules/control-center-web/src/main/js/routes/caches.js
new file mode 100644
index 0000000..24152af
--- /dev/null
+++ b/modules/control-center-web/src/main/js/routes/caches.js
@@ -0,0 +1,105 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var router = require('express').Router();
+var db = require('../db');
+
+/* GET caches page. */
+router.get('/', function (req, res) {
+    res.render('configuration/caches');
+});
+
+/**
+ * Get spaces and caches accessed for user account.
+ *
+ * @param req Request.
+ * @param res Response.
+ */
+router.post('/list', function (req, res) {
+    var user_id = req.currentUserId();
+
+    // Get owned space and all accessed space.
+    db.Space.find({$or: [{owner: user_id}, {usedBy: {$elemMatch: {account: user_id}}}]}, function (err, spaces) {
+        if (err)
+            return res.status(500).send(err.message);
+
+        var space_ids = spaces.map(function (value) {
+            return value._id;
+        });
+
+        // Get all caches type metadata for spaces.
+        db.CacheTypeMetadata.find({space: {$in: space_ids}}, '_id name kind', function (err, metadatas) {
+            if (err)
+                return res.status(500).send(err);
+
+            // Get all caches for spaces.
+            db.Cache.find({space: {$in: space_ids}}).sort('name').exec(function (err, caches) {
+                if (err)
+                    return res.status(500).send(err.message);
+
+                var metadatasJson = metadatas.map(function (meta) {
+                    return {value: meta._id, label: meta.name, kind: meta.kind};
+                });
+
+                res.json({spaces: spaces, metadatas: metadatasJson, caches: caches});
+            });
+        });
+    });
+});
+
+/**
+ * Save cache.
+ */
+router.post('/save', function (req, res) {
+    if (req.body._id)
+        db.Cache.update({_id: req.body._id}, req.body, {upsert: true}, function (err) {
+            if (err)
+                return res.status(500).send(err.message);
+
+            res.send(req.body._id);
+        });
+    else {
+        db.Cache.findOne({space: req.body.space, name: req.body.name}, function (err, cache) {
+            if (err)
+                return res.status(500).send(err.message);
+
+            if (cache)
+                return res.status(500).send('Cache with name: "' + cache.name + '" already exist.');
+
+            (new db.Cache(req.body)).save(function (err, cache) {
+                if (err)
+                    return res.status(500).send(err.message);
+
+                res.send(cache._id);
+            });
+        });
+    }
+});
+
+/**
+ * Remove cache by ._id.
+ */
+router.post('/remove', function (req, res) {
+    db.Cache.remove(req.body, function (err) {
+        if (err)
+            return res.status(500).send(err.message);
+
+        res.sendStatus(200);
+    })
+});
+
+module.exports = router;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/control-center-web/src/main/js/routes/clusters.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/routes/clusters.js b/modules/control-center-web/src/main/js/routes/clusters.js
new file mode 100644
index 0000000..683630e
--- /dev/null
+++ b/modules/control-center-web/src/main/js/routes/clusters.js
@@ -0,0 +1,104 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var router = require('express').Router();
+var db = require('../db');
+
+/* GET clusters page. */
+router.get('/', function (req, res) {
+    res.render('configuration/clusters');
+});
+
+/**
+ * Get spaces and clusters accessed for user account.
+ *
+ * @param req Request.
+ * @param res Response.
+ */
+router.post('/list', function (req, res) {
+    var user_id = req.currentUserId();
+
+    // Get owned space and all accessed space.
+    db.Space.find({$or: [{owner: user_id}, {usedBy: {$elemMatch: {account: user_id}}}]}, function (err, spaces) {
+        if (err)
+            return res.status(500).send(err.message);
+
+        var space_ids = spaces.map(function (value) {
+            return value._id;
+        });
+
+        db.Cache.find({space: {$in: space_ids}}, '_id name swapEnabled', function (err, caches) {
+            if (err)
+                return res.status(500).send(err);
+
+            // Get all clusters for spaces.
+            db.Cluster.find({space: {$in: space_ids}}).sort('name').exec(function (err, clusters) {
+                if (err)
+                    return res.status(500).send(err.message);
+
+                var cachesJson = caches.map(function (cache) {
+                    return {value: cache._id, label: cache.name, swapEnabled: cache.swapEnabled};
+                });
+
+                res.json({spaces: spaces, caches: cachesJson, clusters: clusters});
+            });
+        });
+    });
+});
+
+/**
+ * Save cluster.
+ */
+router.post('/save', function (req, res) {
+    if (req.body._id)
+        db.Cluster.update({_id: req.body._id}, req.body, {upsert: true}, function (err) {
+            if (err)
+                return res.status(500).send(err.message);
+
+            res.send(req.body._id);
+        });
+    else {
+        db.Cluster.findOne({space: req.body.space, name: req.body.name}, function (err, cluster) {
+            if (err)
+                return res.status(500).send(err.message);
+
+            if (cluster)
+                return res.status(500).send('Cluster with name: "' + cluster.name + '" already exist.');
+
+            (new db.Cluster(req.body)).save(function (err, cluster) {
+                if (err)
+                    return res.status(500).send(err.message);
+
+                res.send(cluster._id);
+            });
+        });
+    }
+});
+
+/**
+ * Remove cluster by ._id.
+ */
+router.post('/remove', function (req, res) {
+    db.Cluster.remove(req.body, function (err) {
+        if (err)
+            return res.status(500).send(err.message);
+
+        res.sendStatus(200);
+    })
+});
+
+module.exports = router;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/control-center-web/src/main/js/routes/generator/common.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/routes/generator/common.js b/modules/control-center-web/src/main/js/routes/generator/common.js
new file mode 100644
index 0000000..44ddf31
--- /dev/null
+++ b/modules/control-center-web/src/main/js/routes/generator/common.js
@@ -0,0 +1,312 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var _ = require('lodash');
+
+exports.isDefined = function (v) {
+    return !(v === undefined || v === null);
+};
+
+exports.mainComment = mainComment;
+
+function mainComment() {
+    return 'This configuration was generated by Ignite Control Center ('
+        + formatDate(new Date()) + ')';
+}
+
+function addLeadingZero(numberStr, minSize) {
+    if (typeof (numberStr) != 'string')
+        numberStr = '' + numberStr;
+
+    while (numberStr.length < minSize) {
+        numberStr = '0' + numberStr;
+    }
+
+    return numberStr;
+}
+
+exports.formatDate = formatDate;
+
+function formatDate(date) {
+    var dd = addLeadingZero(date.getDate(), 2);
+    var mm = addLeadingZero(date.getMonth() + 1, 2);
+
+    var yyyy = date.getFullYear();
+
+    return mm + '/' + dd + '/' + yyyy + ' ' + addLeadingZero(date.getHours(), 2) + ':' + addLeadingZero(date.getMinutes(), 2);
+}
+
+exports.builder = function () {
+    var res = [];
+
+    res.deep = 0;
+    res.lineStart = true;
+
+    res.append = function (s) {
+        if (this.lineStart) {
+            for (var i = 0; i < this.deep; i++)
+                this.push('    ');
+
+            this.lineStart = false;
+        }
+
+        this.push(s);
+
+        return this;
+    };
+
+    res.line = function (s) {
+        if (s)
+            this.append(s);
+
+        this.push('\n');
+        this.lineStart = true;
+
+        return this;
+    };
+
+    res.startBlock = function (s) {
+        if (s)
+            this.append(s);
+
+        this.push('\n');
+        this.lineStart = true;
+        this.deep++;
+
+        return this;
+    };
+
+    res.endBlock = function (s) {
+        this.deep--;
+
+        if (s)
+            this.append(s);
+
+        this.push('\n');
+        this.lineStart = true;
+
+        return this;
+    };
+
+    res.emptyLineIfNeeded = function () {
+        if (this.needEmptyLine) {
+            this.line();
+
+            this.needEmptyLine = false;
+
+            return true;
+        }
+
+        return false;
+    };
+
+    res.imports = {};
+
+    res.importClass = function (fullClassName) {
+        var dotIdx = fullClassName.lastIndexOf('.');
+
+        var shortName;
+
+        if (dotIdx > 0)
+            shortName = fullClassName.substr(dotIdx + 1);
+        else
+            shortName = fullClassName;
+
+        if (this.imports[shortName]) {
+            if (this.imports[shortName] != fullClassName)
+                throw "Class name conflict: " + this.imports[shortName] + ' and ' + fullClassName;
+        }
+        else {
+            this.imports[shortName] = fullClassName;
+        }
+
+        return shortName;
+    };
+
+    res.generateImports = function () {
+        var res = [];
+
+        for (var clsName in this.imports) {
+            if (this.imports.hasOwnProperty(clsName))
+                res.push('import ' + this.imports[clsName] + ';');
+        }
+
+        return res.join('\n')
+    };
+
+    return res;
+};
+
+function ClassDescriptor(className, fields) {
+    this.className = className;
+    this.fields = fields;
+}
+
+exports.evictionPolicies = {
+    'LRU': new ClassDescriptor('org.apache.ignite.cache.eviction.lru.LruEvictionPolicy',
+        {batchSize: null, maxMemorySize: null, maxSize: null}),
+    'RND': new ClassDescriptor('org.apache.ignite.cache.eviction.random.RandomEvictionPolicy', {maxSize: null}),
+    'FIFO': new ClassDescriptor('org.apache.ignite.cache.eviction.fifo.FifoEvictionPolicy',
+        {batchSize: null, maxMemorySize: null, maxSize: null}),
+    'SORTED': new ClassDescriptor('org.apache.ignite.cache.eviction.sorted.SortedEvictionPolicy',
+        {batchSize: null, maxMemorySize: null, maxSize: null})
+};
+
+exports.marshallers = {
+    OptimizedMarshaller: new ClassDescriptor('org.apache.ignite.marshaller.optimized.OptimizedMarshaller', {
+        poolSize: null,
+        requireSerializable: null
+    }),
+    JdkMarshaller: new ClassDescriptor('org.apache.ignite.marshaller.jdk.JdkMarshaller', {})
+};
+
+var javaBuildInClasses = {
+    BigDecimal: {className: 'java.math.Boolean'},
+    Boolean: {className: 'java.lang.Boolean'},
+    Byte: {className: 'java.lang.Byte'},
+    Date: {className: 'java.sql.Date'},
+    Double: {className: 'java.lang.Double'},
+    Float: {className: 'java.lang.Float'},
+    Integer: {className: 'java.lang.Integer'},
+    Long: {className: 'java.lang.Long'},
+    Short: {className: 'java.lang.Short'},
+    String: {className: 'java.lang.String'},
+    Time: {className: 'java.sql.Time'},
+    Timestamp: {className: 'java.sql.Timestamp'},
+    UUID: {className: 'java.util.UUID'}
+};
+
+exports.javaBuildInClass = function (className) {
+    var fullClassName = javaBuildInClasses[className];
+
+    if (fullClassName)
+        return fullClassName.className;
+
+    return className;
+};
+
+exports.knownClasses = {
+    Oracle: new ClassDescriptor('org.apache.ignite.cache.store.jdbc.dialect.OracleDialect', {}),
+    DB2: new ClassDescriptor('org.apache.ignite.cache.store.jdbc.dialect.DB2Dialect', {}),
+    SQLServer: new ClassDescriptor('org.apache.ignite.cache.store.jdbc.dialect.SQLServerDialect', {}),
+    MySQL: new ClassDescriptor('org.apache.ignite.cache.store.jdbc.dialect.MySQLDialect', {}),
+    PostgreSQL: new ClassDescriptor('org.apache.ignite.cache.store.jdbc.dialect.BasicJdbcDialect', {}),
+    H2: new ClassDescriptor('org.apache.ignite.cache.store.jdbc.dialect.H2Dialect', {})
+};
+
+exports.dataSources = {
+    Oracle: 'oracle.jdbc.pool.OracleDataSource',
+    DB2: 'com.ibm.db2.jcc.DB2ConnectionPoolDataSource',
+    SQLServer: 'com.microsoft.sqlserver.jdbc.SQLServerDataSource',
+    MySQL: 'com.mysql.jdbc.jdbc2.optional.MysqlDataSource',
+    PostgreSQL: 'org.postgresql.ds.PGPoolingDataSource',
+    H2: 'org.h2.jdbcx.JdbcDataSource'
+};
+
+exports.storeFactories = {
+    CacheJdbcPojoStoreFactory: new ClassDescriptor('org.apache.ignite.cache.store.jdbc.CacheJdbcPojoStoreFactory', {
+        dataSourceBean: null,
+        dialect: {type: 'className'}
+    }),
+
+    CacheJdbcBlobStoreFactory: new ClassDescriptor('org.apache.ignite.cache.store.jdbc.CacheJdbcBlobStoreFactory', {
+        user: null,
+        dataSourceBean: null,
+        initSchema: null,
+        createTableQuery: null,
+        loadQuery: null,
+        insertQuery: null,
+        updateQuery: null,
+        deleteQuery: null
+    }),
+
+    CacheHibernateBlobStoreFactory: new ClassDescriptor('org.apache.ignite.cache.store.hibernate.CacheHibernateBlobStoreFactory', {
+        hibernateProperties: {type: 'propertiesAsList', propVarName: 'props'}
+    })
+};
+
+exports.atomicConfiguration = new ClassDescriptor('org.apache.ignite.configuration.AtomicConfiguration', {
+    backups: null,
+    cacheMode: {type: 'enum', enumClass: 'CacheMode'},
+    atomicSequenceReserveSize: null
+});
+
+exports.swapSpaceSpi = new ClassDescriptor('org.apache.ignite.spi.swapspace.file.FileSwapSpaceSpi', {
+    baseDirectory: null,
+    readStripesNumber: null,
+    maximumSparsity: {type: 'float'},
+    maxWriteQueueSize: null,
+    writeBufferSize: null
+});
+
+exports.transactionConfiguration = new ClassDescriptor('org.apache.ignite.configuration.TransactionConfiguration', {
+    defaultTxConcurrency: {type: 'enum', enumClass: 'TransactionConcurrency'},
+    transactionIsolation: {type: 'TransactionIsolation', setterName: 'defaultTxIsolation'},
+    defaultTxTimeout: null,
+    pessimisticTxLogLinger: null,
+    pessimisticTxLogSize: null,
+    txSerializableEnabled: null
+});
+
+exports.hasProperty = function (obj, props) {
+    for (var propName in props) {
+        if (props.hasOwnProperty(propName)) {
+            if (obj[propName])
+                return true;
+        }
+    }
+
+    return false;
+};
+
+/**
+ * Generate properties file with properties stubs for stores data sources.
+ *
+ * @param cluster Configuration to process.
+ * @returns {string} Generated content.
+ */
+exports.generateProperties = function (cluster) {
+    var res = exports.builder();
+
+    var datasources = [];
+
+    if (cluster.caches && cluster.caches.length > 0) {
+        _.forEach(cluster.caches, function (cache) {
+            if (cache.cacheStoreFactory && cache.cacheStoreFactory.kind) {
+                var storeFactory = cache.cacheStoreFactory[cache.cacheStoreFactory.kind];
+
+                if (storeFactory.dialect) {
+                    var beanId = storeFactory.dataSourceBean;
+
+                    if (!_.contains(datasources, beanId)) {
+                        datasources.push(beanId);
+
+                        res.line(beanId + '.jdbc.url=YOUR_JDBC_URL');
+                        res.line(beanId + '.jdbc.username=YOUR_USER_NAME');
+                        res.line(beanId + '.jdbc.password=YOUR_PASSWORD');
+                        res.line();
+                    }
+                }
+            }
+        });
+    }
+
+    if (datasources.length > 0)
+        return '# ' + mainComment() + '\n\n' + res.join();
+
+    return undefined;
+};

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/control-center-web/src/main/js/routes/generator/docker.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/routes/generator/docker.js b/modules/control-center-web/src/main/js/routes/generator/docker.js
new file mode 100644
index 0000000..93faf8e
--- /dev/null
+++ b/modules/control-center-web/src/main/js/routes/generator/docker.js
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+exports.generateClusterConfiguration = function(cluster, os) {
+    if (!os)
+        os = 'debian:8';
+
+    return "" +
+        "# Start from a OS image.\n"+
+        "FROM " + os + "\n"+
+        "\n"+
+        "# Install tools.\n"+
+        "RUN apt-get update && apt-get install -y --fix-missing \\\n"+
+        "  wget \\\n"+
+        "  dstat \\\n"+
+        "  maven \\\n"+
+        "  git\n"+
+        "\n"+
+        "# Install Oracle JDK.\n"+
+        "RUN mkdir /opt/jdk\n"+
+        "\n"+
+        "RUN wget --header \"Cookie: oraclelicense=accept-securebackup-cookie\" \\\n"+
+        "  http://download.oracle.com/otn-pub/java/jdk/7u79-b15/jdk-7u79-linux-x64.tar.gz\n"+
+        "\n"+
+        "RUN tar -zxf jdk-7u79-linux-x64.tar.gz -C /opt/jdk\n"+
+        "\n"+
+        "RUN rm jdk-7u79-linux-x64.tar.gz\n"+
+        "\n"+
+        "RUN update-alternatives --install /usr/bin/java java /opt/jdk/jdk1.7.0_79/bin/java 100\n"+
+        "\n"+
+        "RUN update-alternatives --install /usr/bin/javac javac /opt/jdk/jdk1.7.0_79/bin/javac 100\n"+
+        "\n"+
+        "# Sets java variables.\n"+
+        "ENV JAVA_HOME /opt/jdk/jdk1.7.0_79/\n"+
+        "\n"+
+        "# Create working directory\n"+
+        "WORKDIR /home\n"+
+        "\n"+
+        "RUN wget -O ignite.zip http://tiny.cc/updater/download_ignite.php && unzip ignite.zip && rm ignite.zip\n"+
+        "\n"+
+        "COPY *.xml /tmp/\n"+
+        "\n"+
+        "RUN mv /tmp/*.xml /home/$(ls)/config";
+};

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/control-center-web/src/main/js/routes/generator/java.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/routes/generator/java.js b/modules/control-center-web/src/main/js/routes/generator/java.js
new file mode 100644
index 0000000..41b9bb8
--- /dev/null
+++ b/modules/control-center-web/src/main/js/routes/generator/java.js
@@ -0,0 +1,788 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var _ = require('lodash');
+
+var generatorUtils = require("./common");
+
+/**
+ * Convert some name to valid java name.
+ *
+ * @param name to convert.
+ * @returns {string} Valid java name.
+ */
+function toJavaName(name) {
+    var javaName = name.replace(/[^A-Za-z_0-9]+/, '_');
+
+    return javaName.charAt(0).toLocaleUpperCase() + javaName.slice(1);
+}
+
+exports.generateClusterConfiguration = function(cluster, javaClass, clientNearConfiguration) {
+    var res = generatorUtils.builder();
+
+    res.datasourceBeans = [];
+
+    if (javaClass) {
+        res.line('/**');
+        res.line(' * ' + generatorUtils.mainComment());
+        res.line(' */');
+        res.startBlock('public class ConfigurationFactory {');
+        res.line('/**');
+        res.line(' * Configure grid.');
+        res.line(' */');
+        res.startBlock('public IgniteConfiguration createConfiguration() {');
+    }
+    
+    res.importClass('org.apache.ignite.configuration.IgniteConfiguration');
+    
+    res.line('IgniteConfiguration cfg = new IgniteConfiguration();');
+    res.line();
+
+    if (clientNearConfiguration) {
+        res.line('cfg.setClientMode(true);');
+
+        res.line();
+    }
+
+    if (cluster.discovery) {
+        var d = cluster.discovery;
+
+        res.importClass('org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi');
+        res.line('TcpDiscoverySpi discovery = new TcpDiscoverySpi();');
+
+        switch (d.kind) {
+            case 'Multicast':
+                res.importClass('org.apache.ignite.spi.discovery.tcp.ipfinder.multicast.TcpDiscoveryMulticastIpFinder');
+
+                addBeanWithProperties(res, d.Multicast, 'discovery', 'ipFinder', 'ipFinder',
+                    'TcpDiscoveryMulticastIpFinder', {
+                        multicastGroup: null,
+                        multicastPort: null,
+                        responseWaitTime: null,
+                        addressRequestAttempts: null,
+                        localAddress: null
+                    }, true);
+
+                break;
+
+            case 'Vm':
+                res.importClass('org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder');
+
+                addBeanWithProperties(res, d.Vm, 'discovery', 'ipFinder', 'ipFinder', 'TcpDiscoveryVmIpFinder', {
+                        addresses: {type: 'list'}
+                    }, true);
+
+                break;
+
+            case 'S3':
+                res.importClass('org.apache.ignite.spi.discovery.tcp.ipfinder.s3.TcpDiscoveryS3IpFinder');
+
+                if (d.S3)
+                    addBeanWithProperties(res, d.S3, 'discovery', 'ipFinder', 'ipFinder', 'TcpDiscoveryS3IpFinder',
+                        {bucketName: null}, true);
+                else
+                    res.line('discovery.setIpFinder(new TcpDiscoveryS3IpFinder());');
+
+                break;
+
+            case 'Cloud':
+                res.importClass('org.apache.ignite.spi.discovery.tcp.ipfinder.cloud.TcpDiscoveryCloudIpFinder');
+
+                addBeanWithProperties(res, d.Cloud, 'discovery', 'ipFinder', 'ipFinder', 'TcpDiscoveryCloudIpFinder', {
+                        credential: null,
+                        credentialPath: null,
+                        identity: null,
+                        provider: null,
+                        regions: {type: 'list'},
+                        zones: {type: 'list'}
+                    }, true);
+
+                break;
+
+            case 'GoogleStorage':
+                res.importClass('org.apache.ignite.spi.discovery.tcp.ipfinder.gce.TcpDiscoveryGoogleStorageIpFinder');
+
+                addBeanWithProperties(res, d.GoogleStorage, 'discovery', 'ipFinder', 'ipFinder',
+                    'TcpDiscoveryGoogleStorageIpFinder', {
+                        projectName: null,
+                        bucketName: null,
+                        serviceAccountP12FilePath: null
+                    }, true);
+
+                //if (d.GoogleStorage.addrReqAttempts) todo ????
+                //    res.line('<property name="serviceAccountP12FilePath" value="' + escapeAttr(d.GoogleStorage.addrReqAttempts) + '"/>');
+
+                break;
+
+            case 'Jdbc':
+                res.importClass('org.apache.ignite.spi.discovery.tcp.ipfinder.jdbc.TcpDiscoveryJdbcIpFinder');
+                
+                res.line();
+                res.line('TcpDiscoveryJdbcIpFinder ipFinder = new TcpDiscoveryJdbcIpFinder();');
+                res.line('ipFinder.setInitSchema(' + (d.Jdbc.initSchema != null || d.Jdbc.initSchema) + ');');
+                res.line('discovery.setIpFinder(ipFinder);');
+                res.needEmptyLine = true;
+
+                break;
+
+            case 'SharedFs':
+                res.importClass('org.apache.ignite.spi.discovery.tcp.ipfinder.sharedfs.TcpDiscoverySharedFsIpFinder');
+
+                addBeanWithProperties(res, d.SharedFs, 'discovery', 'ipFinder', 'ipFinder',
+                    'TcpDiscoverySharedFsIpFinder', {path: null}, true);
+
+                break;
+
+            default:
+                throw "Unknown discovery kind: " + d.kind;
+        }
+
+        res.emptyLineIfNeeded();
+
+        res.line('cfg.setDiscoverySpi(discovery);');
+
+        res.needEmptyLine = true;
+    }
+
+    if (cluster.caches && cluster.caches.length > 0) {
+        res.emptyLineIfNeeded();
+
+        var names = [];
+
+        for (var i = 0; i < cluster.caches.length; i++) {
+            res.emptyLineIfNeeded();
+
+            var cache = cluster.caches[i];
+
+            var cacheName = 'cache' + toJavaName(cache.name);
+
+            names.push(cacheName);
+
+            generateCacheConfiguration(res, cache, cacheName);
+
+            res.needEmptyLine = true;
+        }
+
+        res.emptyLineIfNeeded();
+
+        res.append('cfg.setCacheConfiguration(');
+
+        for (i = 0; i < names.length; i++) {
+            if (i > 0)
+                res.append(', ');
+
+            res.append(names[i]);
+        }
+
+        res.line(');');
+
+        res.needEmptyLine = true;
+    }
+
+    addBeanWithProperties(res, cluster.atomicConfiguration, 'cfg', 'atomicConfiguration', 'atomicCfg',
+        generatorUtils.atomicConfiguration.className, generatorUtils.atomicConfiguration.fields);
+
+    res.needEmptyLine = true;
+
+    addProperty(res, cluster, 'cfg', 'networkTimeout');
+    addProperty(res, cluster, 'cfg', 'networkSendRetryDelay');
+    addProperty(res, cluster, 'cfg', 'networkSendRetryCount');
+    addProperty(res, cluster, 'cfg', 'segmentCheckFrequency');
+    addProperty(res, cluster, 'cfg', 'waitForSegmentOnStart');
+    addProperty(res, cluster, 'cfg', 'discoveryStartupDelay');
+
+    res.needEmptyLine = true;
+
+    addProperty(res, cluster, 'cfg', 'deploymentMode', 'DeploymentMode');
+
+    res.needEmptyLine = true;
+
+    if (cluster.includeEventTypes && cluster.includeEventTypes.length > 0) {
+        res.emptyLineIfNeeded();
+        
+        if (cluster.includeEventTypes.length == 1) {
+            res.importClass('org.apache.ignite.events.EventType');
+            
+            res.line('cfg.setIncludeEventTypes(EventType.' + cluster.includeEventTypes[0] + ');');
+        }
+        else {
+            res.append('int[] events = new int[EventType.' + cluster.includeEventTypes[0] + '.length');
+            
+            for (i = 1; i < cluster.includeEventTypes.length; i++) {
+                res.line();
+                
+                res.append('    + EventType.' + cluster.includeEventTypes[i] + '.length');
+            }
+            
+            res.line('];');
+            res.line();
+            res.line('int k = 0;');
+
+            for (i = 0; i < cluster.includeEventTypes.length; i++) {
+                res.line();
+
+                var e = cluster.includeEventTypes[i];
+                
+                res.line('System.arraycopy(EventType.' + e + ', 0, events, k, EventType.' + e + '.length);');
+                res.line('k += EventType.' + e + '.length;');
+            }
+            
+            res.line();
+            res.line('cfg.setIncludeEventTypes(events);');
+        }
+
+        res.needEmptyLine = true;
+    }
+
+    res.needEmptyLine = true;
+
+    var marshaller = cluster.marshaller;
+
+    if (marshaller && marshaller.kind) {
+        var marshallerDesc = generatorUtils.marshallers[marshaller.kind];
+
+        addBeanWithProperties(res, marshaller[marshaller.kind], 'cfg', 'marshaller', 'marshaller',
+            marshallerDesc.className, marshallerDesc.fields, true);
+
+        addBeanWithProperties(res, marshaller[marshaller.kind], 'marshaller', marshallerDesc.className, marshallerDesc.fields, true);
+    }
+
+    addProperty(res, cluster, 'cfg', 'marshalLocalJobs');
+    addProperty(res, cluster, 'cfg', 'marshallerCacheKeepAliveTime');
+    addProperty(res, cluster, 'cfg', 'marshallerCacheThreadPoolSize');
+
+    res.needEmptyLine = true;
+
+    addProperty(res, cluster, 'cfg', 'metricsExpireTime');
+    addProperty(res, cluster, 'cfg', 'metricsHistorySize');
+    addProperty(res, cluster, 'cfg', 'metricsLogFrequency');
+    addProperty(res, cluster, 'cfg', 'metricsUpdateFrequency');
+    res.needEmptyLine = true;
+
+    addProperty(res, cluster, 'cfg', 'peerClassLoadingEnabled');
+    addMultiparamProperty(res, cluster, 'cfg', 'peerClassLoadingLocalClassPathExclude');
+    addProperty(res, cluster, 'cfg', 'peerClassLoadingMissedResourcesCacheSize');
+    addProperty(res, cluster, 'cfg', 'peerClassLoadingThreadPoolSize');
+    res.needEmptyLine = true;
+
+    if (cluster.swapSpaceSpi && cluster.swapSpaceSpi.kind == 'FileSwapSpaceSpi') {
+        addBeanWithProperties(res, cluster.swapSpaceSpi.FileSwapSpaceSpi, 'cfg', 'swapSpaceSpi', 'swapSpi',
+            generatorUtils.swapSpaceSpi.className, generatorUtils.swapSpaceSpi.fields, true);
+
+        res.needEmptyLine = true;
+    }
+
+    addProperty(res, cluster, 'cfg', 'clockSyncSamples');
+    addProperty(res, cluster, 'cfg', 'clockSyncFrequency');
+    addProperty(res, cluster, 'cfg', 'timeServerPortBase');
+    addProperty(res, cluster, 'cfg', 'timeServerPortRange');
+
+    res.needEmptyLine = true;
+
+    addProperty(res, cluster, 'cfg', 'publicThreadPoolSize');
+    addProperty(res, cluster, 'cfg', 'systemThreadPoolSize');
+    addProperty(res, cluster, 'cfg', 'managementThreadPoolSize');
+    addProperty(res, cluster, 'cfg', 'igfsThreadPoolSize');
+
+    res.needEmptyLine = true;
+
+    addBeanWithProperties(res, cluster.transactionConfiguration, 'cfg', 'transactionConfiguration',
+        'transactionConfiguration', generatorUtils.transactionConfiguration.className,
+        generatorUtils.transactionConfiguration.fields);
+
+    res.needEmptyLine = true;
+
+    addProperty(res, cluster, 'cfg', 'cacheSanityCheckEnabled');
+
+    res.needEmptyLine = true;
+
+    if (javaClass) {
+        res.line();
+        res.line('return cfg;');
+        res.endBlock('}');
+        res.endBlock('}');
+        
+        return res.generateImports() + '\n\n' + res.join('')
+    }
+    
+    return res.join('');
+};
+
+function createEvictionPolicy(res, evictionPolicy, varName, propertyName) {
+    if (evictionPolicy && evictionPolicy.kind) {
+        var e = generatorUtils.evictionPolicies[evictionPolicy.kind];
+
+        var obj = evictionPolicy[evictionPolicy.kind.toUpperCase()];
+
+        addBeanWithProperties(res, obj, varName, propertyName, propertyName, e.className, e.fields, true);
+    }
+}
+
+function addCacheTypeMetadataDatabaseFields(res, meta, varName, fieldsProperty) {
+    var fields = meta[fieldsProperty];
+
+    if (fields && fields.length > 0) {
+        res.line('addCacheTypeMetadataDatabaseFields for ' + varName);
+        //res.startBlock('<property name="' + fieldsProperty + '">');
+        //
+        //res.startBlock('<list>');
+        //
+        //_.forEach(fields, function (field) {
+        //    res.startBlock('<bean class="org.apache.ignite.cache.CacheTypeFieldMetadata">');
+        //
+        //    addProperty(res, field, 'databaseName');
+        //
+        //    res.startBlock('<property name="databaseType">');
+        //    res.line('<util:constant static-field="java.sql.Types.' + field.databaseType + '"/>');
+        //    res.endBlock('</property>');
+        //
+        //    addProperty(res, field, 'javaName');
+        //
+        //    addElement(res, 'property', 'name', 'javaType', 'value', generatorUtils.javaBuildInClass(field.javaType));
+        //
+        //    res.endBlock('</bean>');
+        //});
+        //
+        //res.endBlock('</list>');
+        //res.endBlock('</property>');
+    }
+}
+
+function addCacheTypeMetadataQueryFields(res, meta, varName, fieldsProperty) {
+    var fields = meta[fieldsProperty];
+
+    if (fields && fields.length > 0) {
+        res.line('addCacheTypeMetadataQueryFields for ' + varName);
+        //res.startBlock('<property name="' + fieldsProperty + '">');
+        //
+        //res.startBlock('<map>');
+        //
+        //_.forEach(fields, function (field) {
+        //    addElement(res, 'entry', 'key', field.name, 'value', generatorUtils.javaBuildInClass(field.className));
+        //});
+        //
+        //res.endBlock('</map>');
+        //
+        //res.endBlock('</property>');
+    }
+}
+
+function addCacheTypeMetadataGroups(res, meta, varName) {
+    var groups = meta.groups;
+
+    if (groups && groups.length > 0) {
+        res.line('addCacheTypeMetadataGroups for ' + varName);
+        //res.startBlock('<property name="groups">');
+        //res.startBlock('<map>');
+        //
+        //_.forEach(groups, function (group) {
+        //    var fields = group.fields;
+        //
+        //    if (fields && fields.length > 0) {
+        //        res.startBlock('<entry key="' + group.name + '">');
+        //        res.startBlock('<map>');
+        //
+        //        _.forEach(fields, function (field) {
+        //            res.startBlock('<entry key="' + field.name + '">');
+        //
+        //            res.startBlock('<bean class="org.apache.ignite.lang.IgniteBiTuple">');
+        //            res.line('<constructor-arg value="' + generatorUtils.javaBuildInClass(field.className) + '"/>');
+        //            res.line('<constructor-arg value="' + field.direction + '"/>');
+        //            res.endBlock('</bean>');
+        //
+        //            res.endBlock('</entry>');
+        //        });
+        //
+        //        res.endBlock('</map>');
+        //        res.endBlock('</entry>');
+        //    }
+        //});
+        //
+        //res.endBlock('</map>');
+        //res.endBlock('</property>');
+    }
+}
+
+function generateCacheTypeMetadataConfiguration(res, meta, varCacheTypeMetadata) {
+    if (!res)
+        res = generatorUtils.builder();
+
+    res.importClass('org.apache.ignite.cache.CacheTypeMetadata');
+
+    var varType = varCacheTypeMetadata + 'Item';
+
+    addProperty(res, meta, varType, 'databaseSchema');
+    addProperty(res, meta, varType, 'databaseTable');
+
+    addProperty(res, meta, varType, 'keyType');
+    addProperty(res, meta, varType, 'valueType');
+
+    addCacheTypeMetadataDatabaseFields(res, meta, varType, 'keyFields');
+    addCacheTypeMetadataDatabaseFields(res, meta, varType, 'valueFields');
+
+    addCacheTypeMetadataQueryFields(res, meta, varType, 'queryFields');
+    addCacheTypeMetadataQueryFields(res, meta, varType, 'ascendingFields');
+    addCacheTypeMetadataQueryFields(res, meta, varType, 'descendingFields');
+
+    addListProperty(res, meta, varType, 'textFields');
+
+    addCacheTypeMetadataGroups(res, varType, meta);
+
+    res.line(varCacheTypeMetadata + '.add(' + varType + ')');
+
+    return res;
+}
+
+/**
+ * Generate java code for cache configuration.
+ *
+ * @param cache Cache config.
+ * @param varName Variable name.
+ * @param res Result builder.
+ * @returns {*} Append generated java code to builder and return it.
+ */
+function generateCacheConfiguration(res, cache, varName) {
+    if (!res)
+        res = generatorUtils.builder();
+
+    res.emptyLineIfNeeded();
+
+    res.importClass('org.apache.ignite.cache.CacheAtomicityMode');
+    res.importClass('org.apache.ignite.cache.CacheMode');
+    res.importClass('org.apache.ignite.configuration.CacheConfiguration');
+
+    res.line('CacheConfiguration ' + varName + ' = new CacheConfiguration();');
+
+    res.needEmptyLine = true;
+
+    addProperty(res, cache, varName, 'name');
+    
+    addProperty(res, cache, varName, 'mode', 'CacheMode', 'cacheMode');
+
+    addProperty(res, cache, varName, 'atomicityMode', 'CacheAtomicityMode');
+    addProperty(res, cache, varName, 'backups');
+    addProperty(res, cache, varName, 'startSize');
+    addProperty(res, cache, varName, 'readFromBackup');
+
+    res.needEmptyLine = true;
+    
+    addProperty(res, cache, varName, 'memoryMode', 'CacheMemoryMode');
+    addProperty(res, cache, varName, 'offHeapMaxMemory');
+    addProperty(res, cache, varName, 'swapEnabled');
+    addProperty(res, cache, varName, 'copyOnRead');
+
+    res.needEmptyLine = true;
+
+    createEvictionPolicy(res, cache.evictionPolicy, varName, 'evictionPolicy');
+
+    if (cache.nearCacheEnabled) {
+        res.needEmptyLine = true;
+
+        res.importClass('org.apache.ignite.configuration.NearCacheConfiguration');
+
+        addBeanWithProperties(res, cache.nearConfiguration, varName, 'nearConfiguration', 'nearConfiguration',
+            'NearCacheConfiguration', {nearStartSize: null}, true);
+
+        if (cache.nearConfiguration && cache.nearConfiguration.nearEvictionPolicy && cache.nearConfiguration.nearEvictionPolicy.kind) {
+            createEvictionPolicy(res, cache.nearConfiguration.nearEvictionPolicy, 'nearConfiguration', 'nearEvictionPolicy');
+        }
+    }
+
+    res.needEmptyLine = true;
+    
+    addProperty(res, cache, varName, 'sqlEscapeAll');
+    addProperty(res, cache, varName, 'sqlOnheapRowCacheSize');
+    addProperty(res, cache, varName, 'longQueryWarningTimeout');
+    
+    if (cache.indexedTypes && cache.indexedTypes.length > 0) {
+        res.emptyLineIfNeeded();
+        
+        res.append(varName + '.setIndexedTypes(');
+        
+        for (var i = 0; i < cache.indexedTypes.length; i++) {
+            if (i > 0)
+                res.append(', ');
+
+            var pair = cache.indexedTypes[i];
+            
+            res.append(toJavaCode(pair.keyClass, 'class')).append(', ').append(toJavaCode(pair.valueClass, 'class'))
+        }
+        
+        res.line(');');
+    }
+
+    addMultiparamProperty(res, cache, varName, 'sqlFunctionClasses', 'class');
+    
+    res.needEmptyLine = true;
+
+    addProperty(res, cache, varName, 'rebalanceMode', 'CacheRebalanceMode');
+    addProperty(res, cache, varName, 'rebalanceThreadPoolSize');
+    addProperty(res, cache, varName, 'rebalanceBatchSize');
+    addProperty(res, cache, varName, 'rebalanceOrder');
+    addProperty(res, cache, varName, 'rebalanceDelay');
+    addProperty(res, cache, varName, 'rebalanceTimeout');
+    addProperty(res, cache, varName, 'rebalanceThrottle');
+
+    res.needEmptyLine = true;
+    
+    if (cache.cacheStoreFactory && cache.cacheStoreFactory.kind) {
+        var storeFactory = cache.cacheStoreFactory[cache.cacheStoreFactory.kind];
+        var data = generatorUtils.storeFactories[cache.cacheStoreFactory.kind];
+
+        var sfVarName = 'storeFactory' + toJavaName(cache.name);
+        var dsVarName = 'none';
+
+        if (storeFactory.dialect) {
+            var dataSourceBean = storeFactory.dataSourceBean;
+
+            dsVarName = 'dataSource' + generatorUtils.toJavaName(dataSourceBean);
+
+            if (!_.contains(res.datasourceBeans, dataSourceBean)) {
+                res.datasourceBeans.push(dataSourceBean);
+
+                var dataSource = generatorUtils.dataSources[storeFactory.dialect];
+
+                res.line();
+                res.line(dataSource.className + ' ' + dsVarName + ' = new ' + dataSource.className + '();');
+                res.line(dsVarName + '.setURL(_URL_);');
+                res.line(dsVarName + '.setUsername(_User_Name_);');
+                res.line(dsVarName + '.setPassword(_Password_);');
+            }
+        }
+
+        addBeanWithProperties(res, storeFactory, varName, 'cacheStoreFactory', sfVarName, data.className,
+            data.fields, true);
+
+        if (dsVarName != 'none')
+            res.line(sfVarName + '.setDataSource(' + dsVarName + ');');
+    }
+
+    res.needEmptyLine = true;
+
+    addProperty(res, cache, varName, 'loadPreviousValue');
+    addProperty(res, cache, varName, 'readThrough');
+    addProperty(res, cache, varName, 'writeThrough');
+
+    res.needEmptyLine = true;
+    
+    addProperty(res, cache, varName, 'invalidate');
+    addProperty(res, cache, varName, 'defaultLockTimeout');
+    addProperty(res, cache, varName, 'transactionManagerLookupClassName');
+    
+    res.needEmptyLine = true;
+    
+    addProperty(res, cache, varName, 'writeBehindEnabled');
+    addProperty(res, cache, varName, 'writeBehindBatchSize');
+    addProperty(res, cache, varName, 'writeBehindFlushSize');
+    addProperty(res, cache, varName, 'writeBehindFlushFrequency');
+    addProperty(res, cache, varName, 'writeBehindFlushThreadCount');
+    
+    res.needEmptyLine = true;
+
+    addProperty(res, cache, varName, 'statisticsEnabled');
+    addProperty(res, cache, varName, 'managementEnabled');
+
+    res.needEmptyLine = true;
+
+    addProperty(res, cache, varName, 'maxConcurrentAsyncOperations');
+
+    res.needEmptyLine = true;
+
+    // Generate cache type metadata configs.
+    if ((cache.queryMetadata && cache.queryMetadata.length > 0) ||
+        (cache.storeMetadata && cache.storeMetadata.length > 0)) {
+        res.emptyLineIfNeeded();
+
+        var varCacheTypeMetadata = varName + 'TypeMetadata';
+
+        res.line('Collection ' + varCacheTypeMetadata + ' = new ArrayList();');
+        res.line();
+
+        var metaNames = [];
+
+        if (cache.queryMetadata && cache.queryMetadata.length > 0) {
+            _.forEach(cache.queryMetadata, function (meta) {
+                if (!_.contains(metaNames, meta.name)) {
+                    metaNames.push(meta.name);
+
+                    generateCacheTypeMetadataConfiguration(res, meta, varCacheTypeMetadata);
+                }
+            });
+        }
+
+        if (cache.storeMetadata && cache.storeMetadata.length > 0) {
+            _.forEach(cache.storeMetadata, function (meta) {
+                if (!_.contains(metaNames, meta.name)) {
+                    metaNames.push(meta.name);
+
+                    generateCacheTypeMetadataConfiguration(meta, res);
+                }
+            });
+        }
+
+        res.line(varName + '.setCacheTypeMetadata(' + varCacheTypeMetadata + ');');
+    }
+    
+    return res;
+}
+
+function toJavaCode(val, type) {
+    if (val == null)
+       return 'null';
+
+    if (type == 'float')
+        return val + 'f';
+    
+    if (type == 'class')
+        return val + '.class';
+    
+    if (type)
+        return type + '.' + val;
+    
+    if (typeof(val) == 'string')
+        return '"' + val.replace('"', '\\"') + '"';
+
+    if (typeof(val) == 'number' || typeof(val) == 'boolean')
+        return '' + val;
+
+    throw "Unknown type: " + typeof(val) + ' (' + val + ')';
+}
+
+function addProperty(res, obj, objVariableName, propName, enumType, setterName) {
+    var val = obj[propName];
+    
+    if (generatorUtils.isDefined(val)) {
+        res.emptyLineIfNeeded();
+
+        res.line(objVariableName + '.' + getSetterName(setterName ? setterName : propName)
+            + '(' + toJavaCode(val, enumType)  + ');');
+    }
+}
+
+function getSetterName(propName) {
+    return 'set' + propName.charAt(0).toLocaleUpperCase() + propName.slice(1);
+}
+
+function addListProperty(res, obj, objVariableName, propName, enumType, setterName) {
+    var val = obj[propName];
+    
+    if (val && val.length > 0) {
+        res.append(objVariableName + '.' + getSetterName(setterName ? setterName : propName) + '(Arrays.asList(');
+
+        for (var i = 0; i < val.length; i++) {
+            if (i > 0)
+                res.append(', ');
+            
+            res.append(toJavaCode(val[i], enumType));
+        }
+        
+        res.line('));');
+    }
+}
+
+function addMultiparamProperty(res, obj, objVariableName, propName, type, setterName) {
+    var val = obj[propName];
+    
+    if (val && val.length > 0) {
+        res.append(objVariableName + '.' + getSetterName(setterName ? setterName : propName) + '(');
+
+        for (var i = 0; i < val.length; i++) {
+            if (i > 0)
+                res.append(', ');
+            
+            res.append(toJavaCode(val[i], type));
+        }
+        
+        res.line(');');
+    }
+}
+
+function addBeanWithProperties(res, bean, objVarName, beanPropName, beanVarName, beanClass, props, createBeanAlthoughNoProps) {
+    if (bean && generatorUtils.hasProperty(bean, props)) {
+        if (!res.emptyLineIfNeeded()) {
+            res.line();
+        }
+        
+        res.line(beanClass + ' ' + beanVarName + ' = new ' + beanClass + '();');
+
+        for (var propName in props) {
+            if (props.hasOwnProperty(propName)) {
+                var descr = props[propName];
+
+                if (descr) {
+                    switch (descr.type) {
+                        case 'list':
+                            addListProperty(res, bean, beanVarName, propName, descr.elementsType, descr.setterName);
+                            break;
+                        
+                        case 'enum':
+                            addProperty(res, bean, beanVarName, propName, descr.enumClass, descr.setterName);
+                            break;
+                        
+                        case 'float':
+                            addProperty(res, bean, beanVarName, propName, 'float', descr.setterName);
+                            break;
+                        
+                        case 'propertiesAsList':
+                            var val = bean[propName];
+                            
+                            if (val && val.length > 0) {
+                                res.line('Properties ' + descr.propVarName + ' = new Properties();');
+                                
+                                for (var i = 0; i < val.length; i++) {
+                                    var nameAndValue = val[i];
+                                    
+                                    var eqIndex = nameAndValue.indexOf('=');
+                                    if (eqIndex >= 0) {
+                                        res.line(descr.propVarName + '.setProperty(' 
+                                            + nameAndValue.substring(0, eqIndex) + ', ' 
+                                            + nameAndValue.substr(eqIndex + 1) + ');');
+                                    }
+
+                                }
+                                
+                                res.line(beanVarName + '.' + getSetterName(propName) + '(' + descr.propVarName + ');');
+                            }
+                            break;
+                        
+                        case 'className':
+                            if (bean[propName]) {
+                                res.line(beanVarName + '.' + getSetterName(propName) + '(new ' + generatorUtils.knownClasses[bean[propName]].className + '());');
+                            }
+
+                            break;
+                        
+                        default:
+                            addProperty(res, bean, beanVarName, propName, null, descr.setterName);
+                    }
+                }
+                else {
+                    addProperty(res, bean, beanVarName, propName);
+                }
+            }
+        }
+        
+        res.line(objVarName + '.' + getSetterName(beanPropName) + '(' + beanVarName + ');');
+        
+        res.needEmptyLine = true;
+    }
+    else if (createBeanAlthoughNoProps) {
+        res.emptyLineIfNeeded();
+        
+        res.line(objVarName + '.' + getSetterName(beanPropName) + '(new ' + beanClass + '());');
+    }
+}


[16/41] incubator-ignite git commit: Merge remote-tracking branch 'origin/ignite-1121' into ignite-1121

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


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

Branch: refs/heads/ignite-1121
Commit: f58d813307d12e6173b11ca7133a151e146f2745
Parents: 0ff3504 aa3fc51
Author: Andrey <an...@gridgain.com>
Authored: Tue Jul 28 10:54:19 2015 +0700
Committer: Andrey <an...@gridgain.com>
Committed: Tue Jul 28 10:54:19 2015 +0700

----------------------------------------------------------------------
 modules/web-control-center/src/main/js/db.js    |  4 +--
 .../src/main/js/routes/caches.js                |  2 +-
 .../src/main/js/routes/clusters.js              |  2 +-
 .../src/main/js/routes/generator/xml.js         | 29 +++++++++++++++++++-
 .../src/main/js/routes/metadata.js              |  2 +-
 5 files changed, 33 insertions(+), 6 deletions(-)
----------------------------------------------------------------------



[30/41] incubator-ignite git commit: # ignite-843 Rename

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/web-control-center/src/main/js/controllers/models/caches.json
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/controllers/models/caches.json b/modules/web-control-center/src/main/js/controllers/models/caches.json
deleted file mode 100644
index 932eecc..0000000
--- a/modules/web-control-center/src/main/js/controllers/models/caches.json
+++ /dev/null
@@ -1,943 +0,0 @@
-{
-  "screenTip": {
-    "workflowTitle": "Use caches view to:",
-    "workflowContent": [
-      "<ul>",
-      "  <li>Configure caches.</li>",
-      "  <li>Associate metadata with cache queries and/or cache store.</li>",
-      "</ul>"
-    ],
-    "whatsNextTitle": "What's next:",
-    "whatsNextContent": [
-      "<ul>",
-      "  <li>Configure clusters.</li>",
-      "  <li>Configure cache type metadata.</li>",
-      "  <li>Generate XML and java code on Summary view.</li>",
-      "</ul>"
-    ]
-  },
-  "general": [
-    {
-      "label": "Name",
-      "type": "text",
-      "model": "name",
-      "required": true,
-      "placeholder": "Input name",
-      "id": "defaultFocusId"
-    },
-    {
-      "label": "Mode",
-      "type": "dropdown",
-      "model": "mode",
-      "placeholder": "PARTITIONED",
-      "items": "modes",
-      "tip": [
-        "Cache modes:",
-        "<ul>",
-        "  <li>Partitioned - in this mode the overall key set will be divided into partitions and all partitions will be split equally between participating nodes.</li>",
-        "  <li>Replicated - in this mode all the keys are distributed to all participating nodes.</li>",
-        "  <li>Local - in this mode caches residing on different grid nodes will not know about each other.</li>",
-        "</ul>"
-      ]
-    },
-    {
-      "label": "Atomicity",
-      "type": "dropdown",
-      "model": "atomicityMode",
-      "placeholder": "ATOMIC",
-      "items": "atomicities",
-      "tip": [
-        "Atomicity:",
-        "<ul>",
-        "  <li>Transactional - in this mode specified fully ACID-compliant transactional cache behavior.</li>",
-        "  <li>Atomic - in this mode distributed transactions and distributed locking are not supported.</li>",
-        "</ul>"
-      ]
-    },
-    {
-      "label": "Backups",
-      "type": "number",
-      "model": "backups",
-      "hide": "backupItem.mode == 'LOCAL'",
-      "placeholder": 0,
-      "tip": [
-        "Number of nodes used to back up single partition for partitioned cache."
-      ]
-    },
-    {
-      "label": "Read from backup",
-      "type": "check",
-      "model": "readFromBackup",
-      "placeholder": true,
-      "hide": "!backupItem.backups || backupItem.mode == 'LOCAL'",
-      "tip": [
-        "Flag indicating whether data can be read from backup.",
-        "If not set then always get data from primary node (never from backup)."
-      ]
-    },
-    {
-      "label": "Copy on read",
-      "type": "check",
-      "model": "copyOnRead",
-      "placeholder": true,
-      "tip": [
-        "Flag indicating whether copy of of the value stored in cache should be created for cache operation implying return value.",
-        "Also if this flag is set copies are created for values passed to CacheInterceptor and to CacheEntryProcessor."
-      ]
-    },
-    {
-      "label": "Invalidate near cache",
-      "type": "check",
-      "model": "invalidate",
-      "tip": [
-        "Invalidation flag for near cache entries in transaction.",
-        "If set then values will be invalidated (nullified) upon commit in near cache."
-      ]
-    }
-  ],
-  "advanced": [
-    {
-      "label": "Concurrency control",
-      "tip": [
-        "Cache concurrent usage settings."
-      ],
-      "fields": [
-        {
-          "label": "Max async operations",
-          "type": "number",
-          "model": "maxConcurrentAsyncOperations",
-          "placeholder": 500,
-          "tip": [
-            "Maximum number of allowed concurrent asynchronous operations.",
-            "If 0 then number of concurrent asynchronous operations is unlimited."
-          ]
-        },
-        {
-          "label": "Default lock timeout",
-          "type": "number",
-          "model": "defaultLockTimeout",
-          "placeholder": 0,
-          "tip": [
-            "Default lock acquisition timeout.",
-            "If 0 then lock acquisition will never timeout."
-          ]
-        },
-        {
-          "label": "Entry versioning",
-          "type": "dropdown",
-          "model": "atomicWriteOrderMode",
-          "placeholder": "Choose versioning",
-          "items": "atomicWriteOrderModes",
-          "hide": "backupItem.atomicityMode == 'TRANSACTIONAL'",
-          "tip": [
-            "Write ordering mode determines which node assigns the write version, sender or the primary node.",
-            "<ul>",
-            "  <li>CLOCK - in this mode write versions are assigned on a sender node which generally leads to better performance.</li>",
-            "  <li>PRIMARY - in this mode version is assigned only on primary node. This means that sender will only send write request to primary node, which in turn will assign write version and forward it to backups.</li>",
-            "</ul>"
-          ]
-        }
-      ]
-    },
-    {
-      "label": "Memory",
-      "tip": [
-        "Cache memory settings."
-      ],
-      "fields": [
-        {
-          "label": "Mode",
-          "type": "dropdown",
-          "model": "memoryMode",
-          "placeholder": "ONHEAP_TIERED",
-          "items": "memoryModes",
-          "tip": [
-            "Memory modes:",
-            "<ul>",
-            "  <li>ONHEAP_TIERED - entries are cached on heap memory first.",
-            "    <ul>",
-            "      <li>If offheap memory is enabled and eviction policy evicts an entry from heap memory, entry will be moved to offheap memory. If offheap memory is disabled, then entry is simply discarded.</li>",
-            "      <li>If swap space is enabled and offheap memory fills up, then entry will be evicted into swap space. If swap space is disabled, then entry will be discarded. If swap is enabled and offheap memory is disabled, then entry will be evicted directly from heap memory into swap.</li>",
-            "    </ul>",
-            "  </li>",
-            "  <li>OFFHEAP_TIERED - works the same as ONHEAP_TIERED, except that entries never end up in heap memory and get stored in offheap memory right away. Entries get cached in offheap memory first and then get evicted to swap, if one is configured.</li>",
-            "  <li>OFFHEAP_VALUES - entry keys will be stored on heap memory, and values will be stored in offheap memory. Note that in this mode entries can be evicted only to swap.</li>",
-            "</ul>"
-          ]
-        },
-        {
-          "label": "Off-heap max memory",
-          "type": "number",
-          "model": "offHeapMaxMemory",
-          "min": -1,
-          "placeholder": -1,
-          "hide": "backupItem.memoryMode == 'OFFHEAP_VALUES'",
-          "tip": [
-            "Sets maximum amount of memory available to off-heap storage.",
-            "Possible values are:",
-            "<ul>",
-            "  <li>-1 - means that off-heap storage is disabled.</li>",
-            "  <li>0 - Ignite will not limit off-heap storage (it's up to user to properly add and remove entries from cache to ensure that off-heap storage does not grow infinitely.</li>",
-            "  <li>Any positive value specifies the limit of off-heap storage in bytes.</li>",
-            "</ul>"
-          ]
-        },
-        {
-          "label": "Eviction policy",
-          "type": "dropdown-details",
-          "path": "evictionPolicy",
-          "model": "kind",
-          "placeholder": "Choose eviction policy",
-          "items": "evictionPolicies",
-          "hide": "backupItem.memoryMode == 'OFFHEAP_TIERED'",
-          "tip": [
-            "Optional cache eviction policy. Must be set for entries to be evicted from on-heap to off-heap or swap."
-          ],
-          "details": {
-            "LRU": {
-              "expanded": false,
-              "fields": [
-                {
-                  "label": "Batch size",
-                  "type": "number",
-                  "path": "evictionPolicy.LRU",
-                  "model": "batchSize",
-                  "placeholder": 1,
-                  "tip": [
-                    "Number of entries to remove on shrink."
-                  ]
-                },
-                {
-                  "label": "Max memory size",
-                  "type": "number",
-                  "path": "evictionPolicy.LRU",
-                  "model": "maxMemorySize",
-                  "placeholder": 0,
-                  "tip": [
-                    "Maximum allowed cache size in bytes."
-                  ]
-                },
-                {
-                  "label": "Max size",
-                  "type": "number",
-                  "path": "evictionPolicy.LRU",
-                  "model": "maxSize",
-                  "placeholder": 100000,
-                  "tip": [
-                    "Maximum allowed size of cache before entry will start getting evicted."
-                  ]
-                }
-              ]
-            },
-            "RND": {
-              "expanded": false,
-              "fields": [
-                {
-                  "label": "Max size",
-                  "type": "number",
-                  "path": "evictionPolicy.RND",
-                  "model": "maxSize",
-                  "placeholder": 100000,
-                  "tip": [
-                    "Maximum allowed size of cache before entry will start getting evicted."
-                  ]
-                }
-              ]
-            },
-            "FIFO": {
-              "expanded": false,
-              "fields": [
-                {
-                  "label": "Batch size",
-                  "type": "number",
-                  "path": "evictionPolicy.FIFO",
-                  "model": "batchSize",
-                  "placeholder": 1,
-                  "tip": [
-                    "Number of entries to remove on shrink."
-                  ]
-                },
-                {
-                  "label": "Max memory size",
-                  "type": "number",
-                  "path": "evictionPolicy.FIFO",
-                  "model": "maxMemorySize",
-                  "placeholder": 0,
-                  "tip": [
-                    "Maximum allowed cache size in bytes."
-                  ]
-                },
-                {
-                  "label": "Max size",
-                  "type": "number",
-                  "path": "evictionPolicy.FIFO",
-                  "model": "maxSize",
-                  "placeholder": 100000,
-                  "tip": [
-                    "Maximum allowed size of cache before entry will start getting evicted."
-                  ]
-                }
-              ]
-            },
-            "SORTED": {
-              "expanded": false,
-              "fields": [
-                {
-                  "label": "Batch size",
-                  "type": "number",
-                  "path": "evictionPolicy.SORTED",
-                  "model": "batchSize",
-                  "placeholder": 1,
-                  "tip": [
-                    "Number of entries to remove on shrink."
-                  ]
-                },
-                {
-                  "label": "Max memory size",
-                  "type": "number",
-                  "path": "evictionPolicy.SORTED",
-                  "model": "maxMemorySize",
-                  "placeholder": 0,
-                  "tip": [
-                    "Maximum allowed cache size in bytes."
-                  ]
-                },
-                {
-                  "label": "Max size",
-                  "type": "number",
-                  "path": "evictionPolicy.SORTED",
-                  "model": "maxSize",
-                  "placeholder": 100000,
-                  "tip": [
-                    "Maximum allowed size of cache before entry will start getting evicted."
-                  ]
-                }
-              ]
-            }
-          }
-        },
-        {
-          "label": "Start size",
-          "type": "number",
-          "model": "startSize",
-          "placeholder": 1500000,
-          "tip": [
-            "Initial cache size which will be used to pre-create internal hash table after start."
-          ]
-        },
-        {
-          "label": "Swap enabled",
-          "type": "check",
-          "model": "swapEnabled",
-          "tip": [
-            "Flag indicating whether swap storage is enabled or not for this cache."
-          ]
-        }
-      ]
-    },
-    {
-      "label": "Query",
-      "tip": [
-        "Cache query settings."
-      ],
-      "fields": [
-        {
-          "label": "Escape table and filed names",
-          "type": "check",
-          "model": "sqlEscapeAll",
-          "tip": [
-            "If set then all the SQL table and field names will be escaped with double quotes.",
-            "This enforces case sensitivity for field names and also allows having special characters in table and field names."
-          ]
-        },
-        {
-          "label": "On-heap cache for off-heap indexes",
-          "type": "number",
-          "model": "sqlOnheapRowCacheSize",
-          "placeholder": 10240,
-          "tip": [
-            "Number of SQL rows which will be cached onheap to avoid deserialization on each SQL index access."
-          ]
-        },
-        {
-          "label": "Long query timeout",
-          "type": "number",
-          "model": "longQueryWarningTimeout",
-          "placeholder": 3000,
-          "tip": [
-            "Timeout in milliseconds after which long query warning will be printed."
-          ]
-        },
-        {
-          "label": "Metadata",
-          "type": "dropdown-multiple",
-          "model": "queryMetadata",
-          "placeholder": "Choose metadata",
-          "items": "queryMetadata",
-          "tip": [
-            "Select cache type metadata to describe types in cache."
-          ],
-          "addLink": {
-            "label": "Add metadata(s)",
-            "ref": "/configuration/metadata"
-          }
-        } ,
-        {
-          "type": "indexedTypes",
-          "model": "indexedTypes",
-          "keyName": "keyClass",
-          "valueName": "valueClass",
-          "focusNewItemId": "newIndexedType",
-          "focusCurItemId": "curIndexedType",
-          "addTip": "Add new key and value classes to indexed types.",
-          "removeTip": "Remove item from indexed types.",
-          "tip": [
-            "Collection of types to index."
-          ]
-        },
-        {
-          "label": "SQL functions",
-          "type": "table-simple",
-          "model": "sqlFunctionClasses",
-          "editIdx": -1,
-          "placeholder": "SQL function full class name",
-          "focusNewItemId": "newSqlFxField",
-          "focusCurItemId": "curSqlFxField",
-          "addTip": "Add new user-defined functions for SQL queries.",
-          "removeTip": "Remove user-defined function.",
-          "tableTip": [
-            "Collections of classes with user-defined functions for SQL queries."
-          ],
-          "tip": [
-            "Class with user-defined functions for SQL queries."
-          ]
-        }
-      ]
-    },
-    {
-      "label": "Rebalance",
-      "tip": [
-        "Cache rebalance settings."
-      ],
-      "fields": [
-        {
-          "label": "Mode",
-          "type": "dropdown",
-          "model": "rebalanceMode",
-          "placeholder": "ASYNC",
-          "items": "rebalanceModes",
-          "tip": [
-            "Rebalance modes:",
-            "<ul>",
-            "  <li>Synchronous - in this mode distributed caches will not start until all necessary data is loaded from other available grid nodes.</li>",
-            "  <li>Asynchronous - in this mode distributed caches will start immediately and will load all necessary data from other available grid nodes in the background.</li>",
-            "  <li>None - in this mode no rebalancing will take place which means that caches will be either loaded on demand from persistent store whenever data is accessed, or will be populated explicitly.</li>",
-            "</ul>"
-          ]
-        },
-        {
-          "label": "Pool size",
-          "type": "number",
-          "model": "rebalanceThreadPoolSize",
-          "placeholder": 2,
-          "tip": [
-            "Size of rebalancing thread pool.<br>",
-            "Note that size serves as a hint and implementation may create more threads for rebalancing than specified here (but never less threads)."
-          ]
-        },
-        {
-          "label": "Batch size",
-          "type": "number",
-          "model": "rebalanceBatchSize",
-          "placeholder": "512 * 1024",
-          "tip": [
-            "Size (in bytes) to be loaded within a single rebalance message.",
-            "Rebalancing algorithm will split total data set on every node into multiple batches prior to sending data."
-          ]
-        },
-        {
-          "label": "Order",
-          "type": "number",
-          "model": "rebalanceOrder",
-          "placeholder": 0,
-          "tip": [
-            "If cache rebalance order is positive, rebalancing for this cache will be started only when rebalancing for all caches with smaller rebalance order (except caches with rebalance order 0) will be completed."
-          ]
-        },
-        {
-          "label": "Delay",
-          "type": "number",
-          "model": "rebalanceDelay",
-          "placeholder": 0,
-          "tip": [
-            "Delay in milliseconds upon a node joining or leaving topology (or crash) after which rebalancing should be started automatically."
-          ]
-        },
-        {
-          "label": "Timeout",
-          "type": "number",
-          "model": "rebalanceTimeout",
-          "placeholder": 10000,
-          "tip": [
-            "Rebalance timeout in milliseconds."
-          ]
-        },
-        {
-          "label": "Throttle",
-          "type": "number",
-          "model": "rebalanceThrottle",
-          "placeholder": 0,
-          "tip": [
-            "Time in milliseconds to wait between rebalance messages to avoid overloading of CPU or network."
-          ]
-        }
-      ]
-    },
-    {
-      "label": "Server near cache",
-      "tip": [
-        "Near cache settings.",
-        "Near cache is a small local cache that stores most recently or most frequently accessed data.",
-        "Should be used in case when it is impossible to send computations to remote nodes."
-      ],
-      "fields": [
-        {
-          "label": "Enabled",
-          "type": "check",
-          "model": "nearCacheEnabled",
-          "tip": [
-            "Flag indicating whether to configure near cache."
-          ]
-        },
-        {
-          "label": "Start size",
-          "type": "number",
-          "path": "nearConfiguration",
-          "model": "nearStartSize",
-          "hide": "!backupItem.nearCacheEnabled",
-          "placeholder": 375000,
-          "tip": [
-            "Initial cache size for near cache which will be used to pre-create internal hash table after start."
-          ]
-        },
-        {
-          "label": "Eviction policy",
-          "type": "dropdown-details",
-          "path": "nearConfiguration.nearEvictionPolicy",
-          "model": "kind",
-          "placeholder": "Choose eviction policy",
-          "items": "evictionPolicies",
-          "hide": "!backupItem.nearCacheEnabled",
-          "tip": [
-            "Cache expiration policy."
-          ],
-          "details": {
-            "LRU": {
-              "expanded": false,
-              "fields": [
-                {
-                  "label": "Batch size",
-                  "type": "number",
-                  "path": "nearConfiguration.nearEvictionPolicy.LRU",
-                  "model": "batchSize",
-                  "placeholder": 1,
-                  "tip": [
-                    "Number of entries to remove on shrink."
-                  ]
-                },
-                {
-                  "label": "Max memory size",
-                  "type": "number",
-                  "path": "nearConfiguration.nearEvictionPolicy.LRU",
-                  "model": "maxMemorySize",
-                  "placeholder": 0,
-                  "tip": [
-                    "Maximum allowed cache size in bytes."
-                  ]
-                },
-                {
-                  "label": "Max size",
-                  "type": "number",
-                  "path": "nearConfiguration.nearEvictionPolicy.LRU",
-                  "model": "maxSize",
-                  "placeholder": 100000,
-                  "tip": [
-                    "Maximum allowed size of cache before entry will start getting evicted."
-                  ]
-                }
-              ]
-            },
-            "RND": {
-              "expanded": false,
-              "fields": [
-                {
-                  "label": "Max size",
-                  "type": "number",
-                  "path": "nearConfiguration.nearEvictionPolicy.RND",
-                  "model": "maxSize",
-                  "placeholder": 100000,
-                  "tip": [
-                    "Maximum allowed size of cache before entry will start getting evicted."
-                  ]
-                }
-              ]
-            },
-            "FIFO": {
-              "expanded": false,
-              "fields": [
-                {
-                  "label": "Batch size",
-                  "type": "number",
-                  "path": "nearConfiguration.nearEvictionPolicy.FIFO",
-                  "model": "batchSize",
-                  "placeholder": 1,
-                  "tip": [
-                    "Number of entries to remove on shrink."
-                  ]
-                },
-                {
-                  "label": "Max memory size",
-                  "type": "number",
-                  "path": "nearConfiguration.nearEvictionPolicy.FIFO",
-                  "model": "maxMemorySize",
-                  "placeholder": 0,
-                  "tip": [
-                    "Maximum allowed cache size in bytes."
-                  ]
-                },
-                {
-                  "label": "Max size",
-                  "type": "number",
-                  "path": "nearConfiguration.nearEvictionPolicy.FIFO",
-                  "model": "maxSize",
-                  "placeholder": 100000,
-                  "tip": [
-                    "Maximum allowed size of cache before entry will start getting evicted."
-                  ]
-                }
-              ]
-            },
-            "SORTED": {
-              "expanded": false,
-              "fields": [
-                {
-                  "label": "Batch size",
-                  "type": "number",
-                  "path": "nearConfiguration.nearEvictionPolicy.SORTED",
-                  "model": "batchSize",
-                  "placeholder": 1,
-                  "tip": [
-                    "Number of entries to remove on shrink."
-                  ]
-                },
-                {
-                  "label": "Max memory size",
-                  "type": "number",
-                  "path": "nearConfiguration.nearEvictionPolicy.SORTED",
-                  "model": "maxMemorySize",
-                  "placeholder": 0,
-                  "tip": [
-                    "Maximum allowed cache size in bytes."
-                  ]
-                },
-                {
-                  "label": "Max size",
-                  "type": "number",
-                  "path": "nearConfiguration.nearEvictionPolicy.SORTED",
-                  "model": "maxSize",
-                  "placeholder": 100000,
-                  "tip": [
-                    "Maximum allowed size of cache before entry will start getting evicted."
-                  ]
-                }
-              ]
-            }
-          }
-        }
-      ]
-    },
-    {
-      "label": "Statistics",
-      "tip": [
-        "Cache statistics and management settings."
-      ],
-      "fields": [
-        {
-          "label": "Statistics enabled",
-          "type": "check",
-          "model": "statisticsEnabled",
-          "tip": [
-            "Flag indicating whether statistics gathering is enabled on a cache."
-          ]
-        },
-        {
-          "label": "Management enabled",
-          "type": "check",
-          "model": "managementEnabled",
-          "tip": [
-            "Flag indicating whether management is enabled on this cache."
-          ]
-        }
-      ]
-    },
-    {
-      "label": "Store",
-      "tip": [
-        "Cache store settings."
-      ],
-      "fields": [
-        {
-          "label": "Store factory",
-          "type": "dropdown-details",
-          "path": "cacheStoreFactory",
-          "model": "kind",
-          "placeholder": "Choose store factory",
-          "items": "cacheStoreFactories",
-          "tip": [
-            "Factory for persistent storage for cache data."
-          ],
-          "details": {
-            "CacheJdbcPojoStoreFactory": {
-              "expanded": true,
-              "fields": [
-                {
-                  "label": "Data source bean",
-                  "type": "text",
-                  "path": "cacheStoreFactory.CacheJdbcPojoStoreFactory",
-                  "model": "dataSourceBean",
-                  "required": true,
-                  "placeholder": "Bean name in Spring context",
-                  "tip": [
-                    "Name of the data source bean in Spring context."
-                  ]
-                },
-                {
-                  "label": "Dialect",
-                  "type": "dropdown",
-                  "path": "cacheStoreFactory.CacheJdbcPojoStoreFactory",
-                  "model": "dialect",
-                  "required": true,
-                  "placeholder": "Choose JDBC dialect",
-                  "items": "cacheStoreJdbcDialects",
-                  "tip": [
-                    "Dialect of SQL implemented by a particular RDBMS:",
-                    "<ul>",
-                    "  <li>Generic JDBC dialect.</li>",
-                    "  <li>Oracle database.</li>",
-                    "  <li>IBM DB2.</li>",
-                    "  <li>Microsoft SQL Server.</li>",
-                    "  <li>My SQL.</li>",
-                    "  <li>H2 database.</li>",
-                    "</ul>"
-                  ]
-                }
-              ]
-            },
-            "CacheJdbcBlobStoreFactory": {
-              "expanded": true,
-              "fields": [
-                {
-                  "label": "user",
-                  "type": "text",
-                  "path": "cacheStoreFactory.CacheJdbcBlobStoreFactory",
-                  "model": "user",
-                  "required": true,
-                  "tip": [
-                    "User name for database access."
-                  ]
-                },
-                {
-                  "label": "Data source bean",
-                  "type": "text",
-                  "path": "cacheStoreFactory.CacheJdbcBlobStoreFactory",
-                  "model": "dataSourceBean",
-                  "required": true,
-                  "placeholder": "Bean name in Spring context",
-                  "tip": [
-                    "Name of the data source bean in Spring context."
-                  ]
-                },
-                {
-                  "label": "Init schema",
-                  "type": "check",
-                  "path": "cacheStoreFactory.CacheJdbcBlobStoreFactory",
-                  "model": "initSchema",
-                  "tip": [
-                    "Flag indicating whether DB schema should be initialized by Ignite (default behaviour) or was explicitly created by user."
-                  ]
-                },
-                {
-                  "label": "Create query",
-                  "type": "text",
-                  "path": "cacheStoreFactory.CacheJdbcBlobStoreFactory",
-                  "model": "createTableQuery",
-                  "placeholder": "SQL for table creation",
-                  "tip": [
-                    "Query for table creation in underlying database.",
-                    "Default value: create table if not exists ENTRIES (key binary primary key, val binary)"
-                  ]
-                },
-                {
-                  "label": "Load query",
-                  "type": "text",
-                  "path": "cacheStoreFactory.CacheJdbcBlobStoreFactory",
-                  "model": "loadQuery",
-                  "placeholder": "SQL for load entry",
-                  "tip": [
-                    "Query for entry load from underlying database.",
-                    "Default value: select * from ENTRIES where key=?"
-                  ]
-                },
-                {
-                  "label": "Insert query",
-                  "type": "text",
-                  "path": "cacheStoreFactory.CacheJdbcBlobStoreFactory",
-                  "model": "insertQuery",
-                  "placeholder": "SQL for insert entry",
-                  "tip": [
-                    "Query for insert entry into underlying database.",
-                    "Default value: insert into ENTRIES (key, val) values (?, ?)"
-                  ]
-                },
-                {
-                  "label": "Update query",
-                  "type": "text",
-                  "path": "cacheStoreFactory.CacheJdbcBlobStoreFactory",
-                  "model": "updateQuery",
-                  "placeholder": "SQL for update entry",
-                  "tip": [
-                    "Query fpr update entry in underlying database.",
-                    "Default value: update ENTRIES set val=? where key=?"
-                  ]
-                },
-                {
-                  "label": "Delete query",
-                  "type": "text",
-                  "path": "cacheStoreFactory.CacheJdbcBlobStoreFactory",
-                  "model": "deleteQuery",
-                  "placeholder": "SQL for delete entry",
-                  "tip": [
-                    "Query for delete entry from underlying database.",
-                    "Default value: delete from ENTRIES where key=?"
-                  ]
-                }
-              ]
-            },
-            "CacheHibernateBlobStoreFactory": {
-              "expanded": true,
-              "fields": [
-                {
-                  "label": "Hibernate properties",
-                  "type": "table-simple",
-                  "path": "cacheStoreFactory.CacheHibernateBlobStoreFactory",
-                  "model": "hibernateProperties",
-                  "editIdx": -1,
-                  "placeholder": "key=value",
-                  "addTip": "Add new Hibernate property.",
-                  "removeTip": "Remove Hibernate property.",
-                  "tip": [
-                    "List of Hibernate properties.",
-                    "For example: connection.url=jdbc:h2:mem:"
-                  ]
-                }
-              ]
-            }
-          }
-        },
-        {
-          "label": "Load previous value",
-          "type": "check",
-          "model": "loadPreviousValue",
-          "tip": [
-            "Flag indicating whether value should be loaded from store if it is not in the cache for following cache operations:",
-            "<ul>",
-            "  <li>IgniteCache.putIfAbsent()</li>",
-            "  <li>IgniteCache.replace()</li>",
-            "  <li>IgniteCache.replace()</li>",
-            "  <li>IgniteCache.remove()</li>",
-            "  <li>IgniteCache.getAndPut()</li>",
-            "  <li>IgniteCache.getAndRemove()</li>",
-            "  <li>IgniteCache.getAndReplace()</li>",
-            "  <li>IgniteCache.getAndPutIfAbsent()</li>",
-            "</ul>"
-          ]
-        },
-        {
-          "label": "Read-through",
-          "type": "check",
-          "model": "readThrough",
-          "tip": [
-            "Flag indicating whether read-through caching should be used."
-          ]
-        },
-        {
-          "label": "Write-through",
-          "type": "check",
-          "model": "writeThrough",
-          "tip": [
-            "Flag indicating whether write-through caching should be used."
-          ]
-        }
-      ]
-    },
-    {
-      "label": "Write behind",
-      "tip": [
-        "Cache write behind settings.",
-        "Write-behind is a special mode when updates to cache accumulated and then asynchronously flushed to persistent store as a bulk operation."
-      ],
-      "fields": [
-        {
-          "label": "Enabled",
-          "type": "check",
-          "model": "writeBehindEnabled",
-          "tip": [
-            "Flag indicating whether Ignite should use write-behind behaviour for the cache store."
-          ]
-        },
-        {
-          "label": "Batch size",
-          "type": "number",
-          "model": "writeBehindBatchSize",
-          "hide": "!backupItem.writeBehindEnabled",
-          "placeholder": 512,
-          "tip": [
-            "Maximum batch size for write-behind cache store operations.",
-            "Store operations (get or remove) are combined in a batch of this size to be passed to cache store."
-          ]
-        },
-        {
-          "label": "Flush size",
-          "type": "number",
-          "model": "writeBehindFlushSize",
-          "hide": "!backupItem.writeBehindEnabled",
-          "placeholder": 10240,
-          "tip": [
-            "Maximum size of the write-behind cache.<br>",
-            "If cache size exceeds this value, all cached items are flushed to the cache store and write cache is cleared."
-          ]
-        },
-        {
-          "label": "Flush frequency",
-          "type": "number",
-          "model": "writeBehindFlushFrequency",
-          "hide": "!backupItem.writeBehindEnabled",
-          "placeholder": 5000,
-          "tip": [
-            "Frequency with which write-behind cache is flushed to the cache store in milliseconds."
-          ]
-        },
-        {
-          "label": "Flush threads count",
-          "type": "number",
-          "model": "writeBehindFlushThreadCount",
-          "hide": "!backupItem.writeBehindEnabled",
-          "placeholder": 1,
-          "tip": [
-            "Number of threads that will perform cache flushing."
-          ]
-        }
-      ]
-    }
-  ]
-}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/web-control-center/src/main/js/controllers/models/clusters.json
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/controllers/models/clusters.json b/modules/web-control-center/src/main/js/controllers/models/clusters.json
deleted file mode 100644
index 36d0dd8..0000000
--- a/modules/web-control-center/src/main/js/controllers/models/clusters.json
+++ /dev/null
@@ -1,909 +0,0 @@
-{
-  "screenTip": {
-    "workflowTitle": "Use clusters view to:",
-    "workflowContent": [
-      "<ul>",
-      "  <li>Configure clusters.</li>",
-      "  <li>Associate clusters with caches.</li>",
-      "</ul>"
-    ],
-    "whatsNextTitle": "What's next:",
-    "whatsNextContent": [
-      "<ul>",
-      "  <li>Configure cache type metadata.</li>",
-      "  <li>Configure caches.</li>",
-      "  <li>Generate XML and java code on Summary view.</li>",
-      "</ul>"
-    ]
-  },
-  "templateTip": [
-    "Use following template to add a new cluster:",
-    "<ul>",
-    "  <li>multicast - cluster with multicast discovery.</li>",
-    "  <li>local - cluster with static ips discovery and pre-configured list of IP addresses.</li>",
-    "</ul>"
-  ],
-  "general": [
-    {
-      "label": "Name",
-      "type": "text",
-      "model": "name",
-      "required": true,
-      "placeholder": "Input name",
-      "id": "defaultFocusId"
-    },
-    {
-      "label": "Caches",
-      "type": "dropdown-multiple",
-      "model": "caches",
-      "placeholder": "Choose caches",
-      "items": "caches",
-      "tip": [
-        "Select caches to start in cluster or add a new cache."
-      ],
-      "addLink": {
-        "label": "Add cache(s)",
-        "ref": "/configuration/caches"
-      }
-    },
-    {
-      "label": "Discovery",
-      "type": "dropdown-details",
-      "path": "discovery",
-      "model": "kind",
-      "required": true,
-      "placeholder": "Choose discovery",
-      "items": "discoveries",
-      "tip": [
-        "Discovery allows to discover remote nodes in grid."
-      ],
-      "details": {
-        "Vm": {
-          "expanded": true,
-          "fields": [
-            {
-              "type": "table-simple",
-              "path": "discovery.Vm",
-              "model": "addresses",
-              "editIdx": -1,
-              "reordering": true,
-              "ipaddress": true,
-              "placeholder": "IP address:port",
-              "focusNewItemId": "newIpAddress",
-              "focusCurItemId": "curIpAddress",
-              "addTip": "Add new address.",
-              "removeTip": "Remove address.",
-              "tip": [
-                "Addresses may be represented as follows:",
-                "<ul>",
-                "  <li>IP address (e.g. 127.0.0.1, 9.9.9.9, etc);</li>",
-                "  <li>IP address and port (e.g. 127.0.0.1:47500, 9.9.9.9:47501, etc);</li>",
-                "  <li>IP address and port range (e.g. 127.0.0.1:47500..47510, 9.9.9.9:47501..47504, etc);</li>",
-                "  <li>Hostname (e.g. host1.com, host2, etc);</li>",
-                "  <li>Hostname and port (e.g. host1.com:47500, host2:47502, etc).</li>",
-                "  <li>Hostname and port range (e.g. host1.com:47500..47510, host2:47502..47508, etc).</li>",
-                "</ul>",
-                "If port is 0 or not provided then default port will be used (depends on discovery SPI configuration).",
-                "If port range is provided (e.g. host:port1..port2) the following should be considered:",
-                "<ul>",
-                "  <li>port1 < port2 should be true;</li>",
-                "  <li>Both port1 and port2 should be greater than 0.</li>",
-                "</ul>"
-              ]
-            }
-          ]
-        },
-        "Multicast": {
-          "expanded": false,
-          "fields": [
-            {
-              "label": "IP address",
-              "type": "text",
-              "path": "discovery.Multicast",
-              "model": "multicastGroup",
-              "placeholder": "228.1.2.4",
-              "tip": [
-                "IP address of multicast group."
-              ]
-            },
-            {
-              "label": "Port number",
-              "type": "number",
-              "path": "discovery.Multicast",
-              "model": "multicastPort",
-              "max": 65535,
-              "placeholder": 47400,
-              "tip": [
-                "Port number which multicast messages are sent to."
-              ]
-            },
-            {
-              "label": "Waits for reply",
-              "type": "number",
-              "path": "discovery.Multicast",
-              "model": "responseWaitTime",
-              "placeholder": 500,
-              "tip": [
-                "Time in milliseconds IP finder waits for reply to multicast address request."
-              ]
-            },
-            {
-              "label": "Attempts count",
-              "type": "number",
-              "path": "discovery.Multicast",
-              "model": "addressRequestAttempts",
-              "placeholder": 2,
-              "tip": [
-                "Number of attempts to send multicast address request.",
-                "IP finder re-sends request only in case if no reply for previous request is received."
-              ]
-            },
-            {
-              "label": "Local address",
-              "type": "text",
-              "path": "discovery.Multicast",
-              "model": "localAddress",
-              "tip": [
-                "Local host address used by this IP finder.",
-                "If provided address is non-loopback then multicast socket is bound to this interface.",
-                "If local address is not set or is any local address then IP finder creates multicast sockets for all found non-loopback addresses."
-              ]
-            }
-          ]
-        },
-        "S3": {
-          "expanded": true,
-          "fields": [
-            {
-              "label": "Bucket name",
-              "type": "text",
-              "required": true,
-              "path": "discovery.S3",
-              "model": "bucketName",
-              "tip": [
-                "Bucket name for IP finder."
-              ]
-            },
-            {
-              "label": "Note, AWS credentials will be generated as stubs.",
-              "type": "label"
-            }
-          ]
-        },
-        "Cloud": {
-          "expanded": true,
-          "fields": [
-            {
-              "label": "Credential",
-              "type": "text",
-              "path": "discovery.Cloud",
-              "model": "credential",
-              "tip": [
-                "Credential that is used during authentication on the cloud.",
-                "Depending on a cloud platform it can be a password or access key."
-              ]
-            },
-            {
-              "label": "Path to credential",
-              "type": "text",
-              "path": "discovery.Cloud",
-              "model": "credentialPath",
-              "tip": [
-                "Path to a credential that is used during authentication on the cloud.",
-                "Access key or private key should be stored in a plain or PEM file without a passphrase."
-              ]
-            },
-            {
-              "label": "Identity",
-              "type": "text",
-              "required": true,
-              "path": "discovery.Cloud",
-              "model": "identity",
-              "tip": [
-                "Identity that is used as a user name during a connection to the cloud.",
-                "Depending on a cloud platform it can be an email address, user name, etc."
-              ]
-            },
-            {
-              "label": "Provider",
-              "type": "text",
-              "required": true,
-              "path": "discovery.Cloud",
-              "model": "provider",
-              "tip": [
-                "Cloud provider to use."
-              ]
-            },
-            {
-              "label": "Regions",
-              "type": "table-simple",
-              "path": "discovery.Cloud",
-              "model": "regions",
-              "editIdx": -1,
-              "focusNewItemId": "newRegion",
-              "focusCurItemId": "curRegion",
-              "addTip": "Add new region.",
-              "removeTip": "Remove region.",
-              "tableTip": [
-                "List of regions where VMs are located.",
-                "If the regions are not set then every region, that a cloud provider has, will be investigated. This could lead to significant performance degradation.",
-                "Note, that some cloud providers, like Google Compute Engine, doesn't have a notion of a region. For such providers a call to this method is redundant."
-              ],
-              "tip": [
-                "Region where VMs are located."
-              ]
-            },
-            {
-              "label": "Zones",
-              "type": "table-simple",
-              "path": "discovery.Cloud",
-              "model": "zones",
-              "editIdx": -1,
-              "focusNewItemId": "newZone",
-              "focusCurItemId": "curZone",
-              "addTip": "Add new zone.",
-              "removeTip": "Remove zone.",
-              "tableTip": [
-                "List of zones where VMs are located.",
-                "If the zones are not set then every zone from regions, set by {@link #setRegions(Collection)}}, will be taken into account.",
-                "Note, that some cloud providers, like Rackspace, doesn't have a notion of a zone. For such providers a call to this method is redundant."
-              ],
-              "tip": [
-                "Zone where VMs are located."
-              ]
-            }
-          ]
-        },
-        "GoogleStorage": {
-          "expanded": true,
-          "fields": [
-            {
-              "label": "Project name",
-              "type": "text",
-              "required": true,
-              "path": "discovery.GoogleStorage",
-              "model": "projectName",
-              "tip": [
-                "Google Cloud Platforms project name.",
-                "Usually this is an auto generated project number (ex. 208709979073) that can be found in 'Overview' section of Google Developer Console."
-              ]
-            },
-            {
-              "label": "Bucket name",
-              "type": "text",
-              "required": true,
-              "path": "discovery.GoogleStorage",
-              "model": "bucketName",
-              "tip": [
-                "Google Cloud Storage bucket name.",
-                "If the bucket doesn't exist Ignite will automatically create it.",
-                "However the name must be unique across whole Google Cloud Storage and Service Account Id must be authorized to perform this operation."
-              ]
-            },
-            {
-              "label": "Private key path",
-              "type": "text",
-              "required": true,
-              "path": "discovery.GoogleStorage",
-              "model": "serviceAccountP12FilePath",
-              "tip": [
-                "Full path to the private key in PKCS12 format of the Service Account."
-              ]
-            },
-            {
-              "label": "Account id",
-              "type": "text",
-              "required": true,
-              "path": "discovery.GoogleStorage",
-              "model": "accountId",
-              "tip": [
-                "Service account ID (typically an e-mail address)."
-              ]
-            }
-          ]
-        },
-        "Jdbc": {
-          "expanded": true,
-          "fields": [
-            {
-              "label": "DB schema should be initialized by Ignite",
-              "type": "check",
-              "path": "discovery.Jdbc",
-              "model": "initSchema",
-              "tip": [
-                "Flag indicating whether DB schema should be initialized by Ignite or was explicitly created by user."
-              ]
-            }
-          ]
-        },
-        "SharedFs": {
-          "expanded": false,
-          "fields": [
-            {
-              "label": "File path",
-              "type": "text",
-              "path": "discovery.SharedFs",
-              "model": "path",
-              "placeholder": "disco/tcp"
-            }
-          ]
-        }
-      }
-    }
-  ],
-  "advanced": [
-    {
-      "label": "Atomics configuration",
-      "tip": [
-        "Configuration for atomic data structures.",
-        "Atomics are distributed across the cluster, essentially enabling performing atomic operations (such as increment-and-get or compare-and-set) with the same globally-visible value."
-      ],
-      "fields": [
-        {
-          "label": "Backups",
-          "type": "number",
-          "path": "atomicConfiguration",
-          "model": "backups",
-          "placeholder": 0,
-          "tip": [
-            "Number of backup nodes."
-          ]
-        },
-        {
-          "label": "Cache mode",
-          "type": "dropdown",
-          "path": "atomicConfiguration",
-          "model": "cacheMode",
-          "placeholder": "PARTITIONED",
-          "items": "cacheModes",
-          "tip": [
-            "Cache modes:",
-            "<ul>",
-            "  <li>Partitioned - in this mode the overall key set will be divided into partitions and all partitions will be split equally between participating nodes.</li>",
-            "  <li>Replicated - in this mode all the keys are distributed to all participating nodes.</li>",
-            "  <li>Local - in this mode caches residing on different grid nodes will not know about each other.</li>",
-            "</ul>"
-          ]
-        },
-        {
-          "label": "Sequence reserve",
-          "type": "number",
-          "path": "atomicConfiguration",
-          "model": "atomicSequenceReserveSize",
-          "placeholder": 1000,
-          "tip": [
-            "Default number of sequence values reserved for IgniteAtomicSequence instances.",
-            "After a certain number has been reserved, consequent increments of sequence will happen locally, without communication with other nodes, until the next reservation has to be made."
-          ]
-        }
-      ]
-    },
-    {
-      "label": "Communication",
-      "tip": [
-        "Cluster communication network properties."
-      ],
-      "fields": [
-        {
-          "label": "Timeout",
-          "type": "number",
-          "model": "networkTimeout",
-          "placeholder": 5000,
-          "tip": [
-            "Maximum timeout in milliseconds for network requests."
-          ]
-        },
-        {
-          "label": "Send retry delay",
-          "type": "number",
-          "model": "networkSendRetryDelay",
-          "placeholder": 1000,
-          "tip": [
-            "Interval in milliseconds between message send retries."
-          ]
-        },
-        {
-          "label": "Send retry count",
-          "type": "number",
-          "model": "networkSendRetryCount",
-          "placeholder": 3,
-          "tip": [
-            "Message send retries count."
-          ]
-        },
-        {
-          "label": "Segment check frequency",
-          "type": "number",
-          "model": "segmentCheckFrequency",
-          "placeholder": 10000,
-          "tip": [
-            "Network segment check frequency in milliseconds.",
-            "If 0, periodic segment check is disabled and segment is checked only on topology changes (if segmentation resolvers are configured)."
-          ]
-        },
-        {
-          "label": "Wait for segment on start",
-          "type": "check",
-          "model": "waitForSegmentOnStart",
-          "tip": [
-            "Wait for segment on start flag.",
-            "<ul>",
-            "  <li>If enabled, node should wait for correct segment on start.</li>",
-            "  <li>If node detects that segment is incorrect on startup and enabled, node waits until segment becomes correct.</li>",
-            "  <li>If segment is incorrect on startup and disabled, exception is thrown.</li>",
-            "</ul>"
-          ]
-        },
-        {
-          "label": "Discovery startup delay",
-          "type": "number",
-          "model": "discoveryStartupDelay",
-          "placeholder": 600000,
-          "tip": [
-            "This value is used to expire messages from waiting list whenever node discovery discrepancies happen."
-          ]
-        }
-      ]
-    },
-    {
-      "label": "Deployment",
-      "tip": [
-        "Task and resources deployment in cluster."
-      ],
-      "fields": [
-        {
-          "label": "Mode",
-          "type": "dropdown",
-          "model": "deploymentMode",
-          "placeholder": "SHARED",
-          "items": "deploymentModes",
-          "tip": [
-            "Task classes and resources sharing mode."
-          ]
-        }
-      ]
-    },
-    {
-      "label": "Events",
-      "tip": [
-        " Grid events are used for notification about what happens within the grid."
-      ],
-      "fields": [
-        {
-          "label": "Include type",
-          "type": "dropdown-multiple",
-          "model": "includeEventTypes",
-          "placeholder": "Choose recorded event types",
-          "items": "events",
-          "tip": [
-            "Array of event types, which will be recorded by GridEventStorageManager#record(Event).",
-            "Note, that either the include event types or the exclude event types can be established."
-          ]
-        }
-      ]
-    },
-    {
-      "label": "Marshaller",
-      "tip": [
-        "Marshaller allows to marshal or unmarshal objects in grid.",
-        "It provides serialization/deserialization mechanism for all instances that are sent across networks or are otherwise serialized."
-      ],
-      "fields": [
-        {
-          "label": "Marshaller",
-          "type": "dropdown-details",
-          "path": "marshaller",
-          "model": "kind",
-          "placeholder": "Choose marshaller",
-          "items": "marshallers",
-          "tip": [
-            "Instance of marshaller to use in grid. If not provided, OptimizedMarshaller will be used on Java HotSpot VM, and JdkMarshaller will be used on other VMs."
-          ],
-          "details": {
-            "OptimizedMarshaller": {
-              "expanded": false,
-              "fields": [
-                {
-                  "label": "Streams pool size",
-                  "type": "number",
-                  "path": "marshaller.OptimizedMarshaller",
-                  "model": "poolSize",
-                  "placeholder": 0,
-                  "tip": [
-                    "Specifies size of cached object streams used by marshaller.",
-                    "Object streams are cached for performance reason to avoid costly recreation for every serialization routine.",
-                    "If 0 (default), pool is not used and each thread has its own cached object stream which it keeps reusing.",
-                    "Since each stream has an internal buffer, creating a stream for each thread can lead to high memory consumption if many large messages are marshalled or unmarshalled concurrently.",
-                    "Consider using pool in this case. This will limit number of streams that can be created and, therefore, decrease memory consumption.",
-                    "NOTE: Using streams pool can decrease performance since streams will be shared between different threads which will lead to more frequent context switching."
-                  ]
-                },
-                {
-                  "label": "Require serializable",
-                  "type": "check",
-                  "path": "marshaller.OptimizedMarshaller",
-                  "model": "requireSerializable",
-                  "tip": [
-                    "Whether marshaller should require Serializable interface or not."
-                  ]
-                }
-              ]
-            }
-          }
-        },
-        {
-          "label": "Marshal local jobs",
-          "type": "check",
-          "model": "marshalLocalJobs",
-          "placeholder": "false",
-          "tip": [
-            "If this flag is enabled, jobs mapped to local node will be marshalled as if it was remote node."
-          ]
-        },
-        {
-          "label": "Keep alive time",
-          "type": "number",
-          "model": "marshallerCacheKeepAliveTime",
-          "placeholder": 10000,
-          "tip": [
-            "Keep alive time of thread pool that is in charge of processing marshaller messages."
-          ]
-        },
-        {
-          "label": "Pool size",
-          "type": "number",
-          "model": "marshallerCacheThreadPoolSize",
-          "placeholder": "max(8, availableProcessors) * 2",
-          "tip": [
-            "Default size of thread pool that is in charge of processing marshaller messages."
-          ]
-        }
-      ]
-    },
-    {
-      "label": "Metrics",
-      "tip": [
-        "Cluster runtime metrics settings."
-      ],
-      "fields": [
-        {
-          "label": "Elapsed time",
-          "type": "number",
-          "model": "metricsExpireTime",
-          "placeholder": "Long.MAX_VALUE",
-          "min": 1,
-          "tip": [
-            "Time in milliseconds after which a certain metric value is considered expired."
-          ]
-        },
-        {
-          "label": "History size",
-          "type": "number",
-          "model": "metricsHistorySize",
-          "placeholder": 10000,
-          "min": 1,
-          "tip": [
-            "Number of metrics kept in history to compute totals and averages."
-          ]
-        },
-        {
-          "label": "Log frequency",
-          "type": "number",
-          "model": "metricsLogFrequency",
-          "placeholder": 60000,
-          "tip": [
-            "Frequency of metrics log print out. To disable set to 0"
-          ]
-        },
-        {
-          "label": "Update frequency",
-          "type": "number",
-          "model": "metricsUpdateFrequency",
-          "placeholder": 60000,
-          "tip": [
-            "Job metrics update frequency in milliseconds.",
-            "<ul>",
-            "  <li>If set to -1 job metrics are never updated.</li>",
-            "  <li>If set to 0 job metrics are updated on each job start and finish.</li>",
-            "  <li>Positive value defines the actual update frequency.</li>",
-            "</ul>"
-          ]
-        }
-      ]
-    },
-    {
-      "label": "Peer Class Loading",
-      "tip": [
-        "Cluster peer class loading settings."
-      ],
-      "fields": [
-        {
-          "label": "Enable peer class loading",
-          "type": "check",
-          "model": "peerClassLoadingEnabled",
-          "tip": [
-            "Enables/disables peer class loading."
-          ]
-        },
-        {
-          "label": "Local class path exclude",
-          "type": "text",
-          "model": "peerClassLoadingLocalClassPathExclude",
-          "placeholder": "[]",
-          "tip": [
-            "List of packages separated by comma from the system classpath that need to be peer-to-peer loaded from task originating node.",
-            "'*' is supported at the end of the package name which means that all sub-packages and their classes are included like in Java package import clause."
-          ]
-        },
-        {
-          "label": "Missed resources cache size",
-          "type": "number",
-          "model": "peerClassLoadingMissedResourcesCacheSize",
-          "placeholder": 100,
-          "tip": [
-            "If size greater than 0, missed resources will be cached and next resource request ignored.",
-            "If size is 0, then request for the resource will be sent to the remote node every time this resource is requested."
-          ]
-        },
-        {
-          "label": "Pool size",
-          "type": "number",
-          "model": "peerClassLoadingThreadPoolSize",
-          "placeholder": "availableProcessors",
-          "tip": [
-            "Thread pool size to use for peer class loading."
-          ]
-        }
-      ]
-    },
-    {
-      "label": "Swap",
-      "tip": [
-        "Settings for overflow data to disk if it cannot fit in memory."
-      ],
-      "fields": [
-        {
-          "label": "Swap space SPI",
-          "type": "dropdown-details",
-          "path": "swapSpaceSpi",
-          "model": "kind",
-          "items": "swapSpaceSpis",
-          "placeholder": "Choose swap SPI",
-          "tip": [
-            "Provides a mechanism in grid for storing data on disk.",
-            "Ignite cache uses swap space to overflow data to disk if it cannot fit in memory."
-          ],
-          "details": {
-            "FileSwapSpaceSpi": {
-              "fields": [
-                {
-                  "label": "Base directory",
-                  "type": "text",
-                  "path": "swapSpaceSpi.FileSwapSpaceSpi",
-                  "model": "baseDirectory",
-                  "placeholder": "swapspace",
-                  "tip": [
-                    "Base directory where to write files."
-                  ]
-                },
-                {
-                  "label": "Read stripe size",
-                  "type": "number",
-                  "path": "swapSpaceSpi.FileSwapSpaceSpi",
-                  "model": "readStripesNumber",
-                  "placeholder": "available CPU cores",
-                  "tip": [
-                    "Read stripe size defines number of file channels to be used concurrently."
-                  ]
-                },
-                {
-                  "label": "Maximum sparsity",
-                  "type": "number",
-                  "path": "swapSpaceSpi.FileSwapSpaceSpi",
-                  "model": "maximumSparsity",
-                  "placeholder": 0.5,
-                  "tip": [
-                    "This property defines maximum acceptable wasted file space to whole file size ratio.",
-                    "When this ratio becomes higher than specified number compacting thread starts working."
-                  ]
-                },
-                {
-                  "label": "Max write queue size",
-                  "type": "number",
-                  "path": "swapSpaceSpi.FileSwapSpaceSpi",
-                  "model": "maxWriteQueueSize",
-                  "placeholder": "1024 * 1024",
-                  "tip": [
-                    "Max write queue size in bytes.",
-                    "If there are more values are waiting for being written to disk then specified size, SPI will block on store operation."
-                  ]
-                },
-                {
-                  "label": "Write buffer size",
-                  "type": "number",
-                  "path": "swapSpaceSpi.FileSwapSpaceSpi",
-                  "model": "writeBufferSize",
-                  "placeholder": "Available CPU cores",
-                  "tip": [
-                    "Write buffer size in bytes.",
-                    "Write to disk occurs only when this buffer is full."
-                  ]
-                }
-              ]
-            }
-          }
-        }
-      ]
-    },
-    {
-      "label": "Time configuration",
-      "tip": [
-        "Time settings for CLOCK write ordering mode."
-      ],
-      "fields": [
-        {
-          "label": "Samples size",
-          "type": "number",
-          "model": "clockSyncSamples",
-          "placeholder": 8,
-          "tip": [
-            "Number of samples used to synchronize clocks between different nodes.",
-            "Clock synchronization is used for cache version assignment in CLOCK order mode."
-          ]
-        },
-        {
-          "label": "Frequency",
-          "type": "number",
-          "model": "clockSyncFrequency",
-          "placeholder": 120000,
-          "tip": [
-            "Frequency at which clock is synchronized between nodes, in milliseconds.",
-            "Clock synchronization is used for cache version assignment in CLOCK order mode."
-          ]
-        },
-        {
-          "label": "Port base",
-          "type": "number",
-          "model": "timeServerPortBase",
-          "max": 65535,
-          "placeholder": 31100,
-          "tip": [
-            "Time server provides clock synchronization between nodes.",
-            "Base UPD port number for grid time server. Time server will be started on one of free ports in range."
-          ]
-        },
-        {
-          "label": "Port range",
-          "type": "number",
-          "model": "timeServerPortRange",
-          "placeholder": 100,
-          "tip": [
-            "Time server port range."
-          ]
-        }
-      ]
-    },
-    {
-      "label": "Thread pools size",
-      "tip": [
-        "Settings for node thread pools."
-      ],
-      "fields": [
-        {
-          "label": "Public",
-          "type": "number",
-          "model": "publicThreadPoolSize",
-          "placeholder": "max(8, availableProcessors) * 2",
-          "tip": [
-            "Thread pool that is in charge of processing ComputeJob, GridJobs and user messages sent to node."
-          ]
-        },
-        {
-          "label": "System",
-          "type": "number",
-          "model": "systemThreadPoolSize",
-          "placeholder": "max(8, availableProcessors) * 2",
-          "tip": [
-            "Thread pool that is in charge of processing internal system messages."
-          ]
-        },
-        {
-          "label": "Management",
-          "type": "number",
-          "model": "managementThreadPoolSize",
-          "placeholder": 4,
-          "tip": [
-            "Thread pool that is in charge of processing internal and Visor ComputeJob, GridJobs."
-          ]
-        },
-        {
-          "label": "IGFS",
-          "type": "number",
-          "model": "igfsThreadPoolSize",
-          "placeholder": "availableProcessors",
-          "tip": [
-            "Thread pool that is in charge of processing outgoing IGFS messages."
-          ]
-        }
-      ]
-    },
-    {
-      "label": "Transactions",
-      "tip": [
-        "Settings for transactions."
-      ],
-      "fields": [
-        {
-          "label": "Concurrency",
-          "type": "dropdown",
-          "path": "transactionConfiguration",
-          "model": "defaultTxConcurrency",
-          "placeholder": "PESSIMISTIC",
-          "items": "transactionConcurrency",
-          "tip": [
-            "Cache transaction concurrency to use when one is not explicitly specified."
-          ]
-        },
-        {
-          "label": "Isolation",
-          "type": "dropdown",
-          "path": "transactionConfiguration",
-          "model": "transactionIsolation",
-          "placeholder": "REPEATABLE_READ",
-          "items": "transactionIsolation",
-          "tip": [
-            "Default transaction isolation."
-          ]
-        },
-        {
-          "label": "Default timeout",
-          "type": "number",
-          "path": "transactionConfiguration",
-          "model": "defaultTxTimeout",
-          "placeholder": 0,
-          "tip": [
-            "Default transaction timeout."
-          ]
-        },
-        {
-          "label": "Pessimistic log cleanup delay",
-          "type": "number",
-          "path": "transactionConfiguration",
-          "model": "pessimisticTxLogLinger",
-          "placeholder": 10000,
-          "tip": [
-            "Delay, in milliseconds, after which pessimistic recovery entries will be cleaned up for failed node."
-          ]
-        },
-        {
-          "label": "Pessimistic log size",
-          "type": "number",
-          "path": "transactionConfiguration",
-          "model": "pessimisticTxLogSize",
-          "placeholder": 0,
-          "tip": [
-            "Size of pessimistic transactions log stored on node in order to recover transaction commit if originating node has left grid before it has sent all messages to transaction nodes."
-          ]
-        },
-        {
-          "label": "Manager lookup",
-          "type": "text",
-          "model": "txManagerLookupClassName",
-          "tip": [
-            "Class name of transaction manager finder for integration for JEE app servers."
-          ]
-        },
-        {
-          "label": "Enable serializable cache transactions",
-          "type": "check",
-          "path": "transactionConfiguration",
-          "model": "txSerializableEnabled",
-          "tip": [
-            "Flag to enable/disable isolation level for cache transactions.",
-            "Serializable level does carry certain overhead and if not used, should be disabled."
-          ]
-        }
-      ]
-    }
-  ]
-}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/web-control-center/src/main/js/controllers/models/metadata.json
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/controllers/models/metadata.json b/modules/web-control-center/src/main/js/controllers/models/metadata.json
deleted file mode 100644
index a9b60de..0000000
--- a/modules/web-control-center/src/main/js/controllers/models/metadata.json
+++ /dev/null
@@ -1,252 +0,0 @@
-{
-  "screenTip": {
-    "workflowTitle": "Use metadata view to:",
-    "workflowContent": [
-      "<ul>",
-      "  <li>Manually configure metadata for queries and persistence.</li>",
-      "Or",
-      "  <li>Automatically configure metadata from database schema.</li>",
-      "</ul>"
-    ],
-    "whatsNextTitle": "What's next:",
-    "whatsNextContent": [
-      "<ul>",
-      "  <li>Associate caches with metadata.</li>",
-      "  <li>Generate XML and java code on Summary view.</li>",
-      "</ul>"
-    ]
-  },
-  "templateTip": [
-    "Use following template for metadata:",
-    "<ul>",
-    "  <li>query - Create cache type metadata to use with queries only.</li>",
-    "  <li>store - Create cache type metadata to use with JDBC POJO store only.</li>",
-    "  <li>both - Create cache type metadata to use with query and store.</li>",
-    "</ul>"
-  ],
-  "metadataManual": [
-    {
-      "label": "Name",
-      "type": "text",
-      "model": "name",
-      "required": true,
-      "placeholder": "Input name",
-      "id": "defaultFocusId"
-    },
-    {
-      "label": "Metadata for",
-      "type": "dropdown",
-      "model": "kind",
-      "items": "kinds",
-      "tip": [
-        "Use following template for metadata:",
-        "<ul>",
-        "  <li>query - Create cache type metadata to use with queries only.</li>",
-        "  <li>store - Create cache type metadata to use with JDBC POJO store only.</li>",
-        "  <li>both - Create cache type metadata to use with query and store.</li>",
-        "</ul>"
-      ]
-    },
-    {
-      "label": "Database schema",
-      "type": "text",
-      "model": "databaseSchema",
-      "hide": "backupItem.kind != 'both' && backupItem.kind == 'query'",
-      "placeholder": "Input DB schema name",
-      "tip": [
-        "Schema name in database."
-      ]
-    },
-    {
-      "label": "Database table",
-      "type": "text",
-      "model": "databaseTable",
-      "hide": "backupItem.kind != 'both' && backupItem.kind == 'query'",
-      "placeholder": "Input DB table name",
-      "tip": [
-        "Table name in database."
-      ]
-    },
-    {
-      "label": "Key type",
-      "type": "withJavaBuildInTypes",
-      "model": "keyType",
-      "required": true,
-      "placeholder": "Full class name for Key",
-      "tip": [
-        "Key class used to store key in cache."
-      ]
-    },
-    {
-      "label": "Value type",
-      "type": "text",
-      "model": "valueType",
-      "required": true,
-      "placeholder": "Full class name for Value",
-      "tip": [
-        "Value class used to store value in cache."
-      ]
-    },
-    {
-      "label": "Key fields",
-      "type": "dbFields",
-      "model": "keyFields",
-      "keyName": "name",
-      "valueName": "className",
-      "hide": "backupItem.kind != 'both' && backupItem.kind == 'query'",
-      "addTip": "Add key field.",
-      "removeTip": "Remove key field.",
-      "tip": [
-        "Collection of key fields descriptions for CacheJdbcPojoStore."
-      ]
-    },
-    {
-      "label": "Value fields",
-      "type": "dbFields",
-      "model": "valueFields",
-      "keyName": "name",
-      "valueName": "className",
-      "hide": "backupItem.kind != 'both' && backupItem.kind == 'query'",
-      "addTip": "Add value field.",
-      "removeTip": "Remove value field.",
-      "tip": [
-        "Collection of value fields descriptions for CacheJdbcPojoStore.."
-      ]
-    },
-    {
-      "label": "Query fields",
-      "type": "queryFields",
-      "model": "queryFields",
-      "keyName": "name",
-      "valueName": "className",
-      "hide": "backupItem.kind != 'both' && backupItem.kind != 'query'",
-      "focusNewItemId": "newQryField",
-      "focusCurItemId": "curQryField",
-      "addTip": "Add field to query.",
-      "removeTip": "Remove field.",
-      "tip": [
-        "Collection of name-to-type mappings to be queried, in addition to indexed fields."
-      ]
-    },
-    {
-      "label": "Ascending fields",
-      "type": "queryFields",
-      "model": "ascendingFields",
-      "keyName": "name",
-      "valueName": "className",
-      "hide": "backupItem.kind != 'both' && backupItem.kind != 'query'",
-      "focusNewItemId": "newAscField",
-      "focusCurItemId": "curAscField",
-      "addTip": "Add field to index in ascending order.",
-      "removeTip": "Remove field.",
-      "tip": [
-        "Collection of name-to-type mappings to index in ascending order."
-      ]
-    },
-    {
-      "label": "Descending fields",
-      "type": "queryFields",
-      "model": "descendingFields",
-      "keyName": "name",
-      "valueName": "className",
-      "hide": "backupItem.kind != 'both' && backupItem.kind != 'query'",
-      "focusNewItemId": "newDescField",
-      "focusCurItemId": "curDescField",
-      "addTip": "Add field to index in descending order.",
-      "removeTip": "Remove field.",
-      "tip": [
-        "Collection of name-to-type mappings to index in descending order."
-      ]
-    },
-    {
-      "label": "Text fields",
-      "type": "table-simple",
-      "model": "textFields",
-      "hide": "backupItem.kind != 'both' && backupItem.kind != 'query'",
-      "placeholder": "Field name",
-      "focusNewItemId": "newTextField",
-      "focusCurItemId": "curTextField",
-      "addTip": "Add field to index as text.",
-      "removeTip": "Remove field.",
-      "tableTip": [
-        "Fields to index as text."
-      ],
-      "tip": [
-        "Field to index as text."
-      ]
-    },
-    {
-      "label": "Groups",
-      "type": "queryGroups",
-      "model": "groups",
-      "hide": "backupItem.kind != 'both' && backupItem.kind != 'query'",
-      "addTip": "Add new group.",
-      "removeTip": "Remove group.",
-      "addItemTip": "Add new field to group.",
-      "removeItemTip": "Remove field from group.",
-      "tip": [
-        "Collection of group indexes."
-      ]
-    }
-  ],
-  "metadataDb": [
-    {
-      "label": "Name",
-      "type": "text",
-      "model": "name"
-    },
-    {
-      "label": "Database type",
-      "type": "dropdown",
-      "model": "rdbms",
-      "placeholder": "Choose database",
-      "items": "databases",
-      "tip": [
-        "Select database type to connect for loading tables metadata."
-      ]
-    },
-    {
-      "label": "Database name",
-      "type": "text",
-      "model": "dbName",
-      "tip": [
-        "Database name to connect for loading tables metadata."
-      ]
-    },
-    {
-      "label": "Host",
-      "type": "text",
-      "model": "host",
-      "placeholder": "IP address or host",
-      "tip": [
-        "IP address or host name where database server deployed."
-      ]
-    },
-    {
-      "label": "Port",
-      "type": "number",
-      "model": "port",
-      "max": 65535,
-      "tip": [
-        "Port number for connecting to database."
-      ]
-    },
-    {
-      "label": "User",
-      "type": "text",
-      "model": "user",
-      "tip": [
-        "User name for connecting to database."
-      ]
-    },
-    {
-      "label": "Password",
-      "type": "password",
-      "model": "password",
-      "tip": [
-        "Password for connecting to database.",
-        "Note, password would not be saved."
-      ]
-    }
-  ]
-}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/web-control-center/src/main/js/controllers/models/sql.json
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/controllers/models/sql.json b/modules/web-control-center/src/main/js/controllers/models/sql.json
deleted file mode 100644
index bcb03e0..0000000
--- a/modules/web-control-center/src/main/js/controllers/models/sql.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
-  "screenTip": [
-    "Select cache and execute SQL queries."
-  ]
-}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/web-control-center/src/main/js/controllers/models/summary.json
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/controllers/models/summary.json b/modules/web-control-center/src/main/js/controllers/models/summary.json
deleted file mode 100644
index 29edb3d..0000000
--- a/modules/web-control-center/src/main/js/controllers/models/summary.json
+++ /dev/null
@@ -1,163 +0,0 @@
-{
-  "screenTip": {
-    "workflowTitle": "Use summary view to:",
-    "workflowContent": [
-      "<ul>",
-      "  <li>See XML and java code for server nodes configurations.</li>",
-      "  <li>See XML and java code for client nodes configurations.</li>",
-      "</ul>"
-    ],
-    "whatsNextTitle": "What's next:",
-    "whatsNextContent": [
-      "<ul>",
-      "  <li>Download XML or java code configuration.</li>",
-      "  <li>Start Ignite cluster with downloaded configuration.</li>",
-      "</ul>"
-    ]
-  },
-  "clientFields": [
-    {
-      "label": "Near cache start size",
-      "type": "number",
-      "path": "nearConfiguration",
-      "model": "nearStartSize",
-      "placeholder": 375000,
-      "tip": [
-        "Initial cache size for near cache which will be used to pre-create internal hash table after start."
-      ]
-    },
-    {
-      "label": "Near cache eviction policy",
-      "type": "dropdown-details",
-      "path": "nearConfiguration.nearEvictionPolicy",
-      "model": "kind",
-      "placeholder": "Choose eviction policy",
-      "items": "evictionPolicies",
-      "tip": [
-        "Cache expiration policy."
-      ],
-      "details": {
-        "LRU": {
-          "expanded": false,
-          "fields": [
-            {
-              "label": "Batch size",
-              "type": "number",
-              "path": "nearConfiguration.nearEvictionPolicy.LRU",
-              "model": "batchSize",
-              "placeholder": 1,
-              "tip": [
-                "Number of entries to remove on shrink."
-              ]
-            },
-            {
-              "label": "Max memory size",
-              "type": "number",
-              "path": "nearConfiguration.nearEvictionPolicy.LRU",
-              "model": "maxMemorySize",
-              "placeholder": 0,
-              "tip": [
-                "Maximum allowed cache size in bytes."
-              ]
-            },
-            {
-              "label": "Max size",
-              "type": "number",
-              "path": "nearConfiguration.nearEvictionPolicy.LRU",
-              "model": "maxSize",
-              "placeholder": 100000,
-              "tip": [
-                "Maximum allowed size of cache before entry will start getting evicted."
-              ]
-            }
-          ]
-        },
-        "RND": {
-          "expanded": false,
-          "fields": [
-            {
-              "label": "Max size",
-              "type": "number",
-              "path": "nearConfiguration.nearEvictionPolicy.RND",
-              "model": "maxSize",
-              "placeholder": 100000,
-              "tip": [
-                "Maximum allowed size of cache before entry will start getting evicted."
-              ]
-            }
-          ]
-        },
-        "FIFO": {
-          "expanded": false,
-          "fields": [
-            {
-              "label": "Batch size",
-              "type": "number",
-              "path": "nearConfiguration.nearEvictionPolicy.FIFO",
-              "model": "batchSize",
-              "placeholder": 1,
-              "tip": [
-                "Number of entries to remove on shrink."
-              ]
-            },
-            {
-              "label": "Max memory size",
-              "type": "number",
-              "path": "nearConfiguration.nearEvictionPolicy.FIFO",
-              "model": "maxMemorySize",
-              "placeholder": 0,
-              "tip": [
-                "Maximum allowed cache size in bytes."
-              ]
-            },
-            {
-              "label": "Max size",
-              "type": "number",
-              "path": "nearConfiguration.nearEvictionPolicy.FIFO",
-              "model": "maxSize",
-              "placeholder": 100000,
-              "tip": [
-                "Maximum allowed size of cache before entry will start getting evicted."
-              ]
-            }
-          ]
-        },
-        "SORTED": {
-          "expanded": false,
-          "fields": [
-            {
-              "label": "Batch size",
-              "type": "number",
-              "path": "nearConfiguration.nearEvictionPolicy.SORTED",
-              "model": "batchSize",
-              "placeholder": 1,
-              "tip": [
-                "Number of entries to remove on shrink."
-              ]
-            },
-            {
-              "label": "Max memory size",
-              "type": "number",
-              "path": "nearConfiguration.nearEvictionPolicy.SORTED",
-              "model": "maxMemorySize",
-              "placeholder": 0,
-              "tip": [
-                "Maximum allowed cache size in bytes."
-              ]
-            },
-            {
-              "label": "Max size",
-              "type": "number",
-              "path": "nearConfiguration.nearEvictionPolicy.SORTED",
-              "model": "maxSize",
-              "placeholder": 100000,
-              "tip": [
-                "Maximum allowed size of cache before entry will start getting evicted."
-              ]
-            }
-          ]
-        }
-      }
-    }
-  ]
-}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/web-control-center/src/main/js/controllers/profile-controller.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/controllers/profile-controller.js b/modules/web-control-center/src/main/js/controllers/profile-controller.js
deleted file mode 100644
index a67df63..0000000
--- a/modules/web-control-center/src/main/js/controllers/profile-controller.js
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-controlCenterModule.controller('profileController', ['$scope', '$http', '$common', function ($scope, $http, $common) {
-    $scope.profileUser = angular.copy($scope.user);
-
-    $scope.saveUser = function () {
-        var profile = $scope.profileUser;
-
-        if (profile) {
-            var userName = profile.username;
-            var changeUsername = userName != $scope.user.username;
-
-            var email = profile.email;
-            var changeEmail = email != $scope.user.email;
-
-            if (changeUsername || changeEmail || profile.changePassword) {
-                $http.post('/profile/saveUser', {
-                    _id: profile._id,
-                    userName: changeUsername ? userName : undefined,
-                    email: changeEmail ? email : undefined,
-                    newPassword: profile.changePassword ? profile.newPassword : undefined
-                }).success(function (user) {
-                    $common.showInfo('Profile saved.');
-
-                    if (changeUsername)
-                        $scope.user.username = userName;
-
-                    if (changeEmail)
-                        $scope.user.email = email;
-                }).error(function (err) {
-                    $common.showError('Failed to save profile: ' + $common.errorMessage(err));
-                });
-            }
-        }
-    };
-}]);
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/web-control-center/src/main/js/controllers/sql-controller.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/controllers/sql-controller.js b/modules/web-control-center/src/main/js/controllers/sql-controller.js
deleted file mode 100644
index 12772c6..0000000
--- a/modules/web-control-center/src/main/js/controllers/sql-controller.js
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-var demoResults = [
-    {
-        id: 256,
-        firstName: 'Ivan',
-        lastName: 'Ivanov'
-    },
-    {
-        id: 384,
-        firstName: 'Sergey',
-        lastName: 'Petrov'
-    },
-    {
-        id: 923,
-        firstName: 'Andrey',
-        lastName: 'Sidorov'
-    }
-];
-
-var demoCaches = [{_id: '1', name: 'Users', mode: 'LOCAL'}, {_id: '2', name: 'Organizations', mode: 'REPLICATED'}, {_id: '3', name: 'Cities', mode: 'PARTITIONED'}];
-
-
-
-controlCenterModule.controller('sqlController', ['$scope', '$http', '$common', function ($scope, $http, $common) {
-    $scope.joinTip = $common.joinTip;
-
-    $scope.pageSizes = [50, 100, 200, 400, 800, 1000];
-
-    $scope.tabs = [
-        {
-            query: "SELECT u.id, u.firstName, u.lastName FROM User u WHERE u.name LIKE 'aaaa'",
-            cols: Object.keys(demoResults[0]),
-            page: 1,
-            hasMore: true,
-            total: 0,
-            rows: demoResults
-        },
-        {query: "SELECT * FROM Organization"}
-    ];
-
-    $scope.addTab = function() {
-        console.log('addTab');
-
-        $scope.tabs.push({query: "SELECT "});
-    };
-
-    $scope.removeTab = function(idx) {
-        console.log('removeTab');
-
-        $scope.tabs.splice(idx, 1);
-    };
-
-    $scope.modes = [
-        {value: 'PARTITIONED', label: 'PARTITIONED'},
-        {value: 'REPLICATED', label: 'REPLICATED'},
-        {value: 'LOCAL', label: 'LOCAL'}
-    ];
-
-    $http.get('/models/sql.json')
-        .success(function (data) {
-            $scope.screenTip = data.screenTip;
-        })
-        .error(function (errMsg) {
-            $common.showError(errMsg);
-        });
-
-    $scope.caches = demoCaches;
-}]);



[39/41] incubator-ignite git commit: Merge branch 'ignite-843' of https://git-wip-us.apache.org/repos/asf/incubator-ignite into ignite-1121

Posted by an...@apache.org.
Merge branch 'ignite-843' of https://git-wip-us.apache.org/repos/asf/incubator-ignite into ignite-1121


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

Branch: refs/heads/ignite-1121
Commit: 6b621759a2fb23f0b8ab121db2e69ff74868ea05
Parents: 89220b1 9652287
Author: Andrey <an...@gridgain.com>
Authored: Wed Jul 29 13:44:13 2015 +0700
Committer: Andrey <an...@gridgain.com>
Committed: Wed Jul 29 13:44:13 2015 +0700

----------------------------------------------------------------------
 .../control-center-web/licenses/apache-2.0.txt  |  202 +++
 .../control-center-web/src/main/js/.gitignore   |    4 +
 .../control-center-web/src/main/js/DEVNOTES.txt |   21 +
 modules/control-center-web/src/main/js/app.js   |  158 +++
 modules/control-center-web/src/main/js/bin/www  |  110 ++
 .../src/main/js/config/default.json             |   17 +
 .../src/main/js/controllers/admin-controller.js |   68 +
 .../js/controllers/cache-viewer-controller.js   |   77 ++
 .../main/js/controllers/caches-controller.js    |  349 +++++
 .../main/js/controllers/clusters-controller.js  |  308 +++++
 .../src/main/js/controllers/common-module.js    |  484 +++++++
 .../main/js/controllers/metadata-controller.js  |  709 ++++++++++
 .../src/main/js/controllers/models/caches.json  |  943 +++++++++++++
 .../main/js/controllers/models/clusters.json    |  909 +++++++++++++
 .../main/js/controllers/models/metadata.json    |  252 ++++
 .../src/main/js/controllers/models/sql.json     |    5 +
 .../src/main/js/controllers/models/summary.json |  163 +++
 .../main/js/controllers/profile-controller.js   |   51 +
 .../src/main/js/controllers/sql-controller.js   |  129 ++
 .../main/js/controllers/summary-controller.js   |  170 +++
 modules/control-center-web/src/main/js/db.js    |  370 +++++
 .../src/main/js/helpers/configuration-loader.js |   22 +
 .../src/main/js/helpers/data-structures.js      |   84 ++
 .../control-center-web/src/main/js/package.json |   50 +
 .../src/main/js/public/favicon.ico              |  Bin 0 -> 1150 bytes
 .../src/main/js/public/images/docker.png        |  Bin 0 -> 994 bytes
 .../src/main/js/public/images/java.png          |  Bin 0 -> 170 bytes
 .../src/main/js/public/images/logo.png          |  Bin 0 -> 8148 bytes
 .../src/main/js/public/images/xml.png           |  Bin 0 -> 232 bytes
 .../src/main/js/public/stylesheets/style.scss   | 1270 ++++++++++++++++++
 .../src/main/js/routes/admin.js                 |   79 ++
 .../src/main/js/routes/caches.js                |  105 ++
 .../src/main/js/routes/clusters.js              |  104 ++
 .../src/main/js/routes/generator/common.js      |  312 +++++
 .../src/main/js/routes/generator/docker.js      |   58 +
 .../src/main/js/routes/generator/java.js        |  788 +++++++++++
 .../src/main/js/routes/generator/xml.js         |  736 ++++++++++
 .../src/main/js/routes/metadata.js              |   95 ++
 .../src/main/js/routes/profile.js               |   97 ++
 .../src/main/js/routes/public.js                |  123 ++
 .../src/main/js/routes/sql.js                   |   24 +
 .../src/main/js/routes/summary.js               |  108 ++
 .../src/main/js/views/configuration/caches.jade |   74 +
 .../main/js/views/configuration/clusters.jade   |   77 ++
 .../main/js/views/configuration/metadata.jade   |  121 ++
 .../main/js/views/configuration/sidebar.jade    |   39 +
 .../main/js/views/configuration/summary.jade    |  113 ++
 .../src/main/js/views/error.jade                |   22 +
 .../src/main/js/views/includes/controls.jade    |  350 +++++
 .../src/main/js/views/includes/footer.jade      |   22 +
 .../src/main/js/views/includes/header.jade      |   39 +
 .../src/main/js/views/index.jade                |   30 +
 .../src/main/js/views/login.jade                |   55 +
 .../src/main/js/views/settings/admin.jade       |   58 +
 .../src/main/js/views/settings/profile.jade     |   58 +
 .../src/main/js/views/sql/sql.jade              |   84 ++
 .../src/main/js/views/templates/confirm.jade    |   27 +
 .../src/main/js/views/templates/copy.jade       |   31 +
 .../src/main/js/views/templates/layout.jade     |   61 +
 .../src/main/js/views/templates/select.jade     |   26 +
 .../src/main/js/views/templates/tab.jade        |   26 +
 .../web-control-center/licenses/apache-2.0.txt  |  202 ---
 .../web-control-center/src/main/js/.gitignore   |    4 -
 .../web-control-center/src/main/js/DEVNOTES.txt |   21 -
 modules/web-control-center/src/main/js/app.js   |  158 ---
 modules/web-control-center/src/main/js/bin/www  |  110 --
 .../src/main/js/config/default.json             |   17 -
 .../src/main/js/controllers/admin-controller.js |   68 -
 .../js/controllers/cache-viewer-controller.js   |   77 --
 .../main/js/controllers/caches-controller.js    |  349 -----
 .../main/js/controllers/clusters-controller.js  |  308 -----
 .../src/main/js/controllers/common-module.js    |  484 -------
 .../main/js/controllers/metadata-controller.js  |  709 ----------
 .../src/main/js/controllers/models/caches.json  |  943 -------------
 .../main/js/controllers/models/clusters.json    |  909 -------------
 .../main/js/controllers/models/metadata.json    |  252 ----
 .../src/main/js/controllers/models/sql.json     |    5 -
 .../src/main/js/controllers/models/summary.json |  163 ---
 .../main/js/controllers/profile-controller.js   |   51 -
 .../src/main/js/controllers/sql-controller.js   |  129 --
 .../main/js/controllers/summary-controller.js   |  170 ---
 modules/web-control-center/src/main/js/db.js    |  370 -----
 .../src/main/js/helpers/configuration-loader.js |   22 -
 .../src/main/js/helpers/data-structures.js      |   84 --
 .../web-control-center/src/main/js/package.json |   50 -
 .../src/main/js/public/favicon.ico              |  Bin 1150 -> 0 bytes
 .../src/main/js/public/images/docker.png        |  Bin 994 -> 0 bytes
 .../src/main/js/public/images/java.png          |  Bin 170 -> 0 bytes
 .../src/main/js/public/images/logo.png          |  Bin 8148 -> 0 bytes
 .../src/main/js/public/images/xml.png           |  Bin 232 -> 0 bytes
 .../src/main/js/public/stylesheets/style.scss   | 1270 ------------------
 .../src/main/js/routes/admin.js                 |   79 --
 .../src/main/js/routes/caches.js                |  105 --
 .../src/main/js/routes/clusters.js              |  104 --
 .../src/main/js/routes/generator/common.js      |  324 -----
 .../src/main/js/routes/generator/docker.js      |   58 -
 .../src/main/js/routes/generator/java.js        |  626 ---------
 .../src/main/js/routes/generator/xml.js         |  738 ----------
 .../src/main/js/routes/metadata.js              |   95 --
 .../src/main/js/routes/profile.js               |   97 --
 .../src/main/js/routes/public.js                |  123 --
 .../src/main/js/routes/sql.js                   |   24 -
 .../src/main/js/routes/summary.js               |  108 --
 .../src/main/js/views/configuration/caches.jade |   74 -
 .../main/js/views/configuration/clusters.jade   |   77 --
 .../main/js/views/configuration/metadata.jade   |  121 --
 .../main/js/views/configuration/sidebar.jade    |   39 -
 .../main/js/views/configuration/summary.jade    |  113 --
 .../src/main/js/views/error.jade                |   22 -
 .../src/main/js/views/includes/controls.jade    |  350 -----
 .../src/main/js/views/includes/footer.jade      |   22 -
 .../src/main/js/views/includes/header.jade      |   39 -
 .../src/main/js/views/index.jade                |   30 -
 .../src/main/js/views/login.jade                |   55 -
 .../src/main/js/views/settings/admin.jade       |   58 -
 .../src/main/js/views/settings/profile.jade     |   58 -
 .../src/main/js/views/sql/sql.jade              |   84 --
 .../src/main/js/views/templates/confirm.jade    |   27 -
 .../src/main/js/views/templates/copy.jade       |   31 -
 .../src/main/js/views/templates/layout.jade     |   61 -
 .../src/main/js/views/templates/select.jade     |   26 -
 .../src/main/js/views/templates/tab.jade        |   26 -
 122 files changed, 10867 insertions(+), 10719 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/6b621759/modules/control-center-web/src/main/js/app.js
----------------------------------------------------------------------
diff --cc modules/control-center-web/src/main/js/app.js
index 0000000,a67afc8..930c798
mode 000000,100644..100644
--- a/modules/control-center-web/src/main/js/app.js
+++ b/modules/control-center-web/src/main/js/app.js
@@@ -1,0 -1,156 +1,158 @@@
+ /*
+  * Licensed to the Apache Software Foundation (ASF) under one or more
+  * contributor license agreements.  See the NOTICE file distributed with
+  * this work for additional information regarding copyright ownership.
+  * The ASF licenses this file to You under the Apache License, Version 2.0
+  * (the "License"); you may not use this file except in compliance with
+  * the License.  You may obtain a copy of the License at
+  *
+  *      http://www.apache.org/licenses/LICENSE-2.0
+  *
+  * Unless required by applicable law or agreed to in writing, software
+  * distributed under the License is distributed on an "AS IS" BASIS,
+  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  * See the License for the specific language governing permissions and
+  * limitations under the License.
+  */
+ 
+ var flash = require('connect-flash');
+ var express = require('express');
+ var path = require('path');
+ var favicon = require('serve-favicon');
+ var logger = require('morgan');
+ var cookieParser = require('cookie-parser');
+ var bodyParser = require('body-parser');
+ var session = require('express-session');
+ var mongoStore = require('connect-mongo')(session);
+ 
+ var publicRoutes = require('./routes/public');
+ var clustersRouter = require('./routes/clusters');
+ var cachesRouter = require('./routes/caches');
+ var metadataRouter = require('./routes/metadata');
+ var summary = require('./routes/summary');
+ var adminRouter = require('./routes/admin');
+ var profileRouter = require('./routes/profile');
+ var sqlRouter = require('./routes/sql');
++var agentRouter = require('./routes/agent');
+ 
+ var passport = require('passport');
+ 
+ var db = require('./db');
+ 
+ var app = express();
+ 
+ // Views engine setup.
+ app.set('views', path.join(__dirname, 'views'));
+ app.set('view engine', 'jade');
+ 
+ // Site favicon.
+ app.use(favicon(__dirname + '/public/favicon.ico'));
+ 
+ app.use(logger('dev'));
+ 
+ app.use(bodyParser.json());
+ app.use(bodyParser.urlencoded({extended: false}));
+ 
+ app.use(require('node-sass-middleware')({
+     /* Options */
+     src: path.join(__dirname, 'public'),
+     dest: path.join(__dirname, 'public'),
+     debug: true,
+     outputStyle: 'nested'
+ }));
+ 
+ app.use(express.static(path.join(__dirname, 'public')));
+ app.use(express.static(path.join(__dirname, 'controllers')));
+ app.use(express.static(path.join(__dirname, 'helpers')));
+ 
+ app.use(cookieParser('keyboard cat'));
+ 
+ app.use(session({
+     secret: 'keyboard cat',
+     resave: false,
+     saveUninitialized: true,
+     store: new mongoStore({
+         mongooseConnection: db.mongoose.connection
+     })
+ }));
+ 
+ app.use(flash());
+ 
+ app.use(passport.initialize());
+ app.use(passport.session());
+ 
+ passport.serializeUser(db.Account.serializeUser());
+ passport.deserializeUser(db.Account.deserializeUser());
+ 
+ passport.use(db.Account.createStrategy());
+ 
+ var mustAuthenticated = function (req, res, next) {
+     req.isAuthenticated() ? next() : res.redirect('/');
+ };
+ 
+ var adminOnly = function(req, res, next) {
+     req.isAuthenticated() && req.user.admin ? next() : res.sendStatus(403);
+ };
+ 
+ app.all('/configuration/*', mustAuthenticated);
+ 
+ app.all('*', function(req, res, next) {
+     var becomeUsed = req.session.viewedUser && req.user.admin;
+ 
+     res.locals.user = becomeUsed ? req.session.viewedUser : req.user;
+     res.locals.becomeUsed = becomeUsed;
+ 
+     req.currentUserId = function() {
+         if (!req.user)
+             return null;
+ 
+         if (req.session.viewedUser && req.user.admin)
+             return req.session.viewedUser._id;
+ 
+         return req.user._id;
+     };
+ 
+     next();
+ });
+ 
+ app.use('/', publicRoutes);
+ app.use('/admin', mustAuthenticated, adminOnly, adminRouter);
+ app.use('/profile', mustAuthenticated, profileRouter);
+ 
+ app.use('/configuration/clusters', clustersRouter);
+ app.use('/configuration/caches', cachesRouter);
+ app.use('/configuration/metadata', metadataRouter);
+ app.use('/configuration/summary', summary);
+ app.use('/sql', sqlRouter);
++app.use('/agent', agentRouter);
+ 
+ // Catch 404 and forward to error handler.
+ app.use(function (req, res, next) {
+     var err = new Error('Not Found: ' + req.originalUrl);
+     err.status = 404;
+     next(err);
+ });
+ 
+ // Error handlers.
+ 
+ // Development error handler: will print stacktrace.
+ if (app.get('env') === 'development') {
+     app.use(function (err, req, res) {
+         res.status(err.status || 500);
+         res.render('error', {
+             message: err.message,
+             error: err
+         });
+     });
+ }
+ 
+ // Production error handler: no stacktraces leaked to user.
+ app.use(function (err, req, res) {
+     res.status(err.status || 500);
+     res.render('error', {
+         message: err.message,
+         error: {}
+     });
+ });
+ 
+ module.exports = app;

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/6b621759/modules/control-center-web/src/main/js/bin/www
----------------------------------------------------------------------
diff --cc modules/control-center-web/src/main/js/bin/www
index 0000000,4cf0583..cbc637a
mode 000000,100644..100644
--- a/modules/control-center-web/src/main/js/bin/www
+++ b/modules/control-center-web/src/main/js/bin/www
@@@ -1,0 -1,85 +1,110 @@@
+ #!/usr/bin/env node
+ 
+ /**
+  * Module dependencies.
+  */
 -var app = require('../app');
++var http = require('http');
++var https = require('https');
+ var config = require('../helpers/configuration-loader.js');
++var app = require('../app');
++var agentManager = require('../agents/agent-manager');
++
++var fs = require('fs');
++
+ var debug = require('debug')('ignite-web-control-center:server');
 -var http = require('http');
+ 
+ /**
+  * Get port from environment and store in Express.
+  */
+ var port = normalizePort(process.env.PORT || config.get('express:port'));
+ app.set('port', port);
+ 
+ /**
+  * Create HTTP server.
+  */
+ var server = http.createServer(app);
+ 
+ /**
+  * Listen on provided port, on all network interfaces.
+  */
+ server.listen(port);
+ server.on('error', onError);
+ server.on('listening', onListening);
+ 
+ /**
++ * Start agent server.
++ */
++var agentServer;
++
++if (config.get('monitor:server:ssl')) {
++    agentServer = https.createServer({
++    key: fs.readFileSync(config.get('monitor:server:key')),
++    cert: fs.readFileSync(config.get('monitor:server:cert')),
++    passphrase: config.get('monitor:server:keyPassphrase')
++  });
++}
++else {
++  agentServer = http.createServer();
++}
++
++agentServer.listen(config.get('monitor:server:port'));
++
++agentManager.createManager(agentServer);
++
++/**
+  * Normalize a port into a number, string, or false.
+  */
+ function normalizePort(val) {
+   var port = parseInt(val, 10);
+ 
+   if (isNaN(port)) {
+     // named pipe
+     return val;
+   }
+ 
+   if (port >= 0) {
+     // port number
+     return port;
+   }
+ 
+   return false;
+ }
+ 
+ /**
+  * Event listener for HTTP server "error" event.
+  */
+ function onError(error) {
+   if (error.syscall !== 'listen') {
+     throw error;
+   }
+ 
+   var bind = typeof port === 'string'
+     ? 'Pipe ' + port
+     : 'Port ' + port;
+ 
+   // handle specific listen errors with friendly messages
+   switch (error.code) {
+     case 'EACCES':
+       console.error(bind + ' requires elevated privileges');
+       process.exit(1);
+       break;
+     case 'EADDRINUSE':
+       console.error(bind + ' is already in use');
+       process.exit(1);
+       break;
+     default:
+       throw error;
+   }
+ }
+ 
+ /**
+  * Event listener for HTTP server "listening" event.
+  */
+ function onListening() {
+   var addr = server.address();
+   var bind = typeof addr === 'string'
+     ? 'pipe ' + addr
+     : 'port ' + addr.port;
+ 
+   debug('Listening on ' + bind);
+ }

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/6b621759/modules/control-center-web/src/main/js/config/default.json
----------------------------------------------------------------------
diff --cc modules/control-center-web/src/main/js/config/default.json
index 0000000,72dbd4e..f7f7a02
mode 000000,100644..100644
--- a/modules/control-center-web/src/main/js/config/default.json
+++ b/modules/control-center-web/src/main/js/config/default.json
@@@ -1,0 -1,8 +1,17 @@@
+ {
+     "express": {
+         "port": 3000
+     },
+     "mongoDB": {
+         "url": "mongodb://localhost/web-control-center"
++    },
++    "monitor": {
++        "server": {
++            "port": 3001,
++            "ssl": true,
++            "key": "keys/test.key",
++            "cert": "keys/test.crt",
++            "keyPassphrase": "password"
++        }
+     }
 -}
++}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/6b621759/modules/control-center-web/src/main/js/controllers/sql-controller.js
----------------------------------------------------------------------
diff --cc modules/control-center-web/src/main/js/controllers/sql-controller.js
index 0000000,12772c6..b4b4335
mode 000000,100644..100644
--- a/modules/control-center-web/src/main/js/controllers/sql-controller.js
+++ b/modules/control-center-web/src/main/js/controllers/sql-controller.js
@@@ -1,0 -1,84 +1,129 @@@
+ /*
+  * Licensed to the Apache Software Foundation (ASF) under one or more
+  * contributor license agreements.  See the NOTICE file distributed with
+  * this work for additional information regarding copyright ownership.
+  * The ASF licenses this file to You under the Apache License, Version 2.0
+  * (the "License"); you may not use this file except in compliance with
+  * the License.  You may obtain a copy of the License at
+  *
+  *      http://www.apache.org/licenses/LICENSE-2.0
+  *
+  * Unless required by applicable law or agreed to in writing, software
+  * distributed under the License is distributed on an "AS IS" BASIS,
+  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  * See the License for the specific language governing permissions and
+  * limitations under the License.
+  */
+ 
 -var demoResults = [
 -    {
 -        id: 256,
 -        firstName: 'Ivan',
 -        lastName: 'Ivanov'
 -    },
 -    {
 -        id: 384,
 -        firstName: 'Sergey',
 -        lastName: 'Petrov'
 -    },
 -    {
 -        id: 923,
 -        firstName: 'Andrey',
 -        lastName: 'Sidorov'
 -    }
 -];
 -
 -var demoCaches = [{_id: '1', name: 'Users', mode: 'LOCAL'}, {_id: '2', name: 'Organizations', mode: 'REPLICATED'}, {_id: '3', name: 'Cities', mode: 'PARTITIONED'}];
 -
 -
 -
+ controlCenterModule.controller('sqlController', ['$scope', '$http', '$common', function ($scope, $http, $common) {
+     $scope.joinTip = $common.joinTip;
+ 
+     $scope.pageSizes = [50, 100, 200, 400, 800, 1000];
+ 
 -    $scope.tabs = [
 -        {
 -            query: "SELECT u.id, u.firstName, u.lastName FROM User u WHERE u.name LIKE 'aaaa'",
 -            cols: Object.keys(demoResults[0]),
 -            page: 1,
 -            hasMore: true,
 -            total: 0,
 -            rows: demoResults
 -        },
 -        {query: "SELECT * FROM Organization"}
++    $scope.modes = [
++        {value: 'PARTITIONED', label: 'PARTITIONED'},
++        {value: 'REPLICATED', label: 'REPLICATED'},
++        {value: 'LOCAL', label: 'LOCAL'}
+     ];
+ 
++    $scope.tabs = [];
++
+     $scope.addTab = function() {
 -        console.log('addTab');
++        var tab = {query: "", pageSize: $scope.pageSizes[0]};
++
++        if ($scope.caches.length > 0)
++            tab.selectedItem = $scope.caches[0];
+ 
 -        $scope.tabs.push({query: "SELECT "});
++        $scope.tabs.push(tab);
+     };
+ 
+     $scope.removeTab = function(idx) {
 -        console.log('removeTab');
 -
+         $scope.tabs.splice(idx, 1);
+     };
+ 
 -    $scope.modes = [
 -        {value: 'PARTITIONED', label: 'PARTITIONED'},
 -        {value: 'REPLICATED', label: 'REPLICATED'},
 -        {value: 'LOCAL', label: 'LOCAL'}
 -    ];
 -
+     $http.get('/models/sql.json')
+         .success(function (data) {
+             $scope.screenTip = data.screenTip;
+         })
+         .error(function (errMsg) {
+             $common.showError(errMsg);
+         });
+ 
 -    $scope.caches = demoCaches;
++    $scope.caches = [];
++
++    $http.post('/agent/topology')
++        .success(function (clusters) {
++            var node = clusters[0];
++
++            $scope.caches = node.caches;
++
++            if ($scope.tabs.length == 0)
++                $scope.addTab();
++        })
++        .error(function (errMsg) {
++            $common.showError(errMsg);
++        });
++
++    $scope.execute = function(tab) {
++        $http.post('/agent/query', {query: tab.query, pageSize: tab.pageSize, cacheName: tab.selectedItem.name})
++            .success(function (res) {
++                tab.meta = [];
++
++                if (res.meta)
++                    tab.meta = res.meta;
++
++                tab.page = 1;
++
++                tab.total = 0;
++
++                tab.queryId = res.queryId;
++
++                tab.rows = res.rows;
++            })
++            .error(function (errMsg) {
++                $common.showError(errMsg);
++            });
++    };
++
++    $scope.explain = function(tab) {
++        $http.post('/agent/query', {query: 'EXPLAIN ' + tab.query, pageSize: tab.pageSize, cacheName: tab.selectedItem.name})
++            .success(function (res) {
++                tab.meta = [];
++
++                if (res.meta)
++                    tab.meta = res.meta;
++
++                tab.page = 1;
++
++                tab.total = 0;
++
++                tab.queryId = res.queryId;
++
++                tab.rows = res.rows;
++            })
++            .error(function (errMsg) {
++                $common.showError(errMsg);
++            });
++    };
++
++    $scope.nextPage = function(tab) {
++        $http.post('/agent/next_page', {queryId: tab.queryId, pageSize: tab.pageSize, cacheName: tab.selectedItem.name})
++            .success(function (res) {
++                tab.page++;
++
++                tab.total += tab.rows.length;
++
++                tab.rows = res.rows;
++
++                if (res.last)
++                    delete tab.queryId;
++            })
++            .error(function (errMsg) {
++                $common.showError(errMsg);
++            });
++    };
++
++    $scope.getter = function (value) {
++        return value;
++    }
+ }]);

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/6b621759/modules/control-center-web/src/main/js/package.json
----------------------------------------------------------------------
diff --cc modules/control-center-web/src/main/js/package.json
index 0000000,fd82196..f7926cf
mode 000000,100644..100644
--- a/modules/control-center-web/src/main/js/package.json
+++ b/modules/control-center-web/src/main/js/package.json
@@@ -1,0 -1,49 +1,50 @@@
+ {
+   "name": "ignite-web-control-center",
+   "version": "1.0.0",
+   "description": "Web application for configuration, monitoring Ignite Cluster",
+   "private": true,
+   "scripts": {
+     "start": "node ./bin/www"
+   },
+   "author": "",
+   "contributors": [
+     {
+       "name": "",
+       "email": ""
+     }
+   ],
+   "license": "Apache-2.0",
+   "keywords": "grid",
+   "homepage": "https://ignite.incubator.apache.org/",
+   "engines": {
+     "node": ">=0.12.4"
+   },
+   "dependencies": {
+     "angular-ui-ace": "^0.2.3",
+     "archiver": "^0.14.4",
+     "body-parser": "~1.12.0",
+     "connect-flash": "^0.1.1",
+     "connect-mongo": "^0.8.1",
+     "cookie-parser": "~1.3.4",
+     "debug": "~2.1.1",
+     "express": "~4.12.2",
+     "express-session": "^1.11.1",
+     "jade": "~1.9.2",
+     "lodash": "3.10.0",
+     "mongoose": "^4.0.2",
+     "mongoose-deep-populate": "1.1.0",
+     "nconf": "^0.7.1",
+     "node-sass-middleware": "^0.9.0",
+     "passport": "^0.2.1",
+     "passport-local": "^1.0.0",
+     "passport-local-mongoose": "^1.0.0",
 -    "serve-favicon": "~2.2.0"
++    "serve-favicon": "~2.2.0",
++    "ws": "~0.7.2"
+   },
+   "devDependencies": {
+     "morgan": "~1.5.1",
+     "supertest": "^1.0.1",
+     "mocha": "~2.0.1",
+     "should": "~3.1.3"
+   }
+ }

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/6b621759/modules/control-center-web/src/main/js/views/sql/sql.jade
----------------------------------------------------------------------
diff --cc modules/control-center-web/src/main/js/views/sql/sql.jade
index 0000000,97d34de..2ce6958
mode 000000,100644..100644
--- a/modules/control-center-web/src/main/js/views/sql/sql.jade
+++ b/modules/control-center-web/src/main/js/views/sql/sql.jade
@@@ -1,0 -1,85 +1,84 @@@
+ //-
+     Licensed to the Apache Software Foundation (ASF) under one or more
+     contributor license agreements.  See the NOTICE file distributed with
+     this work for additional information regarding copyright ownership.
+     The ASF licenses this file to You under the Apache License, Version 2.0
+     (the "License"); you may not use this file except in compliance with
+     the License.  You may obtain a copy of the License at
+          http://www.apache.org/licenses/LICENSE-2.0
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ extends ../templates/layout
+ 
+ append scripts
+     script(src='/sql-controller.js')
+ 
+     script(src='//cdnjs.cloudflare.com/ajax/libs/ace/1.2.0/theme-chrome.js')
+     script(src='//cdnjs.cloudflare.com/ajax/libs/ace/1.2.0/mode-sql.js')
+     script(src='//cdnjs.cloudflare.com/ajax/libs/ace/1.2.0/ext-language_tools.js')
+ 
+ block container
+     .row
+         .col-sm-12
+             .docs-content
+                 .docs-header
+                     h1 Connect to Ignite and Execute SQL Queries
+                     hr
+                 .docs-body(ng-controller='sqlController')
+                     - var tab = 'tabs[tabs.activeIdx]'
+ 
+                     .block-callout-parent.block-callout-border.margin-bottom-dflt
+                         .block-callout
+                             p(ng-bind-html='joinTip(screenTip)')
+                     .tabs-below(bs-tabs bs-active-pane='tabs.activeIdx' data-template='/tab')
+                         div(ng-repeat='tab in tabs' title='Query' bs-pane)
+                     .row
+                         .col-sm-9(style='border-right: 1px solid #eee')
+                             div(style='height: 200px' ui-ace='{ theme: "chrome", mode: "sql",' +
+                                 'require: ["ace/ext/language_tools"],' +
+                                 'rendererOptions: {showPrintMargin: false, highlightGutterLine: false, fontSize: 14},' +
+                                 'advanced: {enableSnippets: false, enableBasicAutocompletion: true, enableLiveAutocompletion: true}}' ng-model='#{tab}.query')
+                         .col-sm-3
+                             div(ng-hide='caches.length == 0' style='margin-top: 0.65em')
+                                 lable.labelHeader Caches:
+                                 table.links(st-table='caches')
+                                     tbody
 -                                        tr(ng-repeat='row in caches track by row._id')
 -                                            td.col-sm-6(ng-class='{active: row._id == #{tab}.selectedItem._id}')
 -                                                a(ng-click='#{tab}.selectedItem = row') {{$index + 1}}) {{row.name}}, {{row.mode | displayValue:modes:'Cache mode not set'}}
++                                        tr(ng-repeat='row in caches track by row.name')
++                                            td.col-sm-6(ng-class='{active: row.name == #{tab}.selectedItem.name}')
++                                                a(ng-click='#{tab}.selectedItem = row') {{$index + 1}}) {{::row.name}}, {{::row.mode}}
+                     hr(style='margin: 0')
+                     .settings-row
+                         label Page Size:&nbsp;
 -                        button.btn.btn-default.base-control(ng-init='pageSize = pageSizes[0]' ng-model='pageSize' bs-options='item for item in pageSizes' bs-select)
++                        button.btn.btn-default.base-control(ng-model='#{tab}.pageSize' bs-options='item for item in pageSizes' bs-select)
+                     .settings-row
 -                        button.btn.btn-primary(ng-click='') Explain
 -                        button.btn.btn-primary(ng-click='') Execute
 -                        button.btn.btn-primary(ng-click='' disabled) Scan
++                        button.btn.btn-primary(ng-click='explain(#{tab})') Explain
++                        button.btn.btn-primary(ng-click='execute(#{tab})') Execute
++                        button.btn.btn-primary(ng-click='scan(#{tab})' disabled) Scan
+ 
+                     div(ng-show='#{tab}.rows.length > 0' style='margin-top: 0.65em')
+                         hr
+                         div
 -                            table.table.table-striped.col-sm-12.sql-results(st-table='rows' st-safe-src='#{tab}.rows')
++                            table.table.table-striped.col-sm-12.sql-results(st-table='displayedCollection' st-safe-src='#{tab}.rows')
+                                 thead
+                                     tr(style='border-size: 0')
 -                                        td(colspan='{{#{tab}.cols.length}}')
++                                        td(colspan='{{#{tab}.meta.length}}')
+                                             .col-sm-8
+                                                 lable Page #:&nbsp;
+                                                 b {{#{tab}.page}}&nbsp;&nbsp;&nbsp;
+                                                 | Results:&nbsp;
+                                                 b {{#{tab}.rows.length + #{tab}.total}}
+                                             .col-sm-4
 -                                                button.btn.btn-primary.fieldButton(ng-click='') Next page
 -                                                .input-tip
 -                                                    input.form-control(type='text' st-search='' placeholder='Filter...')
 -
++                                                button.btn.btn-primary.fieldButton(ng-click='nextPage(#{tab})' ng-disabled='!#{tab}.queryId') Next page
++                                                //.input-tip
++                                                //    input.form-control(st-search placeholder='Filter...' type='search')
+                                     tr
 -                                        th(ng-repeat='column in #{tab}.cols' st-sort='{{column}}') {{column}}
++                                        th(ng-repeat='col in #{tab}.meta track by $index' st-sort='getter' data-ng-bind='::col.fieldName' bs-tooltip='col.schemaName + "." + col.typeName + "." + col.fieldName')
+                                 tbody
+                                     //tr
+                                     //    td(colspan='{{#{tab}.cols.length}}')
+                                     //        .loading-indicator
 -                                    tr(ng-repeat='row in rows')
 -                                        td(ng-repeat='column in #{tab}.cols') {{row[column]}}
++                                    tr(ng-repeat='row in displayedCollection track by $index')
++                                        td(ng-repeat='val in row track by $index') {{ val }}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/6b621759/modules/control-center-web/src/main/js/views/templates/layout.jade
----------------------------------------------------------------------
diff --cc modules/control-center-web/src/main/js/views/templates/layout.jade
index 0000000,71d8936..8e92edb
mode 000000,100644..100644
--- a/modules/control-center-web/src/main/js/views/templates/layout.jade
+++ b/modules/control-center-web/src/main/js/views/templates/layout.jade
@@@ -1,0 -1,61 +1,61 @@@
+ //-
+     Licensed to the Apache Software Foundation (ASF) under one or more
+     contributor license agreements.  See the NOTICE file distributed with
+     this work for additional information regarding copyright ownership.
+     The ASF licenses this file to You under the Apache License, Version 2.0
+     (the "License"); you may not use this file except in compliance with
+     the License.  You may obtain a copy of the License at
+ 
+          http://www.apache.org/licenses/LICENSE-2.0
+ 
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ 
+ doctype html
+ html(ng-app='ignite-web-control-center' ng-init='user = #{JSON.stringify(user)}; becomeUsed = #{becomeUsed}')
+     head
+         title= title
+ 
+         block css
+             // Bootstrap
+             link(rel='stylesheet', href='//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.4/css/bootstrap.css')
+ 
+             // Font Awesome Icons
+             link(rel='stylesheet', href='//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.css')
+ 
+             // Font
+             link(rel='stylesheet', href='//fonts.googleapis.com/css?family=Roboto+Slab:700:serif|Roboto+Slab:400:serif')
+ 
+             link(rel='stylesheet', href='/stylesheets/style.css')
+ 
+         block scripts
+             script(src='//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.js')
+ 
+             script(src='//cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.0/lodash.min.js')
+ 
+             script(src='//ajax.googleapis.com/ajax/libs/angularjs/1.4.2/angular.js')
+             script(src='//cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.2/angular-sanitize.js')
+             script(src='//cdnjs.cloudflare.com/ajax/libs/angular-strap/2.3.0/angular-strap.js')
+             script(src='//cdnjs.cloudflare.com/ajax/libs/angular-strap/2.3.0/angular-strap.tpl.min.js')
+ 
 -            script(src='//cdnjs.cloudflare.com/ajax/libs/angular-smart-table/2.0.3/smart-table.js')
++            script(src='//cdnjs.cloudflare.com/ajax/libs/angular-smart-table/2.1.1/smart-table.js')
+ 
+             script(src='//cdnjs.cloudflare.com/ajax/libs/ace/1.2.0/ace.js')
+             script(src='//angular-ui.github.io/ui-ace/dist/ui-ace.min.js')
+ 
+             script(src='/common-module.js')
+             script(src='/data-structures.js')
+ 
+     body.theme-line.body-overlap.greedy
+         .wrapper
+             include ../includes/header
+ 
+             block main-container
+                 .container.body-container
+                     .main-content
+                         block container
+ 
+             include ../includes/footer


[02/41] incubator-ignite git commit: Merge branch 'ignite-843' of https://git-wip-us.apache.org/repos/asf/incubator-ignite into ignite-1121

Posted by an...@apache.org.
Merge branch 'ignite-843' of https://git-wip-us.apache.org/repos/asf/incubator-ignite into ignite-1121


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

Branch: refs/heads/ignite-1121
Commit: ac005f364fcb0250e5c8848e243f8f774967f207
Parents: 9f90103 b6911af
Author: Andrey <an...@gridgain.com>
Authored: Fri Jul 24 13:51:53 2015 +0700
Committer: Andrey <an...@gridgain.com>
Committed: Fri Jul 24 13:51:53 2015 +0700

----------------------------------------------------------------------
 modules/web-control-center/src/main/js/app.js   |   10 +-
 .../web-control-center/src/main/js/package.json |    2 +-
 .../src/main/js/public/stylesheets/style.less   | 1214 -----------------
 .../src/main/js/public/stylesheets/style.scss   | 1270 ++++++++++++++++++
 .../src/main/js/views/configuration/caches.jade |    4 +-
 .../main/js/views/configuration/clusters.jade   |    4 +-
 .../main/js/views/configuration/metadata.jade   |    4 +-
 .../main/js/views/configuration/summary.jade    |   11 +-
 .../src/main/js/views/sql/sql.jade              |    7 +-
 9 files changed, 1293 insertions(+), 1233 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/ac005f36/modules/web-control-center/src/main/js/app.js
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/ac005f36/modules/web-control-center/src/main/js/package.json
----------------------------------------------------------------------


[37/41] incubator-ignite git commit: # ignite-843 Rename

Posted by an...@apache.org.
# ignite-843 Rename


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

Branch: refs/heads/ignite-1121
Commit: 96522874ebc7809a8f4256ce2e4aa681c2b9241c
Parents: cb2ecb5
Author: Andrey <an...@gridgain.com>
Authored: Wed Jul 29 10:39:34 2015 +0700
Committer: Andrey <an...@gridgain.com>
Committed: Wed Jul 29 10:39:34 2015 +0700

----------------------------------------------------------------------
 .../control-center-web/licenses/apache-2.0.txt  |  202 +++
 .../control-center-web/src/main/js/.gitignore   |    4 +
 .../control-center-web/src/main/js/DEVNOTES.txt |   21 +
 modules/control-center-web/src/main/js/app.js   |  156 +++
 modules/control-center-web/src/main/js/bin/www  |   85 ++
 .../src/main/js/config/default.json             |    8 +
 .../src/main/js/controllers/admin-controller.js |   68 +
 .../js/controllers/cache-viewer-controller.js   |   77 ++
 .../main/js/controllers/caches-controller.js    |  349 +++++
 .../main/js/controllers/clusters-controller.js  |  308 +++++
 .../src/main/js/controllers/common-module.js    |  484 +++++++
 .../main/js/controllers/metadata-controller.js  |  709 ++++++++++
 .../src/main/js/controllers/models/caches.json  |  943 +++++++++++++
 .../main/js/controllers/models/clusters.json    |  909 +++++++++++++
 .../main/js/controllers/models/metadata.json    |  252 ++++
 .../src/main/js/controllers/models/sql.json     |    5 +
 .../src/main/js/controllers/models/summary.json |  163 +++
 .../main/js/controllers/profile-controller.js   |   51 +
 .../src/main/js/controllers/sql-controller.js   |   84 ++
 .../main/js/controllers/summary-controller.js   |  170 +++
 modules/control-center-web/src/main/js/db.js    |  370 +++++
 .../src/main/js/helpers/configuration-loader.js |   22 +
 .../src/main/js/helpers/data-structures.js      |   84 ++
 .../control-center-web/src/main/js/package.json |   49 +
 .../src/main/js/public/favicon.ico              |  Bin 0 -> 1150 bytes
 .../src/main/js/public/images/docker.png        |  Bin 0 -> 994 bytes
 .../src/main/js/public/images/java.png          |  Bin 0 -> 170 bytes
 .../src/main/js/public/images/logo.png          |  Bin 0 -> 8148 bytes
 .../src/main/js/public/images/xml.png           |  Bin 0 -> 232 bytes
 .../src/main/js/public/stylesheets/style.scss   | 1270 ++++++++++++++++++
 .../src/main/js/routes/admin.js                 |   79 ++
 .../src/main/js/routes/caches.js                |  105 ++
 .../src/main/js/routes/clusters.js              |  104 ++
 .../src/main/js/routes/generator/common.js      |  312 +++++
 .../src/main/js/routes/generator/docker.js      |   58 +
 .../src/main/js/routes/generator/java.js        |  788 +++++++++++
 .../src/main/js/routes/generator/xml.js         |  736 ++++++++++
 .../src/main/js/routes/metadata.js              |   95 ++
 .../src/main/js/routes/profile.js               |   97 ++
 .../src/main/js/routes/public.js                |  123 ++
 .../src/main/js/routes/sql.js                   |   24 +
 .../src/main/js/routes/summary.js               |  108 ++
 .../src/main/js/views/configuration/caches.jade |   74 +
 .../main/js/views/configuration/clusters.jade   |   77 ++
 .../main/js/views/configuration/metadata.jade   |  121 ++
 .../main/js/views/configuration/sidebar.jade    |   39 +
 .../main/js/views/configuration/summary.jade    |  113 ++
 .../src/main/js/views/error.jade                |   22 +
 .../src/main/js/views/includes/controls.jade    |  350 +++++
 .../src/main/js/views/includes/footer.jade      |   22 +
 .../src/main/js/views/includes/header.jade      |   39 +
 .../src/main/js/views/index.jade                |   30 +
 .../src/main/js/views/login.jade                |   55 +
 .../src/main/js/views/settings/admin.jade       |   58 +
 .../src/main/js/views/settings/profile.jade     |   58 +
 .../src/main/js/views/sql/sql.jade              |   85 ++
 .../src/main/js/views/templates/confirm.jade    |   27 +
 .../src/main/js/views/templates/copy.jade       |   31 +
 .../src/main/js/views/templates/layout.jade     |   61 +
 .../src/main/js/views/templates/select.jade     |   26 +
 .../src/main/js/views/templates/tab.jade        |   26 +
 .../web-control-center/licenses/apache-2.0.txt  |  202 ---
 .../web-control-center/src/main/js/.gitignore   |    4 -
 .../web-control-center/src/main/js/DEVNOTES.txt |   21 -
 modules/web-control-center/src/main/js/app.js   |  156 ---
 modules/web-control-center/src/main/js/bin/www  |   85 --
 .../src/main/js/config/default.json             |    8 -
 .../src/main/js/controllers/admin-controller.js |   68 -
 .../js/controllers/cache-viewer-controller.js   |   77 --
 .../main/js/controllers/caches-controller.js    |  349 -----
 .../main/js/controllers/clusters-controller.js  |  308 -----
 .../src/main/js/controllers/common-module.js    |  484 -------
 .../main/js/controllers/metadata-controller.js  |  709 ----------
 .../src/main/js/controllers/models/caches.json  |  943 -------------
 .../main/js/controllers/models/clusters.json    |  909 -------------
 .../main/js/controllers/models/metadata.json    |  252 ----
 .../src/main/js/controllers/models/sql.json     |    5 -
 .../src/main/js/controllers/models/summary.json |  163 ---
 .../main/js/controllers/profile-controller.js   |   51 -
 .../src/main/js/controllers/sql-controller.js   |   84 --
 .../main/js/controllers/summary-controller.js   |  170 ---
 modules/web-control-center/src/main/js/db.js    |  370 -----
 .../src/main/js/helpers/configuration-loader.js |   22 -
 .../src/main/js/helpers/data-structures.js      |   84 --
 .../web-control-center/src/main/js/package.json |   49 -
 .../src/main/js/public/favicon.ico              |  Bin 1150 -> 0 bytes
 .../src/main/js/public/images/docker.png        |  Bin 994 -> 0 bytes
 .../src/main/js/public/images/java.png          |  Bin 170 -> 0 bytes
 .../src/main/js/public/images/logo.png          |  Bin 8148 -> 0 bytes
 .../src/main/js/public/images/xml.png           |  Bin 232 -> 0 bytes
 .../src/main/js/public/stylesheets/style.scss   | 1270 ------------------
 .../src/main/js/routes/admin.js                 |   79 --
 .../src/main/js/routes/caches.js                |  105 --
 .../src/main/js/routes/clusters.js              |  104 --
 .../src/main/js/routes/generator/common.js      |  312 -----
 .../src/main/js/routes/generator/docker.js      |   58 -
 .../src/main/js/routes/generator/java.js        |  788 -----------
 .../src/main/js/routes/generator/xml.js         |  736 ----------
 .../src/main/js/routes/metadata.js              |   95 --
 .../src/main/js/routes/profile.js               |   97 --
 .../src/main/js/routes/public.js                |  123 --
 .../src/main/js/routes/sql.js                   |   24 -
 .../src/main/js/routes/summary.js               |  108 --
 .../src/main/js/views/configuration/caches.jade |   74 -
 .../main/js/views/configuration/clusters.jade   |   77 --
 .../main/js/views/configuration/metadata.jade   |  121 --
 .../main/js/views/configuration/sidebar.jade    |   39 -
 .../main/js/views/configuration/summary.jade    |  113 --
 .../src/main/js/views/error.jade                |   22 -
 .../src/main/js/views/includes/controls.jade    |  350 -----
 .../src/main/js/views/includes/footer.jade      |   22 -
 .../src/main/js/views/includes/header.jade      |   39 -
 .../src/main/js/views/index.jade                |   30 -
 .../src/main/js/views/login.jade                |   55 -
 .../src/main/js/views/settings/admin.jade       |   58 -
 .../src/main/js/views/settings/profile.jade     |   58 -
 .../src/main/js/views/sql/sql.jade              |   85 --
 .../src/main/js/views/templates/confirm.jade    |   27 -
 .../src/main/js/views/templates/copy.jade       |   31 -
 .../src/main/js/views/templates/layout.jade     |   61 -
 .../src/main/js/views/templates/select.jade     |   26 -
 .../src/main/js/views/templates/tab.jade        |   26 -
 122 files changed, 10786 insertions(+), 10786 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/control-center-web/licenses/apache-2.0.txt
----------------------------------------------------------------------
diff --git a/modules/control-center-web/licenses/apache-2.0.txt b/modules/control-center-web/licenses/apache-2.0.txt
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/modules/control-center-web/licenses/apache-2.0.txt
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/control-center-web/src/main/js/.gitignore
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/.gitignore b/modules/control-center-web/src/main/js/.gitignore
new file mode 100644
index 0000000..65f2596
--- /dev/null
+++ b/modules/control-center-web/src/main/js/.gitignore
@@ -0,0 +1,4 @@
+node_modules
+*.idea
+*.log
+*.css
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/control-center-web/src/main/js/DEVNOTES.txt
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/DEVNOTES.txt b/modules/control-center-web/src/main/js/DEVNOTES.txt
new file mode 100644
index 0000000..e8c558c
--- /dev/null
+++ b/modules/control-center-web/src/main/js/DEVNOTES.txt
@@ -0,0 +1,21 @@
+Ignite Web Control Center Instructions
+======================================
+
+How to deploy:
+
+1. Install locally NodeJS using installer from site https://nodejs.org for your OS.
+2. Install locally MongoDB folow instructions from site http://docs.mongodb.org/manual/installation
+3. Checkout ignite-843 branch.
+4. Change directory '$IGNITE_HOME/modules/web-control-center/src/main/js'.
+5. Run "npm install" in terminal for download all dependencies.
+
+Steps 1 - 5 should be executed once.
+
+How to run:
+
+1. Run MongoDB.
+ 1.1 In terminal change dir to $MONGO_ISNTALL_DIR/server/3.0/bin.
+ 1.2 Run "mongod".
+2. In new terminal change directory '$IGNITE_HOME/modules/web-control-center/src/main/js'.
+3. Start application by executing "npm start".
+4. In browser open: http://localhost:3000
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/control-center-web/src/main/js/app.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app.js b/modules/control-center-web/src/main/js/app.js
new file mode 100644
index 0000000..a67afc8
--- /dev/null
+++ b/modules/control-center-web/src/main/js/app.js
@@ -0,0 +1,156 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var flash = require('connect-flash');
+var express = require('express');
+var path = require('path');
+var favicon = require('serve-favicon');
+var logger = require('morgan');
+var cookieParser = require('cookie-parser');
+var bodyParser = require('body-parser');
+var session = require('express-session');
+var mongoStore = require('connect-mongo')(session);
+
+var publicRoutes = require('./routes/public');
+var clustersRouter = require('./routes/clusters');
+var cachesRouter = require('./routes/caches');
+var metadataRouter = require('./routes/metadata');
+var summary = require('./routes/summary');
+var adminRouter = require('./routes/admin');
+var profileRouter = require('./routes/profile');
+var sqlRouter = require('./routes/sql');
+
+var passport = require('passport');
+
+var db = require('./db');
+
+var app = express();
+
+// Views engine setup.
+app.set('views', path.join(__dirname, 'views'));
+app.set('view engine', 'jade');
+
+// Site favicon.
+app.use(favicon(__dirname + '/public/favicon.ico'));
+
+app.use(logger('dev'));
+
+app.use(bodyParser.json());
+app.use(bodyParser.urlencoded({extended: false}));
+
+app.use(require('node-sass-middleware')({
+    /* Options */
+    src: path.join(__dirname, 'public'),
+    dest: path.join(__dirname, 'public'),
+    debug: true,
+    outputStyle: 'nested'
+}));
+
+app.use(express.static(path.join(__dirname, 'public')));
+app.use(express.static(path.join(__dirname, 'controllers')));
+app.use(express.static(path.join(__dirname, 'helpers')));
+
+app.use(cookieParser('keyboard cat'));
+
+app.use(session({
+    secret: 'keyboard cat',
+    resave: false,
+    saveUninitialized: true,
+    store: new mongoStore({
+        mongooseConnection: db.mongoose.connection
+    })
+}));
+
+app.use(flash());
+
+app.use(passport.initialize());
+app.use(passport.session());
+
+passport.serializeUser(db.Account.serializeUser());
+passport.deserializeUser(db.Account.deserializeUser());
+
+passport.use(db.Account.createStrategy());
+
+var mustAuthenticated = function (req, res, next) {
+    req.isAuthenticated() ? next() : res.redirect('/');
+};
+
+var adminOnly = function(req, res, next) {
+    req.isAuthenticated() && req.user.admin ? next() : res.sendStatus(403);
+};
+
+app.all('/configuration/*', mustAuthenticated);
+
+app.all('*', function(req, res, next) {
+    var becomeUsed = req.session.viewedUser && req.user.admin;
+
+    res.locals.user = becomeUsed ? req.session.viewedUser : req.user;
+    res.locals.becomeUsed = becomeUsed;
+
+    req.currentUserId = function() {
+        if (!req.user)
+            return null;
+
+        if (req.session.viewedUser && req.user.admin)
+            return req.session.viewedUser._id;
+
+        return req.user._id;
+    };
+
+    next();
+});
+
+app.use('/', publicRoutes);
+app.use('/admin', mustAuthenticated, adminOnly, adminRouter);
+app.use('/profile', mustAuthenticated, profileRouter);
+
+app.use('/configuration/clusters', clustersRouter);
+app.use('/configuration/caches', cachesRouter);
+app.use('/configuration/metadata', metadataRouter);
+app.use('/configuration/summary', summary);
+app.use('/sql', sqlRouter);
+
+// Catch 404 and forward to error handler.
+app.use(function (req, res, next) {
+    var err = new Error('Not Found: ' + req.originalUrl);
+    err.status = 404;
+    next(err);
+});
+
+// Error handlers.
+
+// Development error handler: will print stacktrace.
+if (app.get('env') === 'development') {
+    app.use(function (err, req, res) {
+        res.status(err.status || 500);
+        res.render('error', {
+            message: err.message,
+            error: err
+        });
+    });
+}
+
+// Production error handler: no stacktraces leaked to user.
+app.use(function (err, req, res) {
+    res.status(err.status || 500);
+    res.render('error', {
+        message: err.message,
+        error: {}
+    });
+});
+
+module.exports = app;

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/control-center-web/src/main/js/bin/www
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/bin/www b/modules/control-center-web/src/main/js/bin/www
new file mode 100644
index 0000000..4cf0583
--- /dev/null
+++ b/modules/control-center-web/src/main/js/bin/www
@@ -0,0 +1,85 @@
+#!/usr/bin/env node
+
+/**
+ * Module dependencies.
+ */
+var app = require('../app');
+var config = require('../helpers/configuration-loader.js');
+var debug = require('debug')('ignite-web-control-center:server');
+var http = require('http');
+
+/**
+ * Get port from environment and store in Express.
+ */
+var port = normalizePort(process.env.PORT || config.get('express:port'));
+app.set('port', port);
+
+/**
+ * Create HTTP server.
+ */
+var server = http.createServer(app);
+
+/**
+ * Listen on provided port, on all network interfaces.
+ */
+server.listen(port);
+server.on('error', onError);
+server.on('listening', onListening);
+
+/**
+ * Normalize a port into a number, string, or false.
+ */
+function normalizePort(val) {
+  var port = parseInt(val, 10);
+
+  if (isNaN(port)) {
+    // named pipe
+    return val;
+  }
+
+  if (port >= 0) {
+    // port number
+    return port;
+  }
+
+  return false;
+}
+
+/**
+ * Event listener for HTTP server "error" event.
+ */
+function onError(error) {
+  if (error.syscall !== 'listen') {
+    throw error;
+  }
+
+  var bind = typeof port === 'string'
+    ? 'Pipe ' + port
+    : 'Port ' + port;
+
+  // handle specific listen errors with friendly messages
+  switch (error.code) {
+    case 'EACCES':
+      console.error(bind + ' requires elevated privileges');
+      process.exit(1);
+      break;
+    case 'EADDRINUSE':
+      console.error(bind + ' is already in use');
+      process.exit(1);
+      break;
+    default:
+      throw error;
+  }
+}
+
+/**
+ * Event listener for HTTP server "listening" event.
+ */
+function onListening() {
+  var addr = server.address();
+  var bind = typeof addr === 'string'
+    ? 'pipe ' + addr
+    : 'port ' + addr.port;
+
+  debug('Listening on ' + bind);
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/control-center-web/src/main/js/config/default.json
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/config/default.json b/modules/control-center-web/src/main/js/config/default.json
new file mode 100644
index 0000000..72dbd4e
--- /dev/null
+++ b/modules/control-center-web/src/main/js/config/default.json
@@ -0,0 +1,8 @@
+{
+    "express": {
+        "port": 3000
+    },
+    "mongoDB": {
+        "url": "mongodb://localhost/web-control-center"
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/control-center-web/src/main/js/controllers/admin-controller.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/controllers/admin-controller.js b/modules/control-center-web/src/main/js/controllers/admin-controller.js
new file mode 100644
index 0000000..09490fe
--- /dev/null
+++ b/modules/control-center-web/src/main/js/controllers/admin-controller.js
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+controlCenterModule.controller('adminController', ['$scope', '$http', '$common', '$confirm', function ($scope, $http, $common, $confirm) {
+    $scope.users = null;
+
+    function reload() {
+        $http.post('admin/list')
+            .success(function (data) {
+                $scope.users = data;
+            })
+            .error(function (errMsg) {
+                $common.showError($common.errorMessage(errMsg));
+            });
+    }
+
+    reload();
+
+    $scope.removeUser = function (user) {
+        $confirm.show('Are you sure you want to remove user: "' + user.username + '"?').then(function () {
+            $http.post('admin/remove', {userId: user._id}).success(
+                function () {
+                    var i = _.findIndex($scope.users, function (u) {
+                        return u._id == user._id;
+                    });
+
+                    if (i >= 0)
+                        $scope.users.splice(i, 1);
+
+                    $common.showInfo('User has been removed: "' + user.username + '"');
+                }).error(function (errMsg) {
+                    $common.showError('Failed to remove user: "' + $common.errorMessage(errMsg) + '"');
+                });
+        });
+    };
+
+    $scope.toggleAdmin = function (user) {
+        if (user.adminChanging)
+            return;
+
+        user.adminChanging = true;
+
+        $http.post('admin/save', {userId: user._id, adminFlag: user.admin}).success(
+            function () {
+                $common.showInfo('Admin right was successfully toggled for user: "' + user.username + '"');
+
+                user.adminChanging = false;
+            }).error(function (errMsg) {
+                $common.showError('Failed to toggle admin right for user: "' + $common.errorMessage(errMsg) + '"');
+
+                user.adminChanging = false;
+            });
+    }
+}]);
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/control-center-web/src/main/js/controllers/cache-viewer-controller.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/controllers/cache-viewer-controller.js b/modules/control-center-web/src/main/js/controllers/cache-viewer-controller.js
new file mode 100644
index 0000000..6e0c130
--- /dev/null
+++ b/modules/control-center-web/src/main/js/controllers/cache-viewer-controller.js
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var demoResults = [
+    {
+        id: 256,
+        s: 'com.foo.User@3213',
+        fields: {
+            id: 256,
+            firstName: 'Ivan',
+            lastName: 'Ivanov',
+            old: 23
+        }
+    },
+
+    {
+        id: 384,
+        s: 'com.foo.User@23214',
+        fields: {
+            id: 384,
+            firstName: 'Sergey',
+            lastName: 'Petrov',
+            old: 28
+        }
+    },
+
+    {
+        id: 923,
+        s: 'com.foo.User@93494',
+        fields: {
+            id: 923,
+            firstName: 'Andrey',
+            lastName: 'Sidorov',
+            old: 28
+        }
+    }
+];
+
+var demoCaches = ['Users', 'Organizations', 'Cities'];
+
+controlCenterModule.controller('cacheViewerController', ['$scope', '$http', '$common', function ($scope, $http, $common) {
+    $scope.results = demoResults;
+
+    $scope.caches = demoCaches;
+
+    $scope.defCache = $scope.caches.length > 0 ? $scope.caches[0] : null;
+
+    var sqlEditor = ace.edit('querySql');
+
+    sqlEditor.setOptions({
+        highlightActiveLine: false,
+        showPrintMargin: false,
+        showGutter: true,
+        theme: "ace/theme/chrome",
+        mode: "ace/mode/sql",
+        fontSize: 14
+    });
+
+    sqlEditor.setValue("select u.id from User u where u.name like 'aaaa';");
+
+    sqlEditor.selection.clearSelection()
+
+}]);

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/control-center-web/src/main/js/controllers/caches-controller.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/controllers/caches-controller.js b/modules/control-center-web/src/main/js/controllers/caches-controller.js
new file mode 100644
index 0000000..e995233
--- /dev/null
+++ b/modules/control-center-web/src/main/js/controllers/caches-controller.js
@@ -0,0 +1,349 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+controlCenterModule.controller('cachesController', ['$scope', '$http', '$common', '$confirm', '$copy', '$table', function ($scope, $http, $common, $confirm, $copy, $table) {
+        $scope.joinTip = $common.joinTip;
+        $scope.getModel = $common.getModel;
+        $scope.javaBuildInTypes = $common.javaBuildInTypes;
+
+        $scope.tableReset = $table.tableReset;
+        $scope.tableNewItem = $table.tableNewItem;
+        $scope.tableNewItemActive = $table.tableNewItemActive;
+        $scope.tableEditing = $table.tableEditing;
+        $scope.tableStartEdit = $table.tableStartEdit;
+        $scope.tableRemove = $table.tableRemove;
+
+        $scope.tableSimpleSave = $table.tableSimpleSave;
+        $scope.tableSimpleSaveVisible = $table.tableSimpleSaveVisible;
+        $scope.tableSimpleUp = $table.tableSimpleUp;
+        $scope.tableSimpleDown = $table.tableSimpleDown;
+        $scope.tableSimpleDownVisible = $table.tableSimpleDownVisible;
+
+        $scope.tablePairSave = $table.tablePairSave;
+        $scope.tablePairSaveVisible = $table.tablePairSaveVisible;
+
+        $scope.atomicities = [
+            {value: 'ATOMIC', label: 'ATOMIC'},
+            {value: 'TRANSACTIONAL', label: 'TRANSACTIONAL'}
+        ];
+
+        $scope.modes = [
+            {value: 'PARTITIONED', label: 'PARTITIONED'},
+            {value: 'REPLICATED', label: 'REPLICATED'},
+            {value: 'LOCAL', label: 'LOCAL'}
+        ];
+
+        $scope.atomicWriteOrderModes = [
+            {value: 'CLOCK', label: 'CLOCK'},
+            {value: 'PRIMARY', label: 'PRIMARY'}
+        ];
+
+        $scope.memoryModes = [
+            {value: 'ONHEAP_TIERED', label: 'ONHEAP_TIERED'},
+            {value: 'OFFHEAP_TIERED', label: 'OFFHEAP_TIERED'},
+            {value: 'OFFHEAP_VALUES', label: 'OFFHEAP_VALUES'}
+        ];
+
+        $scope.evictionPolicies = [
+            {value: 'LRU', label: 'LRU'},
+            {value: 'RND', label: 'Random'},
+            {value: 'FIFO', label: 'FIFO'},
+            {value: 'SORTED', label: 'Sorted'},
+            {value: undefined, label: 'Not set'}
+        ];
+
+        $scope.rebalanceModes = [
+            {value: 'SYNC', label: 'SYNC'},
+            {value: 'ASYNC', label: 'ASYNC'},
+            {value: 'NONE', label: 'NONE'}
+        ];
+
+        $scope.cacheStoreFactories = [
+            {value: 'CacheJdbcPojoStoreFactory', label: 'JDBC POJO store factory'},
+            {value: 'CacheJdbcBlobStoreFactory', label: 'JDBC BLOB store factory'},
+            {value: 'CacheHibernateBlobStoreFactory', label: 'Hibernate BLOB store factory'},
+            {value: undefined, label: 'Not set'}
+        ];
+
+        $scope.cacheStoreJdbcDialects = [
+            {value: 'Oracle', label: 'Oracle'},
+            {value: 'DB2', label: 'IBM DB2'},
+            {value: 'SQLServer', label: 'Microsoft SQL Server'},
+            {value: 'MySQL', label: 'My SQL'},
+            {value: 'PostgreSQL', label: 'Postgre SQL'},
+            {value: 'H2', label: 'H2 database'}
+        ];
+
+        $scope.general = [];
+        $scope.advanced = [];
+
+        $http.get('/models/caches.json')
+            .success(function (data) {
+                $scope.screenTip = data.screenTip;
+                $scope.general = data.general;
+                $scope.advanced = data.advanced;
+            })
+            .error(function (errMsg) {
+                $common.showError(errMsg);
+            });
+
+        $scope.caches = [];
+        $scope.queryMetadata = [];
+        $scope.storeMetadata = [];
+
+        $scope.required = function (field) {
+            var model = $common.isDefined(field.path) ? field.path + '.' + field.model : field.model;
+
+            var backupItem = $scope.backupItem;
+
+            var memoryMode = backupItem.memoryMode;
+
+            var onHeapTired = memoryMode == 'ONHEAP_TIERED';
+            var offHeapTired = memoryMode == 'OFFHEAP_TIERED';
+
+            var offHeapMaxMemory = backupItem.offHeapMaxMemory;
+
+            if (model == 'offHeapMaxMemory' && offHeapTired)
+                return true;
+
+            if (model == 'evictionPolicy.kind' && onHeapTired)
+                return backupItem.swapEnabled || ($common.isDefined(offHeapMaxMemory) && offHeapMaxMemory >= 0);
+
+            return false;
+        };
+
+        $scope.tableSimpleValid = function (item, field, fx, index) {
+            var model = item[field.model];
+
+            if ($common.isDefined(model)) {
+                var idx = _.indexOf(model, fx);
+
+                // Found itself.
+                if (index >= 0 && index == idx)
+                    return true;
+
+                // Found duplicate.
+                if (idx >= 0) {
+                    $common.showError('SQL function such class name already exists!');
+
+                    return false;
+                }
+            }
+
+            return true;
+        };
+
+        $scope.tablePairValid = function (item, field, keyCls, valCls, index) {
+            var model = item[field.model];
+
+            if ($common.isDefined(model)) {
+                var idx = _.findIndex(model, function (pair) {
+                    return pair.keyClass == keyCls
+                });
+
+                // Found itself.
+                if (index >= 0 && index == idx)
+                    return true;
+
+                // Found duplicate.
+                if (idx >= 0) {
+                    $common.showError('Indexed type with such key class already exists!');
+
+                    return false;
+                }
+            }
+
+            return true;
+        };
+
+        // When landing on the page, get caches and show them.
+        $http.post('caches/list')
+            .success(function (data) {
+                $scope.spaces = data.spaces;
+                $scope.caches = data.caches;
+
+                _.forEach(data.metadatas, function (meta) {
+                    var kind = meta.kind;
+
+                    if (kind == 'query' || kind == 'both')
+                        $scope.queryMetadata.push(meta);
+
+                    if (kind == 'store' || kind == 'both')
+                        $scope.storeMetadata.push(meta);
+                });
+
+                var restoredItem = angular.fromJson(sessionStorage.cacheBackupItem);
+
+                if (restoredItem) {
+                    if (restoredItem._id) {
+                        var idx = _.findIndex($scope.caches, function (cache) {
+                            return cache._id == restoredItem._id;
+                        });
+
+                        if (idx >= 0) {
+                            $scope.selectedItem = $scope.caches[idx];
+                            $scope.backupItem = restoredItem;
+                        }
+                        else
+                            sessionStorage.removeItem('cacheBackupItem');
+                    }
+                    else
+                        $scope.backupItem = restoredItem;
+                }
+                else if ($scope.caches.length > 0)
+                    $scope.selectItem($scope.caches[0]);
+
+                $scope.$watch('backupItem', function (val) {
+                    if (val)
+                        sessionStorage.cacheBackupItem = angular.toJson(val);
+                }, true);
+            })
+            .error(function (errMsg) {
+                $common.showError(errMsg);
+            });
+
+        $scope.selectItem = function (item) {
+            $table.tableReset();
+
+            $scope.selectedItem = item;
+            $scope.backupItem = angular.copy(item);
+        };
+
+        // Add new cache.
+        $scope.createItem = function () {
+            $table.tableReset();
+
+            $scope.backupItem = {mode: 'PARTITIONED', atomicityMode: 'ATOMIC', readFromBackup: true, copyOnRead: true};
+            $scope.backupItem.queryMetadata = [];
+            $scope.backupItem.spaceMetadata = [];
+            $scope.backupItem.space = $scope.spaces[0]._id;
+        };
+
+        // Check cache logical consistency.
+        function validate(item) {
+            var cacheStoreFactorySelected = item.cacheStoreFactory && item.cacheStoreFactory.kind;
+
+            if (cacheStoreFactorySelected && !(item.readThrough || item.writeThrough)) {
+                $common.showError('Store is configured but read/write through are not enabled!');
+
+                return false;
+            }
+
+            if ((item.readThrough || item.writeThrough) && !cacheStoreFactorySelected) {
+                $common.showError('Read / write through are enabled but store is not configured!');
+
+                return false;
+            }
+
+            if (item.writeBehindEnabled && !cacheStoreFactorySelected) {
+                $common.showError('Write behind enabled but store is not configured!');
+
+                return false;
+            }
+
+            return true;
+        }
+
+        // Save cache into database.
+        function save(item) {
+            $http.post('caches/save', item)
+                .success(function (_id) {
+                    var idx = _.findIndex($scope.caches, function (cache) {
+                        return cache._id == _id;
+                    });
+
+                    if (idx >= 0)
+                        angular.extend($scope.caches[idx], item);
+                    else {
+                        item._id = _id;
+
+                        $scope.caches.push(item);
+                    }
+
+                    $scope.selectItem(item);
+
+                    $common.showInfo('Cache "' + item.name + '" saved.');
+                })
+                .error(function (errMsg) {
+                    $common.showError(errMsg);
+                });
+        }
+
+        // Save cache.
+        $scope.saveItem = function () {
+            $table.tableReset();
+
+            var item = $scope.backupItem;
+
+            if (validate(item))
+                save(item);
+        };
+
+        // Save cache with new name.
+        $scope.saveItemAs = function () {
+            $table.tableReset();
+
+            if (validate($scope.backupItem))
+                $copy.show($scope.backupItem.name).then(function (newName) {
+                    var item = angular.copy($scope.backupItem);
+
+                    item._id = undefined;
+                    item.name = newName;
+
+                    save(item);
+                });
+        };
+
+        // Remove cache from db.
+        $scope.removeItem = function () {
+            $table.tableReset();
+
+            var selectedItem = $scope.selectedItem;
+
+            $confirm.show('Are you sure you want to remove cache: "' + selectedItem.name + '"?').then(
+                function () {
+                    var _id = selectedItem._id;
+
+                    $http.post('caches/remove', {_id: _id})
+                        .success(function () {
+                            $common.showInfo('Cache has been removed: ' + selectedItem.name);
+
+                            var caches = $scope.caches;
+
+                            var idx = _.findIndex(caches, function (cache) {
+                                return cache._id == _id;
+                            });
+
+                            if (idx >= 0) {
+                                caches.splice(idx, 1);
+
+                                if (caches.length > 0)
+                                    $scope.selectItem(caches[0]);
+                                else {
+                                    $scope.selectedItem = undefined;
+                                    $scope.backupItem = undefined;
+                                }
+                            }
+                        })
+                        .error(function (errMsg) {
+                            $common.showError(errMsg);
+                        });
+                }
+            );
+        };
+    }]
+);
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/control-center-web/src/main/js/controllers/clusters-controller.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/controllers/clusters-controller.js b/modules/control-center-web/src/main/js/controllers/clusters-controller.js
new file mode 100644
index 0000000..0b18868
--- /dev/null
+++ b/modules/control-center-web/src/main/js/controllers/clusters-controller.js
@@ -0,0 +1,308 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+controlCenterModule.controller('clustersController', ['$scope', '$http', '$common', '$confirm', '$copy', '$table', function ($scope, $http, $common, $confirm, $copy, $table) {
+        $scope.joinTip = $common.joinTip;
+        $scope.getModel = $common.getModel;
+
+        $scope.tableReset = $table.tableReset;
+        $scope.tableNewItem = $table.tableNewItem;
+        $scope.tableNewItemActive = $table.tableNewItemActive;
+        $scope.tableEditing = $table.tableEditing;
+        $scope.tableStartEdit = $table.tableStartEdit;
+        $scope.tableRemove = $table.tableRemove;
+
+        $scope.tableSimpleSave = $table.tableSimpleSave;
+        $scope.tableSimpleSaveVisible = $table.tableSimpleSaveVisible;
+        $scope.tableSimpleUp = $table.tableSimpleUp;
+        $scope.tableSimpleDown = $table.tableSimpleDown;
+        $scope.tableSimpleDownVisible = $table.tableSimpleDownVisible;
+
+        $scope.templates = [
+            {value: {discovery: {kind: 'Multicast', Vm: {addresses: ['127.0.0.1:47500..47510']}, Multicast: {}}},label: 'multicast'},
+            {value: {discovery: {kind: 'Vm', Vm: {addresses: ['127.0.0.1:47500..47510']}}}, label: 'local'}
+        ];
+
+        $scope.discoveries = [
+            {value: 'Vm', label: 'static IPs'},
+            {value: 'Multicast', label: 'multicast'},
+            {value: 'S3', label: 'AWS S3'},
+            {value: 'Cloud', label: 'apache jclouds'},
+            {value: 'GoogleStorage', label: 'google cloud storage'},
+            {value: 'Jdbc', label: 'JDBC'},
+            {value: 'SharedFs', label: 'shared filesystem'}
+        ];
+
+        $scope.swapSpaceSpis = [
+            {value: 'FileSwapSpaceSpi', label: 'File-based swap'},
+            {value: undefined, label: 'Not set'}
+        ];
+
+        $scope.events = [];
+
+        for (var eventGroupName in eventGroups) {
+            if (eventGroups.hasOwnProperty(eventGroupName)) {
+                $scope.events.push({value: eventGroupName, label: eventGroupName});
+            }
+        }
+
+        $scope.cacheModes = [
+            {value: 'LOCAL', label: 'LOCAL'},
+            {value: 'REPLICATED', label: 'REPLICATED'},
+            {value: 'PARTITIONED', label: 'PARTITIONED'}
+        ];
+
+        $scope.deploymentModes = [
+            {value: 'PRIVATE', label: 'PRIVATE'},
+            {value: 'ISOLATED', label: 'ISOLATED'},
+            {value: 'SHARED', label: 'SHARED'},
+            {value: 'CONTINUOUS', label: 'CONTINUOUS'}
+        ];
+
+        $scope.transactionConcurrency = [
+            {value: 'OPTIMISTIC', label: 'OPTIMISTIC'},
+            {value: 'PESSIMISTIC', label: 'PESSIMISTIC'}
+        ];
+
+        $scope.transactionIsolation = [
+            {value: 'READ_COMMITTED', label: 'READ_COMMITTED'},
+            {value: 'REPEATABLE_READ', label: 'REPEATABLE_READ'},
+            {value: 'SERIALIZABLE', label: 'SERIALIZABLE'}
+        ];
+
+        $scope.segmentationPolicy = [
+            {value: 'RESTART_JVM', label: 'RESTART_JVM'},
+            {value: 'STOP', label: 'STOP'},
+            {value: 'NOOP', label: 'NOOP'}
+        ];
+
+        $scope.marshallers = [
+            {value: 'OptimizedMarshaller', label: 'OptimizedMarshaller'},
+            {value: 'JdkMarshaller', label: 'JdkMarshaller'}
+        ];
+
+        $scope.tableSimpleValid = function (item, field, val, index) {
+            var model = $common.getModel(item, field)[field.model];
+
+            if ($common.isDefined(model)) {
+                var idx = _.indexOf(model, val);
+
+                // Found itself.
+                if (index >= 0 && index == idx)
+                    return true;
+
+                // Found duplicate.
+                if (idx >= 0) {
+                    var msg = 'Such IP address already exists!';
+
+                    if (field.model == 'regions')
+                        msg = 'Such region already exists!';
+                    if (field.model == 'zones')
+                        msg = 'Such zone already exists!';
+
+                    $common.showError(msg);
+
+                    return false;
+                }
+            }
+
+            return true;
+        };
+
+        $scope.clusters = [];
+
+        $http.get('/models/clusters.json')
+            .success(function (data) {
+                $scope.screenTip = data.screenTip;
+                $scope.templateTip = data.templateTip;
+
+                $scope.general = data.general;
+                $scope.advanced = data.advanced;
+            })
+            .error(function (errMsg) {
+                $common.showError(errMsg);
+            });
+
+        // When landing on the page, get clusters and show them.
+        $http.post('clusters/list')
+            .success(function (data) {
+                $scope.caches = data.caches;
+                $scope.spaces = data.spaces;
+                $scope.clusters = data.clusters;
+
+                var restoredItem = angular.fromJson(sessionStorage.clusterBackupItem);
+
+                if (restoredItem) {
+                    if (restoredItem._id) {
+                        var idx = _.findIndex($scope.clusters, function (cluster) {
+                            return cluster._id == restoredItem._id;
+                        });
+
+                        if (idx >= 0) {
+                            $scope.selectedItem = $scope.clusters[idx];
+                            $scope.backupItem = restoredItem;
+                        }
+                        else
+                            sessionStorage.removeItem('clusterBackupItem');
+                    }
+                    else
+                        $scope.backupItem = restoredItem;
+                }
+                else if ($scope.clusters.length > 0)
+                    $scope.selectItem($scope.clusters[0]);
+
+                $scope.$watch('backupItem', function (val) {
+                    if (val)
+                        sessionStorage.clusterBackupItem = angular.toJson(val);
+                }, true);
+            })
+            .error(function (errMsg) {
+                $common.showError(errMsg);
+            });
+
+        $scope.selectItem = function (item) {
+            $table.tableReset();
+
+            $scope.selectedItem = item;
+            $scope.backupItem = angular.copy(item);
+        };
+
+        // Add new cluster.
+        $scope.createItem = function () {
+            $table.tableReset();
+
+            $scope.backupItem = angular.copy($scope.create.template);
+            $scope.backupItem.caches = [];
+            $scope.backupItem.space = $scope.spaces[0]._id;
+        };
+
+        $scope.indexOfCache = function (cacheId) {
+            return _.findIndex($scope.caches, function (cache) {
+                return cache.value == cacheId;
+            });
+        };
+
+        // Check cluster logical consistency.
+        function validate(item) {
+            if (!item.swapSpaceSpi || !item.swapSpaceSpi.kind && item.caches) {
+                for (var i = 0; i < item.caches.length; i++) {
+                    var idx = $scope.indexOfCache(item.caches[i]);
+
+                    if (idx >= 0) {
+                        var cache = $scope.caches[idx];
+
+                        if (cache.swapEnabled) {
+                            $common.showError('Swap space SPI is not configured, but cache "' + cache.label + '" configured to use swap!');
+
+                            return false;
+                        }
+                    }
+                }
+            }
+
+            return true;
+        }
+
+        // Save cluster in database.
+        function save(item) {
+            $http.post('clusters/save', item)
+                .success(function (_id) {
+                    var idx = _.findIndex($scope.clusters, function (cluster) {
+                        return cluster._id == _id;
+                    });
+
+                    if (idx >= 0)
+                        angular.extend($scope.clusters[idx], item);
+                    else {
+                        item._id = _id;
+
+                        $scope.clusters.push(item);
+                    }
+
+                    $scope.selectItem(item);
+
+                    $common.showInfo('Cluster "' + item.name + '" saved.');
+                })
+                .error(function (errMsg) {
+                    $common.showError(errMsg);
+                });
+        }
+
+        // Save cluster.
+        $scope.saveItem = function () {
+            $table.tableReset();
+
+            var item = $scope.backupItem;
+
+            if (validate(item))
+                save(item);
+        };
+
+        // Save cluster with new name.
+        $scope.saveItemAs = function () {
+            $table.tableReset();
+
+            if (validate($scope.backupItem))
+                $copy.show($scope.backupItem.name).then(function (newName) {
+                    var item = angular.copy($scope.backupItem);
+
+                    item._id = undefined;
+                    item.name = newName;
+
+                    save(item);
+                });
+        };
+
+        // Remove cluster from db.
+        $scope.removeItem = function () {
+            $table.tableReset();
+
+            var selectedItem = $scope.selectedItem;
+
+            $confirm.show('Are you sure you want to remove cluster: "' + selectedItem.name + '"?').then(
+                function () {
+                    var _id = selectedItem._id;
+
+                    $http.post('clusters/remove', {_id: _id})
+                        .success(function () {
+                            $common.showInfo('Cluster has been removed: ' + selectedItem.name);
+
+                            var clusters = $scope.clusters;
+
+                            var idx = _.findIndex(clusters, function (cluster) {
+                                return cluster._id == _id;
+                            });
+
+                            if (idx >= 0) {
+                                clusters.splice(idx, 1);
+
+                                if (clusters.length > 0)
+                                    $scope.selectItem(clusters[0]);
+                                else {
+                                    $scope.selectedItem = undefined;
+                                    $scope.backupItem = undefined;
+                                }
+                            }
+                        })
+                        .error(function (errMsg) {
+                            $common.showError(errMsg);
+                        });
+                }
+            );
+        };
+    }]
+);
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/96522874/modules/control-center-web/src/main/js/controllers/common-module.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/controllers/common-module.js b/modules/control-center-web/src/main/js/controllers/common-module.js
new file mode 100644
index 0000000..df2ff19
--- /dev/null
+++ b/modules/control-center-web/src/main/js/controllers/common-module.js
@@ -0,0 +1,484 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var controlCenterModule = angular.module('ignite-web-control-center', ['smart-table', 'mgcrea.ngStrap', 'ui.ace', 'ngSanitize']);
+
+// Modal popup configuration.
+controlCenterModule.config(function ($modalProvider) {
+    angular.extend($modalProvider.defaults, {
+        html: true
+    });
+});
+
+// Tooltips configuration.
+controlCenterModule.config(function ($tooltipProvider) {
+    angular.extend($tooltipProvider.defaults, {
+        container: 'body',
+        placement: 'right',
+        html: 'true',
+        trigger: 'click hover'
+    });
+});
+
+// Comboboxes configuration.
+controlCenterModule.config(function ($selectProvider) {
+    angular.extend($selectProvider.defaults, {
+        maxLength: '1',
+        allText: 'Select All',
+        noneText: 'Clear All',
+        templateUrl: '/select',
+        iconCheckmark: 'fa fa-check',
+        caretHtml: '<span class="caret"></span>'
+    });
+});
+
+// Alerts configuration.
+controlCenterModule.config(function ($alertProvider) {
+    angular.extend($alertProvider.defaults, {
+        container: 'body',
+        placement: 'top-right',
+        duration: '5',
+        type: 'danger'
+    });
+});
+
+// Common functions to be used in controllers.
+controlCenterModule.service('$common', ['$alert', function ($alert) {
+    var msgModal = undefined;
+
+    function errorMessage(errMsg) {
+        return errMsg ? errMsg : 'Internal server error.';
+    }
+
+    function isDefined(v) {
+        return !(v === undefined || v === null);
+    }
+
+    return {
+        getModel: function (obj, field) {
+            var path = field.path;
+
+            if (!isDefined(path))
+                return obj;
+
+            path = path.replace(/\[(\w+)\]/g, '.$1'); // convert indexes to properties
+            path = path.replace(/^\./, '');           // strip a leading dot
+
+            var segs = path.split('.');
+            var root = obj;
+
+            while (segs.length > 0) {
+                var pathStep = segs.shift();
+
+                if (typeof root[pathStep] === 'undefined')
+                    root[pathStep] = {};
+
+                root = root[pathStep];
+            }
+
+            return root;
+        },
+        joinTip: function (arr) {
+            if (!arr) {
+                return arr;
+            }
+
+            var lines = arr.map(function (line) {
+                var rtrimmed = line.replace(/\s+$/g, '');
+
+                if (rtrimmed.indexOf('>', this.length - 1) == -1) {
+                    rtrimmed = rtrimmed + '<br/>';
+                }
+
+                return rtrimmed;
+            });
+
+            return lines.join("");
+        },
+        isDefined: isDefined,
+        isNonEmpty: function (s) {
+            return isDefined(s) && s.trim().length > 0;
+        },
+        errorMessage: errorMessage,
+        showError: function (msg) {
+            if (msgModal)
+                msgModal.hide();
+
+            msgModal = $alert({title: errorMessage(msg)});
+        },
+        showInfo: function (msg) {
+            if (msgModal)
+                msgModal.hide();
+
+            msgModal = $alert({
+                type: 'success',
+                title: msg,
+                duration: 2
+            });
+        },
+        javaBuildInTypes: [
+            'Boolean', 'Byte', 'Date', 'Double', 'Float', 'Integer', 'Long', 'Short', 'String', 'Time', 'Timestamp', 'UUID'
+        ]
+    }
+}]);
+
+// Confirm popup service.
+controlCenterModule.service('$confirm', function ($modal, $rootScope, $q) {
+    var scope = $rootScope.$new();
+
+    var deferred;
+
+    scope.ok = function () {
+        deferred.resolve();
+
+        confirmModal.hide();
+    };
+
+    var confirmModal = $modal({templateUrl: '/confirm', scope: scope, placement: 'center', show: false});
+
+    var parentShow = confirmModal.show;
+
+    confirmModal.show = function (content) {
+        scope.content = content || 'Confirm deletion?';
+
+        deferred = $q.defer();
+
+        parentShow();
+
+        return deferred.promise;
+    };
+
+    return confirmModal;
+});
+
+// "Save as" popup service.
+controlCenterModule.service('$copy', function ($modal, $rootScope, $q) {
+    var scope = $rootScope.$new();
+
+    var deferred;
+
+    scope.ok = function (newName) {
+        deferred.resolve(newName);
+
+        copyModal.hide();
+    };
+
+    var copyModal = $modal({templateUrl: '/copy', scope: scope, placement: 'center', show: false});
+
+    var parentShow = copyModal.show;
+
+    copyModal.show = function (oldName) {
+        scope.newName = oldName + '(1)';
+
+        deferred = $q.defer();
+
+        parentShow();
+
+        return deferred.promise;
+    };
+
+    return copyModal;
+});
+
+// Tables support service.
+controlCenterModule.service('$table', ['$common', function ($common) {
+    function _swapSimpleItems(a, ix1, ix2) {
+        var tmp = a[ix1];
+
+        a[ix1] = a[ix2];
+        a[ix2] = tmp;
+    }
+
+    function _model(item, field) {
+        return $common.getModel(item, field);
+    }
+
+    var table = {name: 'none', editIndex: -1};
+
+    function _tableReset() {
+        table.name = 'none';
+        table.editIndex = -1;
+    }
+
+    function _tableState(name, editIndex) {
+        table.name = name;
+        table.editIndex = editIndex;
+    }
+
+    return {
+        tableState: function (name, editIndex) {
+            _tableState(name, editIndex);
+        },
+        tableReset: function () {
+            _tableReset();
+        },
+        tableNewItem: function (field) {
+            _tableState(field.model, -1);
+        },
+        tableNewItemActive: function (field) {
+            return table.name == field.model && table.editIndex < 0;
+        },
+        tableEditing: function (field, index) {
+            return table.name == field.model && table.editIndex == index;
+        },
+        tableStartEdit: function (item, field, index) {
+            _tableState(field.model, index);
+
+            return _model(item, field)[field.model][index];
+        },
+        tableRemove: function (item, field, index) {
+            _tableReset();
+
+            _model(item, field)[field.model].splice(index, 1);
+        },
+        tableSimpleSave: function (valueValid, item, field, newValue, index) {
+            if (valueValid(item, field, newValue, index)) {
+                _tableReset();
+
+                if (index < 0) {
+                    if (_model(item, field)[field.model])
+                        _model(item, field)[field.model].push(newValue);
+                    else
+                        _model(item, field)[field.model] = [newValue];
+                }
+                else
+                    _model(item, field)[field.model][index] = newValue;
+            }
+        },
+        tableSimpleSaveVisible: function (newValue) {
+            return $common.isNonEmpty(newValue);
+        },
+        tableSimpleUp: function (item, field, index) {
+            _tableReset();
+
+            _swapSimpleItems(_model(item, field)[field.model], index, index - 1);
+        },
+        tableSimpleDown: function (item, field, index) {
+            _tableReset();
+
+            _swapSimpleItems(_model(item, field)[field.model], index, index + 1);
+        },
+        tableSimpleDownVisible: function (item, field, index) {
+            return index < _model(item, field)[field.model].length - 1;
+        },
+        tablePairSave: function (pairValid, item, field, newKey, newValue, index) {
+            if (pairValid(item, field, newKey, newValue, index)) {
+                _tableReset();
+
+                var pair = {};
+
+                if (index < 0) {
+                    pair[field.keyName] = newKey;
+                    pair[field.valueName] = newValue;
+
+                    if (item[field.model])
+                        item[field.model].push(pair);
+                    else
+                        item[field.model] = [pair];
+                }
+                else {
+                    pair = item[field.model][index];
+
+                    pair[field.keyName] = newKey;
+                    pair[field.valueName] = newValue;
+                }
+            }
+        },
+        tablePairSaveVisible: function (newKey, newValue) {
+            return $common.isNonEmpty(newKey) && $common.isNonEmpty(newValue);
+        }
+    }
+}]);
+
+
+// Filter to decode name using map(value, label).
+controlCenterModule.filter('displayValue', function () {
+    return function (v, m, dflt) {
+        var i = _.findIndex(m, function (item) {
+            return item.value == v;
+        });
+
+        if (i >= 0) {
+            return m[i].label;
+        }
+
+        if (dflt) {
+            return dflt;
+        }
+
+        return 'Unknown value';
+    }
+});
+
+/**
+ * Filter for replacing all occurrences of {@code org.apache.ignite.} with {@code o.a.i.},
+ * {@code org.apache.ignite.internal.} with {@code o.a.i.i.},
+ * {@code org.apache.ignite.internal.visor.} with {@code o.a.i.i.v.} and
+ * {@code org.apache.ignite.scalar.} with {@code o.a.i.s.}.
+ *
+ * @param s String to replace in.
+ * @return Replaces string.
+ */
+controlCenterModule.filter('compact', function () {
+    return function (s) {
+        return s.replace("org.apache.ignite.internal.visor.", "o.a.i.i.v.").
+            replace("org.apache.ignite.internal.", "o.a.i.i.").
+            replace("org.apache.ignite.scalar.", "o.a.i.s.").
+            replace("org.apache.ignite.", "o.a.i.");
+    }
+});
+
+// Directive to enable validation for IP addresses.
+controlCenterModule.directive('ipaddress', function () {
+    const ip = '(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])';
+    const port = '([0-9]{1,4}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])';
+    const portRange = '(:' + port + '(..' + port + ')?)?';
+    const host = '(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])';
+
+    return {
+        require: 'ngModel',
+        link: function (scope, elem, attrs, ctrl) {
+            ctrl.$validators.ipaddress = function (modelValue, viewValue) {
+                if (ctrl.$isEmpty(modelValue) || !attrs['ipaddress'])
+                    return true;
+
+                return viewValue.match(new RegExp('(^' + ip + portRange + '$)|(^' + host + portRange + '$)')) != null;
+            }
+        }
+    }
+});
+
+// Directive to enable validation to match specified value.
+controlCenterModule.directive('match', function ($parse) {
+    return {
+        require: 'ngModel',
+        link: function (scope, elem, attrs, ctrl) {
+            scope.$watch(function () {
+                return $parse(attrs.match)(scope) === ctrl.$modelValue;
+            }, function (currentValue) {
+                ctrl.$setValidity('mismatch', currentValue);
+            });
+        }
+    };
+});
+
+// Directive to bind ENTER key press with some user action.
+controlCenterModule.directive('ngEnter', function() {
+    return function(scope, element, attrs) {
+        element.bind('keydown keypress', function(event) {
+            if (event.which === 13) {
+                scope.$apply(function() {
+                    scope.$eval(attrs.ngEnter);
+                });
+
+                event.preventDefault();
+            }
+        });
+    };
+});
+
+// Directive to bind ESC key press with some user action.
+controlCenterModule.directive('ngEscape', function() {
+    return function(scope, element, attrs) {
+        element.bind('keydown keyup', function(event) {
+            if (event.which === 27) {
+                scope.$apply(function() {
+                    scope.$eval(attrs.ngEscape);
+                });
+
+                event.preventDefault();
+            }
+        });
+    };
+});
+
+// Factory function to focus element.
+controlCenterModule.factory('focus', function ($timeout, $window) {
+    return function (id) {
+        // Timeout makes sure that is invoked after any other event has been triggered.
+        // E.g. click events that need to run before the focus or inputs elements that are
+        // in a disabled state but are enabled when those events are triggered.
+        $timeout(function () {
+            var element = $window.document.getElementById(id);
+
+            if (element)
+                element.focus();
+        });
+    };
+});
+
+// Directive to mark elements to focus.
+controlCenterModule.directive('eventFocus', function (focus) {
+    return function (scope, elem, attr) {
+        elem.on(attr.eventFocus, function () {
+            focus(attr.eventFocusId);
+        });
+
+        // Removes bound events in the element itself when the scope is destroyed
+        scope.$on('$destroy', function () {
+            element.off(attr.eventFocus);
+        });
+    };
+});
+
+// Navigation bar controller.
+controlCenterModule.controller('activeLink', [
+    '$scope', function ($scope) {
+        $scope.isActive = function (path) {
+            return window.location.pathname.substr(0, path.length) == path;
+        };
+    }]);
+
+// Login popup controller.
+controlCenterModule.controller('auth', [
+    '$scope', '$modal', '$alert', '$http', '$window', '$common',
+    function ($scope, $modal, $alert, $http, $window, $common) {
+        $scope.errorMessage = $common.errorMessage;
+
+        $scope.action = 'login';
+
+        $scope.valid = false;
+
+        $scope.userDropdown = [{"text": "Profile", "href": "/profile"}];
+
+        if (!$scope.becomeUsed) {
+            if ($scope.user && $scope.user.admin)
+                $scope.userDropdown.push({"text": "Admin Panel", "href": "/admin"});
+
+            $scope.userDropdown.push({"text": "Log Out", "href": "/logout"});
+        }
+
+        // Pre-fetch an external template populated with a custom scope
+        var authModal = $modal({scope: $scope, templateUrl: '/login', show: false});
+
+        $scope.login = function () {
+            // Show when some event occurs (use $promise property to ensure the template has been loaded)
+            authModal.$promise.then(authModal.show);
+        };
+
+        $scope.auth = function (action, user_info) {
+            $http.post('/' + action, user_info)
+                .success(function () {
+                    authModal.hide();
+
+                    $window.location = '/configuration/clusters';
+                })
+                .error(function (data) {
+                    $alert({placement: 'top', container: '#errors-container', title: $scope.errorMessage(data)});
+                });
+        };
+    }]);
\ No newline at end of file


[09/41] incubator-ignite git commit: Added putAll benchmarks.

Posted by an...@apache.org.
Added putAll benchmarks.


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

Branch: refs/heads/ignite-1121
Commit: 5304e6ee47970c6989784a2ab47f875437883cfa
Parents: f22de3e
Author: nikolay_tikhonov <nt...@gridgain.com>
Authored: Mon Jul 27 13:46:47 2015 +0300
Committer: nikolay_tikhonov <nt...@gridgain.com>
Committed: Mon Jul 27 13:46:47 2015 +0300

----------------------------------------------------------------------
 modules/yardstick/config/benchmark.properties   |  6 +-
 .../yardstick/IgniteBenchmarkArguments.java     | 22 +++++++
 .../yardstick/cache/IgnitePutAllBenchmark.java  | 67 +++++++++++++++++++
 .../cache/IgnitePutAllTxBenchmark.java          | 68 ++++++++++++++++++++
 4 files changed, 162 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/5304e6ee/modules/yardstick/config/benchmark.properties
----------------------------------------------------------------------
diff --git a/modules/yardstick/config/benchmark.properties b/modules/yardstick/config/benchmark.properties
index edda9ee..d691f1e 100644
--- a/modules/yardstick/config/benchmark.properties
+++ b/modules/yardstick/config/benchmark.properties
@@ -86,5 +86,9 @@ CONFIGS="\
 -cfg ${SCRIPT_DIR}/../config/ignite-localhost-config.xml -nn ${nodesNum} -b 1 -w 60 -d 300 -t 64 -sm PRIMARY_SYNC -dn IgnitePutTxOffHeapValuesBenchmark -sn IgniteNode -ds ${ver}tx-put-offheap-val-1-backup,\
 -cfg ${SCRIPT_DIR}/../config/ignite-localhost-config.xml -nn ${nodesNum} -b 1 -w 60 -d 300 -t 64 -sm PRIMARY_SYNC -dn IgniteSqlQueryOffHeapBenchmark -sn IgniteNode -ds ${ver}sql-query-offheap-1-backup,\
 -cfg ${SCRIPT_DIR}/../config/ignite-localhost-config.xml -nn ${nodesNum} -b 1 -w 60 -d 300 -t 64 -sm PRIMARY_SYNC -dn IgniteSqlQueryJoinOffHeapBenchmark -sn IgniteNode -ds ${ver}sql-query-join-offheap-1-backup,\
--cfg ${SCRIPT_DIR}/../config/ignite-localhost-config.xml -nn ${nodesNum} -b 1 -w 60 -d 300 -t 64 -sm PRIMARY_SYNC -dn IgniteSqlQueryPutOffHeapBenchmark -sn IgniteNode -ds ${ver}sql-query-put-offheap-1-backup\
+-cfg ${SCRIPT_DIR}/../config/ignite-localhost-config.xml -nn ${nodesNum} -b 1 -w 60 -d 300 -t 64 -sm PRIMARY_SYNC -dn IgniteSqlQueryPutOffHeapBenchmark -sn IgniteNode -ds ${ver}sql-query-put-offheap-1-backup,\
+-cfg ${SCRIPT_DIR}/../config/ignite-localhost-config.xml -nn ${nodesNum} -b 1 -w 60 -d 300 -t 64 -bs 1000 -sm PRIMARY_SYNC -dn IgnitePutAllBenchmark -sn IgniteNode -ds ${ver}atomic-putAll-1-backup,\
+-cfg ${SCRIPT_DIR}/../config/ignite-localhost-config.xml -nn ${nodesNum} -b 1 -w 60 -d 300 -t 64 -bs 1000 -col -sm PRIMARY_SYNC -dn IgnitePutAllBenchmark -sn IgniteNode -ds ${ver}atomic-collocated-putAll-1-backup,\
+-cfg ${SCRIPT_DIR}/../config/ignite-localhost-config.xml -nn ${nodesNum} -b 1 -w 60 -d 300 -t 64 -bs 1000 -sm PRIMARY_SYNC -dn IgnitePutAllTxBenchmark -sn IgniteNode -ds ${ver}atomic-putAll-tx-1-backup,\
+-cfg ${SCRIPT_DIR}/../config/ignite-localhost-config.xml -nn ${nodesNum} -b 1 -w 60 -d 300 -t 64 -bs 1000 -col -sm PRIMARY_SYNC -dn IgnitePutAllTxBenchmark -sn IgniteNode -ds ${ver}atomic-collocated-putAll-tx-1-backup\
 "

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/5304e6ee/modules/yardstick/src/main/java/org/apache/ignite/yardstick/IgniteBenchmarkArguments.java
----------------------------------------------------------------------
diff --git a/modules/yardstick/src/main/java/org/apache/ignite/yardstick/IgniteBenchmarkArguments.java b/modules/yardstick/src/main/java/org/apache/ignite/yardstick/IgniteBenchmarkArguments.java
index b21bed3..1562b26 100644
--- a/modules/yardstick/src/main/java/org/apache/ignite/yardstick/IgniteBenchmarkArguments.java
+++ b/modules/yardstick/src/main/java/org/apache/ignite/yardstick/IgniteBenchmarkArguments.java
@@ -98,6 +98,14 @@ public class IgniteBenchmarkArguments {
     @Parameter(names = {"-wb", "--writeBehind"}, description = "Enable or disable writeBehind for cache store")
     private boolean writeBehind;
 
+    /** */
+    @Parameter(names = {"-bs", "--batchSize"}, description = "Batch size")
+    private int batch = 500;
+
+    /** */
+    @Parameter(names = {"-col", "--collocated"}, description = "Collocated")
+    private boolean collocated;
+
     /**
      * @return Transaction concurrency.
      */
@@ -232,6 +240,20 @@ public class IgniteBenchmarkArguments {
     }
 
     /**
+     * @return Batch size.
+     */
+    public int batch() {
+        return batch;
+    }
+
+    /**
+     * @return Collocated.
+     */
+    public boolean collocated() {
+        return collocated;
+    }
+
+    /**
      * @return Description.
      */
     public String description() {

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/5304e6ee/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/IgnitePutAllBenchmark.java
----------------------------------------------------------------------
diff --git a/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/IgnitePutAllBenchmark.java b/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/IgnitePutAllBenchmark.java
new file mode 100644
index 0000000..6b30875
--- /dev/null
+++ b/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/IgnitePutAllBenchmark.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.yardstick.cache;
+
+import org.apache.ignite.*;
+import org.apache.ignite.cache.affinity.*;
+import org.apache.ignite.cluster.*;
+import org.yardstickframework.*;
+
+import java.util.*;
+
+/**
+ * Ignite benchmark that performs putAll operations.
+ */
+public class IgnitePutAllBenchmark extends IgniteCacheAbstractBenchmark {
+    /** Affinity mapper. */
+    private Affinity<Integer> aff;
+
+    /** {@inheritDoc} */
+    @Override public void setUp(BenchmarkConfiguration cfg) throws Exception {
+        super.setUp(cfg);
+
+        aff = ignite().affinity("atomic");
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean test(Map<Object, Object> ctx) throws Exception {
+        SortedMap<Integer, Integer> vals = new TreeMap<>();
+
+        ClusterNode node = args.collocated() ? aff.mapKeyToNode(nextRandom(args.range())) : null;
+
+        for (int i = 0; i < args.batch(); ) {
+            int key = nextRandom(args.range());
+
+            if (args.collocated() && !aff.isPrimary(node, key))
+                continue;
+
+            ++i;
+
+            vals.put(key, key);
+        }
+
+        cache.putAll(vals);
+
+        return true;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected IgniteCache<Integer, Object> cache() {
+        return ignite().cache("atomic");
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/5304e6ee/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/IgnitePutAllTxBenchmark.java
----------------------------------------------------------------------
diff --git a/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/IgnitePutAllTxBenchmark.java b/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/IgnitePutAllTxBenchmark.java
new file mode 100644
index 0000000..01890c9
--- /dev/null
+++ b/modules/yardstick/src/main/java/org/apache/ignite/yardstick/cache/IgnitePutAllTxBenchmark.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.yardstick.cache;
+
+import org.apache.ignite.*;
+import org.apache.ignite.cache.affinity.*;
+import org.apache.ignite.cluster.*;
+import org.yardstickframework.*;
+
+import java.util.*;
+
+/**
+ * Ignite benchmark that performs transactional putAll operations.
+ */
+public class IgnitePutAllTxBenchmark extends IgniteCacheAbstractBenchmark {
+    /** Affinity mapper. */
+    private Affinity<Integer> aff;
+
+    /** {@inheritDoc} */
+    @Override public void setUp(BenchmarkConfiguration cfg) throws Exception {
+        super.setUp(cfg);
+
+        aff = ignite().affinity("tx");
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean test(Map<Object, Object> ctx) throws Exception {
+        SortedMap<Integer, Integer> vals = new TreeMap<>();
+
+        ClusterNode node = args.collocated() ? aff.mapKeyToNode(nextRandom(args.range())) : null;
+
+        for (int i = 0; i < args.batch(); ) {
+            int key = nextRandom(args.range());
+
+            if (args.collocated() && !aff.isPrimary(node, key))
+                continue;
+
+            ++i;
+
+            vals.put(key, key);
+        }
+
+        // Implicit transaction is used.
+        cache.putAll(vals);
+
+        return true;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected IgniteCache<Integer, Object> cache() {
+        return ignite().cache("tx");
+    }
+}


[26/41] incubator-ignite git commit: # ignite-1148 Added sql tab.

Posted by an...@apache.org.
# ignite-1148 Added sql tab.


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

Branch: refs/heads/ignite-1121
Commit: 94bb0d9587b0479cd64c48496e500c570fa6350a
Parents: f621c3e
Author: Andrey <an...@gridgain.com>
Authored: Wed Jul 29 10:27:57 2015 +0700
Committer: Andrey <an...@gridgain.com>
Committed: Wed Jul 29 10:27:57 2015 +0700

----------------------------------------------------------------------
 modules/nodejs/src/main/js/cache.js             |  13 ++
 .../src/main/js/agents/agent-manager.js         |   4 +-
 .../src/main/js/controllers/sql-controller.js   | 131 +++++++++++++------
 .../src/main/js/routes/agent.js                 |  57 +++++++-
 .../src/main/js/views/sql.jade                  |  70 ----------
 .../src/main/js/views/sql/sql.jade              |  31 +++--
 .../src/main/js/views/templates/layout.jade     |   2 +-
 7 files changed, 171 insertions(+), 137 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/94bb0d95/modules/nodejs/src/main/js/cache.js
----------------------------------------------------------------------
diff --git a/modules/nodejs/src/main/js/cache.js b/modules/nodejs/src/main/js/cache.js
index 1600eaa..e9db1b3 100644
--- a/modules/nodejs/src/main/js/cache.js
+++ b/modules/nodejs/src/main/js/cache.js
@@ -421,6 +421,19 @@ QueryCursor.prototype.page = function() {
 }
 
 /**
+ * Gets queryId of the query.
+ *
+ * @this{QueryCursor}
+ * @returns {Object} Query id may be null.
+ */
+QueryCursor.prototype.queryId = function() {
+    if (this.isFinished())
+        return undefined;
+
+    return this._res.queryId;
+}
+
+/**
  * Closes all resources related to this cursor.
  *
  * @this{QueryCursor}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/94bb0d95/modules/web-control-center/src/main/js/agents/agent-manager.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/agents/agent-manager.js b/modules/web-control-center/src/main/js/agents/agent-manager.js
index 252b984..10d3a56 100644
--- a/modules/web-control-center/src/main/js/agents/agent-manager.js
+++ b/modules/web-control-center/src/main/js/agents/agent-manager.js
@@ -17,7 +17,7 @@
 
 var WebSocketServer = require('ws').Server;
 
-var ignite = require('apache-ignite');
+var apacheIgnite = require('apache-ignite');
 
 var db = require('../db');
 
@@ -216,7 +216,7 @@ Client.prototype._handleMessage = function(msg) {
 
                             self._manager._addClient(account._id, self);
 
-                            self._ignite = new ignite.Ignite(new AgentServer(self));
+                            self._ignite = new apacheIgnite.Ignite(new AgentServer(self));
                         }
                     });
                 }

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/94bb0d95/modules/web-control-center/src/main/js/controllers/sql-controller.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/controllers/sql-controller.js b/modules/web-control-center/src/main/js/controllers/sql-controller.js
index 12772c6..b4b4335 100644
--- a/modules/web-control-center/src/main/js/controllers/sql-controller.js
+++ b/modules/web-control-center/src/main/js/controllers/sql-controller.js
@@ -15,63 +15,32 @@
  * limitations under the License.
  */
 
-var demoResults = [
-    {
-        id: 256,
-        firstName: 'Ivan',
-        lastName: 'Ivanov'
-    },
-    {
-        id: 384,
-        firstName: 'Sergey',
-        lastName: 'Petrov'
-    },
-    {
-        id: 923,
-        firstName: 'Andrey',
-        lastName: 'Sidorov'
-    }
-];
-
-var demoCaches = [{_id: '1', name: 'Users', mode: 'LOCAL'}, {_id: '2', name: 'Organizations', mode: 'REPLICATED'}, {_id: '3', name: 'Cities', mode: 'PARTITIONED'}];
-
-
-
 controlCenterModule.controller('sqlController', ['$scope', '$http', '$common', function ($scope, $http, $common) {
     $scope.joinTip = $common.joinTip;
 
     $scope.pageSizes = [50, 100, 200, 400, 800, 1000];
 
-    $scope.tabs = [
-        {
-            query: "SELECT u.id, u.firstName, u.lastName FROM User u WHERE u.name LIKE 'aaaa'",
-            cols: Object.keys(demoResults[0]),
-            page: 1,
-            hasMore: true,
-            total: 0,
-            rows: demoResults
-        },
-        {query: "SELECT * FROM Organization"}
+    $scope.modes = [
+        {value: 'PARTITIONED', label: 'PARTITIONED'},
+        {value: 'REPLICATED', label: 'REPLICATED'},
+        {value: 'LOCAL', label: 'LOCAL'}
     ];
 
+    $scope.tabs = [];
+
     $scope.addTab = function() {
-        console.log('addTab');
+        var tab = {query: "", pageSize: $scope.pageSizes[0]};
+
+        if ($scope.caches.length > 0)
+            tab.selectedItem = $scope.caches[0];
 
-        $scope.tabs.push({query: "SELECT "});
+        $scope.tabs.push(tab);
     };
 
     $scope.removeTab = function(idx) {
-        console.log('removeTab');
-
         $scope.tabs.splice(idx, 1);
     };
 
-    $scope.modes = [
-        {value: 'PARTITIONED', label: 'PARTITIONED'},
-        {value: 'REPLICATED', label: 'REPLICATED'},
-        {value: 'LOCAL', label: 'LOCAL'}
-    ];
-
     $http.get('/models/sql.json')
         .success(function (data) {
             $scope.screenTip = data.screenTip;
@@ -80,5 +49,81 @@ controlCenterModule.controller('sqlController', ['$scope', '$http', '$common', f
             $common.showError(errMsg);
         });
 
-    $scope.caches = demoCaches;
+    $scope.caches = [];
+
+    $http.post('/agent/topology')
+        .success(function (clusters) {
+            var node = clusters[0];
+
+            $scope.caches = node.caches;
+
+            if ($scope.tabs.length == 0)
+                $scope.addTab();
+        })
+        .error(function (errMsg) {
+            $common.showError(errMsg);
+        });
+
+    $scope.execute = function(tab) {
+        $http.post('/agent/query', {query: tab.query, pageSize: tab.pageSize, cacheName: tab.selectedItem.name})
+            .success(function (res) {
+                tab.meta = [];
+
+                if (res.meta)
+                    tab.meta = res.meta;
+
+                tab.page = 1;
+
+                tab.total = 0;
+
+                tab.queryId = res.queryId;
+
+                tab.rows = res.rows;
+            })
+            .error(function (errMsg) {
+                $common.showError(errMsg);
+            });
+    };
+
+    $scope.explain = function(tab) {
+        $http.post('/agent/query', {query: 'EXPLAIN ' + tab.query, pageSize: tab.pageSize, cacheName: tab.selectedItem.name})
+            .success(function (res) {
+                tab.meta = [];
+
+                if (res.meta)
+                    tab.meta = res.meta;
+
+                tab.page = 1;
+
+                tab.total = 0;
+
+                tab.queryId = res.queryId;
+
+                tab.rows = res.rows;
+            })
+            .error(function (errMsg) {
+                $common.showError(errMsg);
+            });
+    };
+
+    $scope.nextPage = function(tab) {
+        $http.post('/agent/next_page', {queryId: tab.queryId, pageSize: tab.pageSize, cacheName: tab.selectedItem.name})
+            .success(function (res) {
+                tab.page++;
+
+                tab.total += tab.rows.length;
+
+                tab.rows = res.rows;
+
+                if (res.last)
+                    delete tab.queryId;
+            })
+            .error(function (errMsg) {
+                $common.showError(errMsg);
+            });
+    };
+
+    $scope.getter = function (value) {
+        return value;
+    }
 }]);

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/94bb0d95/modules/web-control-center/src/main/js/routes/agent.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/routes/agent.js b/modules/web-control-center/src/main/js/routes/agent.js
index 19379e2..4646c28 100644
--- a/modules/web-control-center/src/main/js/routes/agent.js
+++ b/modules/web-control-center/src/main/js/routes/agent.js
@@ -18,20 +18,67 @@
 var router = require('express').Router();
 var agentManager = require('../agents/agent-manager');
 
+var apacheIgnite = require('apache-ignite');
+var SqlFieldsQuery = apacheIgnite.SqlFieldsQuery;
+
 /* GET summary page. */
 router.post('/topology', function(req, res) {
-    var c = agentManager.getAgentManager().getOneClient();
+    var client = agentManager.getAgentManager().getOneClient();
 
-    if (!c)
+    if (!client)
         return res.status(500).send("Client not found");
 
-    var ignite = c.ignite();
+    client.ignite().cluster().then(function (clusters) {
+        res.json(clusters.map(function (cluster) {
+            var caches = Object.keys(cluster._caches).map(function(key) {
+                return {"name" : key, "mode" : cluster._caches[key] }
+            });
 
-    ignite.cluster().then(function (cluster) {
-        res.json(cluster);
+            return { nodeId: cluster._nodeId, caches: caches };
+        }));
     }, function (err) {
         res.send(err);
     });
 });
 
+/* GET summary page. */
+router.post('/query', function(req, res) {
+    var client = agentManager.getAgentManager().getOneClient();
+
+    if (!client)
+        return res.status(500).send("Client not found");
+
+    // Create sql query.
+    var qry = new SqlFieldsQuery(req.body.query);
+
+    // Set page size for query.
+    qry.setPageSize(req.body.pageSize);
+
+    // Get query cursor.
+    client.ignite().cache(req.body.cacheName).query(qry).nextPage().then(function (cursor) {
+        res.json({meta: cursor.fieldsMetadata(), rows: cursor.page(), queryId: cursor.queryId()});
+    }, function (err) {
+        res.status(500).send(err);
+    });
+});
+
+/* GET summary page. */
+router.post('/next_page', function(req, res) {
+    var client = agentManager.getAgentManager().getOneClient();
+
+    if (!client)
+        return res.status(500).send("Client not found");
+
+    var cache = client.ignite().cache(req.body.cacheName);
+
+    var cmd = cache._createCommand("qryfetch").addParam("qryId", req.body.queryId).
+        addParam("psz", req.body.pageSize);
+
+    cache.__createPromise(cmd).then(function (page) {
+        res.json({rows: page["items"], last: page === null || page["last"]});
+    }, function (err) {
+        res.status(500).send(err);
+    });
+});
+
 module.exports = router;

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/94bb0d95/modules/web-control-center/src/main/js/views/sql.jade
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/views/sql.jade b/modules/web-control-center/src/main/js/views/sql.jade
deleted file mode 100644
index 9ba3056..0000000
--- a/modules/web-control-center/src/main/js/views/sql.jade
+++ /dev/null
@@ -1,70 +0,0 @@
-//-
-    Licensed to the Apache Software Foundation (ASF) under one or more
-    contributor license agreements.  See the NOTICE file distributed with
-    this work for additional information regarding copyright ownership.
-    The ASF licenses this file to You under the Apache License, Version 2.0
-    (the "License"); you may not use this file except in compliance with
-    the License.  You may obtain a copy of the License at
-         http://www.apache.org/licenses/LICENSE-2.0
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
-extends ../templates/layout
-
-append scripts
-    script(src='/sql-controller.js')
-
-    script(src='//cdnjs.cloudflare.com/ajax/libs/ace/1.2.0/theme-chrome.js')
-    script(src='//cdnjs.cloudflare.com/ajax/libs/ace/1.2.0/mode-sql.js')
-    script(src='//cdnjs.cloudflare.com/ajax/libs/ace/1.2.0/ext-language_tools.js')
-
-block container
-    .row
-        .col-sm-12
-            .docs-content
-                .docs-header
-                    h1 Connect to Ignite and execute SQL queries
-                    hr
-                .docs-body(ng-controller='sqlController')
-                    .block-callout
-                        p(ng-bind-html='joinTip(screenTip)')
-                    .tabs-below(bs-tabs bs-active-pane='tabs.activeTab')
-                        div(title='Query #1' bs-pane)
-                            .row
-                                .col-sm-9
-                                    div(style='height: 200px' ui-ace='{ theme: "chrome", mode: "sql",' +
-                                        'require: ["ace/ext/language_tools"],' +
-                                        'rendererOptions: {showPrintMargin: false, highlightGutterLine: false, fontSize: 14},' +
-                                        'advanced: {enableSnippets: false, enableBasicAutocompletion: true, enableLiveAutocompletion: true}}'  ng-model='query')
-                                .col-sm-3
-                                    .links(ng-hide='caches.length == 0' style='margin-top: 0.65em')
-                                        lable.labelHeader Caches:
-                                        table(st-table='caches')
-                                            tbody
-                                                tr(ng-repeat='row in caches track by row._id')
-                                                    td.col-sm-6(ng-class='{active: row._id == selectedItem._id}')
-                                                        a(ng-click='selectItem(row)') {{$index + 1}}) {{row.name}}, {{row.mode | displayValue:modes:'Cache mode not set'}}
-                        div(title='Query #2' bs-pane)
-                            .row
-                    .settings-row
-                        button.btn.btn-primary(ng-click='') Explain
-                        button.btn.btn-primary(ng-click='') Execute
-                        button.btn.btn-primary(ng-click='' disabled) Scan
-                    //#resultPanel
-                    //    strong Results
-                    //
-                    //    #queryResult
-                    //        div(ng-repeat='r in results')
-                    //            .resultRow
-                    //                | {{r.id}} -> {{r.s}}
-                    //                span.props  {{r.fields}}
-
-                    div(ng-hide='results.length == 0' style='margin-top: 0.65em')
-                        lable.labelHeader Results:
-                        table.table-bordered(st-table='results')
-                            tbody
-                                tr(ng-repeat='row in results')
-                                    td
-                                        a(ng-click='selectItem(row)') {{$index + 1}}) {{row.name}}, {{row.mode | displayValue:modes:'Cache mode not set'}}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/94bb0d95/modules/web-control-center/src/main/js/views/sql/sql.jade
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/views/sql/sql.jade b/modules/web-control-center/src/main/js/views/sql/sql.jade
index 97d34de..2ce6958 100644
--- a/modules/web-control-center/src/main/js/views/sql/sql.jade
+++ b/modules/web-control-center/src/main/js/views/sql/sql.jade
@@ -46,40 +46,39 @@ block container
                                 lable.labelHeader Caches:
                                 table.links(st-table='caches')
                                     tbody
-                                        tr(ng-repeat='row in caches track by row._id')
-                                            td.col-sm-6(ng-class='{active: row._id == #{tab}.selectedItem._id}')
-                                                a(ng-click='#{tab}.selectedItem = row') {{$index + 1}}) {{row.name}}, {{row.mode | displayValue:modes:'Cache mode not set'}}
+                                        tr(ng-repeat='row in caches track by row.name')
+                                            td.col-sm-6(ng-class='{active: row.name == #{tab}.selectedItem.name}')
+                                                a(ng-click='#{tab}.selectedItem = row') {{$index + 1}}) {{::row.name}}, {{::row.mode}}
                     hr(style='margin: 0')
                     .settings-row
                         label Page Size:&nbsp;
-                        button.btn.btn-default.base-control(ng-init='pageSize = pageSizes[0]' ng-model='pageSize' bs-options='item for item in pageSizes' bs-select)
+                        button.btn.btn-default.base-control(ng-model='#{tab}.pageSize' bs-options='item for item in pageSizes' bs-select)
                     .settings-row
-                        button.btn.btn-primary(ng-click='') Explain
-                        button.btn.btn-primary(ng-click='') Execute
-                        button.btn.btn-primary(ng-click='' disabled) Scan
+                        button.btn.btn-primary(ng-click='explain(#{tab})') Explain
+                        button.btn.btn-primary(ng-click='execute(#{tab})') Execute
+                        button.btn.btn-primary(ng-click='scan(#{tab})' disabled) Scan
 
                     div(ng-show='#{tab}.rows.length > 0' style='margin-top: 0.65em')
                         hr
                         div
-                            table.table.table-striped.col-sm-12.sql-results(st-table='rows' st-safe-src='#{tab}.rows')
+                            table.table.table-striped.col-sm-12.sql-results(st-table='displayedCollection' st-safe-src='#{tab}.rows')
                                 thead
                                     tr(style='border-size: 0')
-                                        td(colspan='{{#{tab}.cols.length}}')
+                                        td(colspan='{{#{tab}.meta.length}}')
                                             .col-sm-8
                                                 lable Page #:&nbsp;
                                                 b {{#{tab}.page}}&nbsp;&nbsp;&nbsp;
                                                 | Results:&nbsp;
                                                 b {{#{tab}.rows.length + #{tab}.total}}
                                             .col-sm-4
-                                                button.btn.btn-primary.fieldButton(ng-click='') Next page
-                                                .input-tip
-                                                    input.form-control(type='text' st-search='' placeholder='Filter...')
-
+                                                button.btn.btn-primary.fieldButton(ng-click='nextPage(#{tab})' ng-disabled='!#{tab}.queryId') Next page
+                                                //.input-tip
+                                                //    input.form-control(st-search placeholder='Filter...' type='search')
                                     tr
-                                        th(ng-repeat='column in #{tab}.cols' st-sort='{{column}}') {{column}}
+                                        th(ng-repeat='col in #{tab}.meta track by $index' st-sort='getter' data-ng-bind='::col.fieldName' bs-tooltip='col.schemaName + "." + col.typeName + "." + col.fieldName')
                                 tbody
                                     //tr
                                     //    td(colspan='{{#{tab}.cols.length}}')
                                     //        .loading-indicator
-                                    tr(ng-repeat='row in rows')
-                                        td(ng-repeat='column in #{tab}.cols') {{row[column]}}
\ No newline at end of file
+                                    tr(ng-repeat='row in displayedCollection track by $index')
+                                        td(ng-repeat='val in row track by $index') {{ val }}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/94bb0d95/modules/web-control-center/src/main/js/views/templates/layout.jade
----------------------------------------------------------------------
diff --git a/modules/web-control-center/src/main/js/views/templates/layout.jade b/modules/web-control-center/src/main/js/views/templates/layout.jade
index 71d8936..8e92edb 100644
--- a/modules/web-control-center/src/main/js/views/templates/layout.jade
+++ b/modules/web-control-center/src/main/js/views/templates/layout.jade
@@ -41,7 +41,7 @@ html(ng-app='ignite-web-control-center' ng-init='user = #{JSON.stringify(user)};
             script(src='//cdnjs.cloudflare.com/ajax/libs/angular-strap/2.3.0/angular-strap.js')
             script(src='//cdnjs.cloudflare.com/ajax/libs/angular-strap/2.3.0/angular-strap.tpl.min.js')
 
-            script(src='//cdnjs.cloudflare.com/ajax/libs/angular-smart-table/2.0.3/smart-table.js')
+            script(src='//cdnjs.cloudflare.com/ajax/libs/angular-smart-table/2.1.1/smart-table.js')
 
             script(src='//cdnjs.cloudflare.com/ajax/libs/ace/1.2.0/ace.js')
             script(src='//angular-ui.github.io/ui-ace/dist/ui-ace.min.js')


[38/41] incubator-ignite git commit: # ignite-1121 Add install npm and node.js through maven.

Posted by an...@apache.org.
# ignite-1121 Add install npm and node.js through maven.


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

Branch: refs/heads/ignite-1121
Commit: 89220b19a3de2e48633b8248d94a055a640e5be0
Parents: 94bb0d9
Author: Andrey <an...@gridgain.com>
Authored: Wed Jul 29 13:43:54 2015 +0700
Committer: Andrey <an...@gridgain.com>
Committed: Wed Jul 29 13:43:54 2015 +0700

----------------------------------------------------------------------
 modules/control-center-web/pom.xml | 69 +++++++++++++++++++++++++++++++++
 1 file changed, 69 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/89220b19/modules/control-center-web/pom.xml
----------------------------------------------------------------------
diff --git a/modules/control-center-web/pom.xml b/modules/control-center-web/pom.xml
new file mode 100644
index 0000000..eb71764
--- /dev/null
+++ b/modules/control-center-web/pom.xml
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+
+<!--
+    POM file.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.ignite</groupId>
+        <artifactId>ignite-parent</artifactId>
+        <version>1</version>
+        <relativePath>../../parent</relativePath>
+    </parent>
+
+    <artifactId>ignite-control-center-web</artifactId>
+    <version>1.4.1-SNAPSHOT</version>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>com.github.eirslett</groupId>
+                <artifactId>frontend-maven-plugin</artifactId>
+                <version>0.0.23</version>
+
+                <configuration>
+                    <workingDirectory>src/main/js</workingDirectory>
+                </configuration>
+
+                <executions>
+                    <execution>
+                        <id>install node and npm</id>
+                        <goals>
+                            <goal>install-node-and-npm</goal>
+                        </goals>
+                        <configuration>
+                            <nodeVersion>v0.12.7</nodeVersion>
+                            <npmVersion>2.13.2</npmVersion>
+                        </configuration>
+                    </execution>
+
+                    <execution>
+                        <id>npm install</id>
+                        <goals>
+                            <goal>npm</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+</project>
\ No newline at end of file