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/10/13 05:28:08 UTC

[07/18] ignite git commit: IGNITE-843 Web console initial commit.

http://git-wip-us.apache.org/repos/asf/ignite/blob/bce0deb7/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..607de15
--- /dev/null
+++ b/modules/control-center-web/src/main/js/routes/agent.js
@@ -0,0 +1,261 @@
+/*
+ *
+ *  * 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;
+var ScanQuery = apacheIgnite.ScanQuery;
+
+function _client(req, res) {
+    var client = agentManager.getAgentManager().findClient(req.currentUserId());
+
+    if (!client) {
+        res.status(503).send('Client not found');
+
+        return null;
+    }
+
+    return client;
+}
+
+function _compact(className) {
+    return className.replace('java.lang.', '').replace('java.util.', '').replace('java.sql.', '');
+}
+
+/* Get grid topology. */
+router.get('/download', function (req, res) {
+    res.render('templates/agent-download');
+});
+
+/* Get grid topology. */
+router.post('/topology', function (req, res) {
+    var client = _client(req, res);
+
+    if (client) {
+        client.ignite().cluster().then(function (clusters) {
+            var caches = clusters.map(function (cluster) {
+                return Object.keys(cluster._caches).map(function (key) {
+                    return {name: key, mode: cluster._caches[key]}
+                });
+            });
+
+            res.json(_.uniq(_.reject(_.flatten(caches), { mode: 'LOCAL' }), function(cache) {
+                return cache.name;
+            }));
+        }, function (err) {
+            res.status(500).send(err);
+        });
+    }
+});
+
+/* Execute query. */
+router.post('/query', function (req, res) {
+    var client = _client(req, res);
+
+    if (client) {
+        // 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);
+        });
+    }
+});
+
+/* Execute query getAll. */
+router.post('/query/getAll', function (req, res) {
+    var client = _client(req, res);
+
+    if (client) {
+        // Create sql query.
+        var qry = new SqlFieldsQuery(req.body.query);
+
+        // Set page size for query.
+        qry.setPageSize(1024);
+
+        // Get query cursor.
+        var cursor = client.ignite().cache(req.body.cacheName).query(qry);
+
+        cursor.getAll().then(function (rows) {
+            res.json({meta: cursor.fieldsMetadata(), rows: rows});
+        }, function (err) {
+            res.status(500).send(err);
+        });
+    }
+});
+
+/* Execute query. */
+router.post('/scan', function (req, res) {
+    var client = _client(req, res);
+
+    if (client) {
+        // Create sql query.
+        var qry = new ScanQuery();
+
+        // 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 next query page. */
+router.post('/query/fetch', function (req, res) {
+    var client = _client(req, res);
+
+    if (client) {
+        var cache = client.ignite().cache(req.body.cacheName);
+
+        var cmd = cache._createCommand('qryfetch').addParam('qryId', req.body.queryId).
+            addParam('pageSize', 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);
+        });
+    }
+});
+
+/* Get metadata for cache. */
+router.post('/cache/metadata', function (req, res) {
+    var client = _client(req, res);
+
+    if (client) {
+        client.ignite().cache(req.body.cacheName).metadata().then(function (meta) {
+            var tables = meta.types.map(function (typeName) {
+                var fields = meta.fields[typeName];
+
+                var showSystem = fields.length == 2 && fields["_KEY"] && fields["_VAL"];
+
+                var columns = [];
+
+                for (var fieldName in fields)
+                    if (showSystem || fieldName != "_KEY" && fieldName != "_VAL") {
+                        var fieldClass = _compact(fields[fieldName]);
+
+                        columns.push({
+                            type: 'field',
+                            name: fieldName,
+                            fullName: typeName + '.' + fieldName,
+                            clazz: fieldClass
+                        });
+                    }
+
+                var indexes = [];
+
+                for (var index of meta.indexes[typeName]) {
+                    fields = [];
+
+                    for (var field of index.fields) {
+                        fields.push({
+                            type: 'index-field',
+                            name: field,
+                            fullName: typeName + '.' + index.name + '.' + field,
+                            order: index.descendings.indexOf(field) < 0,
+                            unique: index.unique
+                        });
+                    }
+
+                    if (fields.length > 0)
+                        indexes.push({
+                            type: 'index',
+                            name: index.name,
+                            fullName: typeName + '.' + index.name,
+                            children: fields
+                        });
+                }
+
+                columns = _.sortBy(columns, 'name');
+
+                if (indexes.length > 0)
+                    columns = columns.concat({type: 'indexes', name: 'Indexes', fullName: typeName + '.indexes', children: indexes });
+
+                return {type: 'type', name: typeName, fullName: req.body.cacheName + '.' +typeName,  children: columns };
+            });
+
+            res.json(tables);
+        }, function (err) {
+            res.status(500).send(err);
+        });
+    }
+});
+
+/* Get JDBC drivers list. */
+router.post('/drivers', function (req, res) {
+    var client = _client(req, res);
+
+    if (client) {
+        client.availableDrivers(function (err, drivers) {
+            if (err)
+                return res.status(500).send(err);
+
+            res.json(drivers);
+        });
+    }
+});
+
+/** Get database schemas. */
+router.post('/schemas', function (req, res) {
+    var client = _client(req, res);
+
+    if (client) {
+        var params = req.body;
+
+        client.metadataSchemas(params.jdbcDriverJar, params.jdbcDriverClass, params.jdbcUrl, {user: params.user, password: params.password}, function (err, meta) {
+            if (err)
+                return res.status(500).send(err);
+
+            res.json(meta);
+        });
+    }
+});
+
+/** Get database metadata. */
+router.post('/metadata', function (req, res) {
+    var client = _client(req, res);
+
+    if (client) {
+        var params = req.body;
+
+        client.metadataTables(params.jdbcDriverJar, params.jdbcDriverClass, params.jdbcUrl,
+            {user: params.user, password: params.password}, params.schemas, params.tablesOnly,
+            function (err, meta) {
+                if (err)
+                    return res.status(500).send(err);
+
+                res.json(meta);
+            });
+    }
+});
+
+module.exports = router;

http://git-wip-us.apache.org/repos/asf/ignite/blob/bce0deb7/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..30a5547
--- /dev/null
+++ b/modules/control-center-web/src/main/js/routes/caches.js
@@ -0,0 +1,171 @@
+/*
+ *
+ *  * 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 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 (db.processed(err, res)) {
+            var space_ids = spaces.map(function (value) {
+                return value._id;
+            });
+
+            // Get all clusters for spaces.
+            db.Cluster.find({space: {$in: space_ids}}, '_id name').sort('name').exec(function (err, clusters) {
+                if (db.processed(err, res)) {
+                    // Get all caches type metadata for spaces.
+                    db.CacheTypeMetadata.find({space: {$in: space_ids}}).sort('name').exec(function (err, metadatas) {
+                        if (db.processed(err, res)) {
+                            // Get all caches for spaces.
+                            db.Cache.find({space: {$in: space_ids}}).sort('name').exec(function (err, caches) {
+                                if (db.processed(err, res)) {
+                                    _.forEach(caches, function (cache) {
+                                        // Remove deleted clusters.
+                                        cache.clusters = _.filter(cache.clusters, function (clusterId) {
+                                            return _.findIndex(clusters, function (cluster) {
+                                                    return cluster._id.equals(clusterId);
+                                                }) >= 0;
+                                        });
+
+                                        // Remove deleted metadata.
+                                        cache.metadatas = _.filter(cache.metadatas, function (metaId) {
+                                            return _.findIndex(metadatas, function (meta) {
+                                                    return meta._id.equals(metaId);
+                                                }) >= 0;
+                                        });
+                                    });
+
+                                    res.json({
+                                        spaces: spaces,
+                                        clusters: clusters.map(function (cluster) {
+                                            return {value: cluster._id, label: cluster.name};
+                                        }),
+                                        metadatas: metadatas,
+                                        caches: caches
+                                    });
+                                }
+                            });
+                        }
+                    });
+                }
+            });
+        }
+    });
+});
+
+/**
+ * Save cache.
+ */
+router.post('/save', function (req, res) {
+    var params = req.body;
+    var cacheId = params._id;
+    var clusters = params.clusters;
+    var metadatas = params.metadatas;
+
+    if (params._id) {
+        db.Cache.update({_id: cacheId}, params, {upsert: true}, function (err) {
+            if (db.processed(err, res))
+                db.Cluster.update({_id: {$in: clusters}}, {$addToSet: {caches: cacheId}}, {multi: true}, function (err) {
+                    if (db.processed(err, res))
+                        db.Cluster.update({_id: {$nin: clusters}}, {$pull: {caches: cacheId}}, {multi: true}, function (err) {
+                            if (db.processed(err, res))
+                                db.CacheTypeMetadata.update({_id: {$in: metadatas}}, {$addToSet: {caches: cacheId}}, {multi: true}, function (err) {
+                                    if (db.processed(err, res))
+                                        db.CacheTypeMetadata.update({_id: {$nin: metadatas}}, {$pull: {caches: cacheId}}, {multi: true}, function (err) {
+                                            if (db.processed(err, res))
+                                                res.send(params._id);
+                                        });
+                                });
+                        });
+                });
+        })
+    }
+    else
+        db.Cache.findOne({space: params.space, name: params.name}, function (err, cache) {
+            if (db.processed(err, res)) {
+                if (cache)
+                    return res.status(500).send('Cache with name: "' + cache.name + '" already exist.');
+
+                (new db.Cache(params)).save(function (err, cache) {
+                    if (db.processed(err, res)) {
+                        cacheId = cache._id;
+
+                        db.Cluster.update({_id: {$in: clusters}}, {$addToSet: {caches: cacheId}}, {multi: true}, function (err) {
+                            if (db.processed(err, res))
+                                db.CacheTypeMetadata.update({_id: {$in: metadatas}}, {$addToSet: {caches: cacheId}}, {multi: true}, function (err) {
+                                    if (db.processed(err, res))
+                                        res.send(cacheId);
+                                });
+                        });
+                    }
+                });
+            }
+        });
+});
+
+/**
+ * Remove cache by ._id.
+ */
+router.post('/remove', function (req, res) {
+    db.Cache.remove(req.body, function (err) {
+        if (db.processed(err, res))
+            res.sendStatus(200);
+    })
+});
+
+/**
+ * Remove all caches.
+ */
+router.post('/remove/all', 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 (db.processed(err, res)) {
+            var space_ids = spaces.map(function (value) {
+                return value._id;
+            });
+
+            db.Cache.remove({space: {$in: space_ids}}, function (err) {
+                if (err)
+                    return res.status(500).send(err.message);
+
+                res.sendStatus(200);
+            })
+        }
+    });
+});
+
+module.exports = router;

http://git-wip-us.apache.org/repos/asf/ignite/blob/bce0deb7/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..59773e0
--- /dev/null
+++ b/modules/control-center-web/src/main/js/routes/clusters.js
@@ -0,0 +1,145 @@
+/*
+ *
+ *  * 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 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 (db.processed(err, res)) {
+            var space_ids = spaces.map(function (value) {
+                return value._id;
+            });
+
+            // Get all caches for spaces.
+            db.Cache.find({space: {$in: space_ids}}).sort('name').deepPopulate('metadatas').exec(function (err, caches) {
+                if (db.processed(err, res)) {
+                    // Get all clusters for spaces.
+                    db.Cluster.find({space: {$in: space_ids}}).sort('name').exec(function (err, clusters) {
+                        if (db.processed(err, res)) {
+                            // Remove deleted caches.
+                            _.forEach(clusters, function (cluster) {
+                                cluster.caches = _.filter(cluster.caches, function (cacheId) {
+                                    return _.findIndex(caches, function (cache) {
+                                            return cache._id.equals(cacheId);
+                                        }) >= 0;
+                                });
+                            });
+
+                            res.json({spaces: spaces, caches: caches, clusters: clusters});
+                        }
+                    });
+                }
+            });
+        }
+    });
+});
+
+/**
+ * Save cluster.
+ */
+router.post('/save', function (req, res) {
+    var params = req.body;
+    var clusterId = params._id;
+    var caches = params.caches;
+
+    if (params._id)
+        db.Cluster.update({_id: params._id}, params, {upsert: true}, function (err) {
+            if (db.processed(err, res))
+                db.Cache.update({_id: {$in: caches}}, {$addToSet: {clusters: clusterId}}, {multi: true}, function(err) {
+                    if (db.processed(err, res)) {
+                        db.Cache.update({_id: {$nin: caches}}, {$pull: {clusters: clusterId}}, {multi: true}, function(err) {
+                            if (db.processed(err, res))
+                                res.send(params._id);
+                        });
+                    }
+                });
+        });
+    else {
+        db.Cluster.findOne({space: params.space, name: params.name}, function (err, cluster) {
+            if (db.processed(err, res)) {
+                if (cluster)
+                    return res.status(500).send('Cluster with name: "' + cluster.name + '" already exist.');
+
+                (new db.Cluster(params)).save(function (err, cluster) {
+                    if (db.processed(err, res)) {
+                        clusterId = cluster._id;
+
+                        db.Cache.update({_id: {$in: caches}}, {$addToSet: {clusters: clusterId}}, {multi: true}, function (err) {
+                            if (db.processed(err, res))
+                                res.send(clusterId);
+                        });
+                    }
+                });
+            }
+        });
+    }
+});
+
+/**
+ * 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);
+    })
+});
+
+/**
+ * Remove all clusters.
+ */
+router.post('/remove/all', 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 (db.processed(err, res)) {
+            var space_ids = spaces.map(function (value) {
+                return value._id;
+            });
+
+            db.Cluster.remove({space: {$in: space_ids}}, function (err) {
+                if (err)
+                    return res.status(500).send(err.message);
+
+                res.sendStatus(200);
+            })
+        }
+    });
+});
+
+module.exports = router;

http://git-wip-us.apache.org/repos/asf/ignite/blob/bce0deb7/modules/control-center-web/src/main/js/routes/generator/generator-common.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/routes/generator/generator-common.js b/modules/control-center-web/src/main/js/routes/generator/generator-common.js
new file mode 100644
index 0000000..ccd11e0
--- /dev/null
+++ b/modules/control-center-web/src/main/js/routes/generator/generator-common.js
@@ -0,0 +1,353 @@
+/*
+ *
+ *  * 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.
+ *
+ */
+
+// For server side we should load required libraries.
+if (typeof window === 'undefined') {
+    _ = require('lodash');
+
+    $commonUtils = require('../../helpers/common-utils');
+    $dataStructures = require('../../helpers/data-structures');
+}
+
+// Entry point for common functions for code generation.
+$generatorCommon = {};
+
+// Add leading zero.
+$generatorCommon.addLeadingZero = function (numberStr, minSize) {
+    if (typeof (numberStr) != 'string')
+        numberStr = '' + numberStr;
+
+    while (numberStr.length < minSize) {
+        numberStr = '0' + numberStr;
+    }
+
+    return numberStr;
+};
+
+// Format date to string.
+$generatorCommon.formatDate = function (date) {
+    var dd = $generatorCommon.addLeadingZero(date.getDate(), 2);
+    var mm = $generatorCommon.addLeadingZero(date.getMonth() + 1, 2);
+
+    var yyyy = date.getFullYear();
+
+    return mm + '/' + dd + '/' + yyyy + ' ' + $generatorCommon.addLeadingZero(date.getHours(), 2) + ':' + $generatorCommon.addLeadingZero(date.getMinutes(), 2);
+};
+
+// Generate comment for generated XML, Java, ... files.
+$generatorCommon.mainComment = function mainComment() {
+    return 'This configuration was generated by Ignite Web Console (' + $generatorCommon.formatDate(new Date()) + ')';
+};
+
+// Create result holder with service functions and properties for XML and java code generation.
+$generatorCommon.builder = function () {
+    var res = [];
+
+    res.deep = 0;
+    res.needEmptyLine = false;
+    res.lineStart = true;
+    res.datasources = [];
+    res.imports = {};
+
+    res.safeDeep = 0;
+    res.safeNeedEmptyLine = false;
+    res.safeImports = {};
+    res.safeDatasources = [];
+    res.safePoint = -1;
+
+    function getLineStart() {
+        return this.lineStart ? _.repeat('    ', this.deep) : '';
+    }
+
+    res.startSafeBlock = function () {
+        res.safeDeep = this.deep;
+        this.safeNeedEmptyLine = this.needEmptyLine;
+        this.safeImports = _.cloneDeep(this.imports);
+        this.safeDatasources = this.datasources.slice();
+        this.safePoint = this.length;
+    };
+
+    res.rollbackSafeBlock = function () {
+        if (this.safePoint >= 0) {
+            this.splice(this.safePoint, this.length - this.safePoint);
+
+            this.deep = res.safeDeep;
+            this.needEmptyLine = this.safeNeedEmptyLine;
+            this.datasources = this.safeDatasources;
+            this.imports = this.safeImports;
+            this.safePoint = -1;
+        }
+    };
+
+    res.asString = function() {
+      return this.join('\n');
+    };
+
+    res.append = function (s) {
+        this.push((this.lineStart ? _.repeat('    ', this.deep) : '') + s);
+
+        return this;
+    };
+
+    res.line = function (s) {
+        if (s) {
+            if (this.needEmptyLine)
+                this.push('');
+
+            this.append(s);
+        }
+
+        this.needEmptyLine = false;
+
+        this.lineStart = true;
+
+        return this;
+    };
+
+    res.startBlock = function (s) {
+        if (s) {
+            if (this.needEmptyLine)
+                this.push('');
+
+            this.append(s);
+        }
+
+        this.needEmptyLine = false;
+
+        this.lineStart = true;
+
+        this.deep++;
+
+        return this;
+    };
+
+    res.endBlock = function (s) {
+        this.deep--;
+
+        if (s)
+            this.append(s);
+
+        this.lineStart = true;
+
+        return this;
+    };
+
+    res.emptyLineIfNeeded = function () {
+        if (this.needEmptyLine) {
+            this.push('');
+            this.lineStart = true;
+
+            this.needEmptyLine = false;
+        }
+    };
+
+    /**
+     * Add class to imports.
+     *
+     * @param clsName Full class name.
+     * @returns {String} Short class name or full class name in case of names conflict.
+     */
+    res.importClass = function (clsName) {
+        var fullClassName = $dataStructures.fullClassName(clsName);
+
+        var dotIdx = fullClassName.lastIndexOf('.');
+
+        var shortName = dotIdx > 0 ? fullClassName.substr(dotIdx + 1) : fullClassName;
+
+        if (this.imports[shortName]) {
+            if (this.imports[shortName] != fullClassName)
+                return fullClassName; // Short class names conflict. Return full name.
+        }
+        else
+            this.imports[shortName] = fullClassName;
+
+        return shortName;
+    };
+
+    /**
+     * @returns String with "java imports" section.
+     */
+    res.generateImports = function () {
+        var res = [];
+
+        for (var clsName in this.imports) {
+            if (this.imports.hasOwnProperty(clsName) && this.imports[clsName].lastIndexOf('java.lang.', 0) != 0)
+                res.push('import ' + this.imports[clsName] + ';');
+        }
+
+        res.sort();
+
+        return res.join('\n')
+    };
+
+    return res;
+};
+
+// Eviction policies code generation descriptors.
+$generatorCommon.EVICTION_POLICIES = {
+    LRU: {
+        className: 'org.apache.ignite.cache.eviction.lru.LruEvictionPolicy',
+        fields: {batchSize: null, maxMemorySize: null, maxSize: null}
+    },
+    RND: {
+        className: 'org.apache.ignite.cache.eviction.random.RandomEvictionPolicy',
+        fields: {maxSize: null}
+    },
+    FIFO: {
+        className: 'org.apache.ignite.cache.eviction.fifo.FifoEvictionPolicy',
+        fields: {batchSize: null, maxMemorySize: null, maxSize: null}
+    },
+    SORTED: {
+        className: 'org.apache.ignite.cache.eviction.sorted.SortedEvictionPolicy',
+        fields: {batchSize: null, maxMemorySize: null, maxSize: null}
+    }
+};
+
+// Marshaller code generation descriptors.
+$generatorCommon.MARSHALLERS = {
+    OptimizedMarshaller: {
+        className: 'org.apache.ignite.marshaller.optimized.OptimizedMarshaller',
+        fields: {poolSize: null, requireSerializable: null }
+    },
+    JdkMarshaller: {
+        className: 'org.apache.ignite.marshaller.jdk.JdkMarshaller',
+        fields: {}
+    }
+};
+
+// Pairs of supported databases and their JDBC dialects.
+$generatorCommon.JDBC_DIALECTS = {
+    Oracle: 'org.apache.ignite.cache.store.jdbc.dialect.OracleDialect',
+    DB2: 'org.apache.ignite.cache.store.jdbc.dialect.DB2Dialect',
+    SQLServer: 'org.apache.ignite.cache.store.jdbc.dialect.SQLServerDialect',
+    MySQL: 'org.apache.ignite.cache.store.jdbc.dialect.MySQLDialect',
+    PostgreSQL: 'org.apache.ignite.cache.store.jdbc.dialect.BasicJdbcDialect',
+    H2: 'org.apache.ignite.cache.store.jdbc.dialect.H2Dialect'
+};
+
+// Return JDBC dialect full class name for specified database.
+$generatorCommon.jdbcDialectClassName = function(db) {
+    var dialectClsName = $generatorCommon.JDBC_DIALECTS[db];
+
+    return dialectClsName ? dialectClsName : 'Unknown database: ' + db;
+};
+
+// Pairs of supported databases and their data sources.
+$generatorCommon.DATA_SOURCES = {
+    Oracle: 'oracle.jdbc.pool.OracleDataSource',
+    DB2: 'com.ibm.db2.jcc.DB2DataSource',
+    SQLServer: 'com.microsoft.sqlserver.jdbc.SQLServerDataSource',
+    MySQL: 'com.mysql.jdbc.jdbc2.optional.MysqlDataSource',
+    PostgreSQL: 'org.postgresql.ds.PGPoolingDataSource',
+    H2: 'org.h2.jdbcx.JdbcDataSource'
+};
+
+// Return data source full class name for specified database.
+$generatorCommon.dataSourceClassName = function(db) {
+    var dsClsName = $generatorCommon.DATA_SOURCES[db];
+
+    return dsClsName ? dsClsName : 'Unknown database: ' + db;
+};
+
+// Store factories code generation descriptors.
+$generatorCommon.STORE_FACTORIES = {
+    CacheJdbcPojoStoreFactory: {
+        className: 'org.apache.ignite.cache.store.jdbc.CacheJdbcPojoStoreFactory',
+        fields: {dataSourceBean: null, dialect: {type: 'jdbcDialect'}}
+    },
+    CacheJdbcBlobStoreFactory: {
+        className: 'org.apache.ignite.cache.store.jdbc.CacheJdbcBlobStoreFactory',
+        fields: {
+            user: null,
+            dataSourceBean: null,
+            initSchema: null,
+            createTableQuery: null,
+            loadQuery: null,
+            insertQuery: null,
+            updateQuery: null,
+            deleteQuery: null
+        }
+    },
+    CacheHibernateBlobStoreFactory: {
+        className: 'org.apache.ignite.cache.store.hibernate.CacheHibernateBlobStoreFactory',
+        fields: {hibernateProperties: {type: 'propertiesAsList', propVarName: 'props'}}
+    }
+};
+
+// Swap space SPI code generation descriptor.
+$generatorCommon.SWAP_SPACE_SPI = {
+    className: 'org.apache.ignite.spi.swapspace.file.FileSwapSpaceSpi',
+    fields: {
+        baseDirectory: {type: 'path'},
+        readStripesNumber: null,
+        maximumSparsity: {type: 'float'},
+        maxWriteQueueSize: null,
+        writeBufferSize: null
+    }
+};
+
+// Transaction configuration code generation descriptor.
+$generatorCommon.TRANSACTION_CONFIGURATION = {
+    className: 'org.apache.ignite.configuration.TransactionConfiguration',
+    fields: {
+        defaultTxConcurrency: {type: 'enum', enumClass: 'org.apache.ignite.transactions.TransactionConcurrency'},
+        transactionIsolation: {
+            type: 'org.apache.ignite.transactions.TransactionIsolation',
+            setterName: 'defaultTxIsolation'
+        },
+        defaultTxTimeout: null,
+        pessimisticTxLogLinger: null,
+        pessimisticTxLogSize: null,
+        txSerializableEnabled: null,
+        txManagerLookupClassName: null
+    }
+};
+
+// SSL configuration code generation descriptor.
+$generatorCommon.SSL_CONFIGURATION_TRUST_FILE_FACTORY = {
+    className: 'org.apache.ignite.ssl.SslContextFactory',
+    fields: {
+        keyAlgorithm: null,
+        keyStoreFilePath: {type: 'path'},
+        keyStorePassword: {type: 'raw'},
+        keyStoreType: null,
+        protocol: null,
+        trustStoreFilePath: {type: 'path'},
+        trustStorePassword: {type: 'raw'},
+        trustStoreType: null
+    }
+};
+
+// SSL configuration code generation descriptor.
+$generatorCommon.SSL_CONFIGURATION_TRUST_MANAGER_FACTORY = {
+    className: 'org.apache.ignite.ssl.SslContextFactory',
+    fields: {
+        keyAlgorithm: null,
+        keyStoreFilePath: {type: 'path'},
+        keyStorePassword: {type: 'raw'},
+        keyStoreType: null,
+        protocol: null,
+        trustManagers: {type: 'array'}
+    }
+};
+
+// For server side we should export Java code generation entry point.
+if (typeof window === 'undefined') {
+    module.exports = $generatorCommon;
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/bce0deb7/modules/control-center-web/src/main/js/routes/generator/generator-docker.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/routes/generator/generator-docker.js b/modules/control-center-web/src/main/js/routes/generator/generator-docker.js
new file mode 100644
index 0000000..676cc94
--- /dev/null
+++ b/modules/control-center-web/src/main/js/routes/generator/generator-docker.js
@@ -0,0 +1,60 @@
+/*
+ *
+ *  * 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.
+ *
+ */
+
+// Docker file generation entry point.
+$generatorDocker = {};
+
+// Generate Docker file for cluster.
+$generatorDocker.clusterDocker = 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 Java. \n' +
+        'RUN \\\n' +
+        'apt-get update && \\\n' +
+        'apt-get install -y openjdk-7-jdk && \\\n' +
+        'rm -rf /var/lib/apt/lists/*\n' +
+        '\n' +
+        '# Define commonly used JAVA_HOME variable.\n' +
+        'ENV JAVA_HOME /usr/lib/jvm/java-7-openjdk-amd64\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';
+};
+
+// For server side we should export Java code generation entry point.
+if (typeof window === 'undefined') {
+    module.exports = $generatorDocker;
+}