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/23 10:41:21 UTC
[50/50] [abbrv] incubator-ignite git commit: #ignite-1121 Merged with
ignite-843
#ignite-1121 Merged 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/a45a700c
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ignite/tree/a45a700c
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ignite/diff/a45a700c
Branch: refs/heads/ignite-1121
Commit: a45a700c63b70c075df494fd080e668803387c32
Parents: 71b313c 14fa6f6
Author: Andrey <an...@gridgain.com>
Authored: Thu Jul 23 15:41:20 2015 +0700
Committer: Andrey <an...@gridgain.com>
Committed: Thu Jul 23 15:41:20 2015 +0700
----------------------------------------------------------------------
modules/web-control-center/nodejs/.gitignore | 4 -
modules/web-control-center/nodejs/DEVNOTES.txt | 21 -
.../nodejs/agents/agent-manager.js | 283 -----
.../nodejs/agents/agent-server.js | 90 --
modules/web-control-center/nodejs/app.js | 156 ---
modules/web-control-center/nodejs/bin/www | 110 --
.../nodejs/config/default.json | 17 -
.../nodejs/controllers/admin-controller.js | 68 -
.../nodejs/controllers/caches-controller.js | 333 -----
.../nodejs/controllers/clusters-controller.js | 309 -----
.../nodejs/controllers/common-module.js | 422 -------
.../nodejs/controllers/metadata-controller.js | 678 ----------
.../nodejs/controllers/models/caches.json | 905 -------------
.../nodejs/controllers/models/clusters.json | 896 -------------
.../nodejs/controllers/models/metadata.json | 218 ----
.../nodejs/controllers/models/sql.json | 5 -
.../nodejs/controllers/models/summary.json | 150 ---
.../nodejs/controllers/profile-controller.js | 51 -
.../nodejs/controllers/sql-controller.js | 60 -
.../nodejs/controllers/summary-controller.js | 171 ---
modules/web-control-center/nodejs/db.js | 358 ------
.../nodejs/helpers/configuration-loader.js | 22 -
.../nodejs/helpers/data-structures.js | 84 --
modules/web-control-center/nodejs/keys/test.crt | 13 -
modules/web-control-center/nodejs/keys/test.key | 18 -
modules/web-control-center/nodejs/package.json | 51 -
.../nodejs/public/favicon.ico | Bin 1150 -> 0 bytes
.../nodejs/public/images/docker.png | Bin 994 -> 0 bytes
.../nodejs/public/images/java.png | Bin 170 -> 0 bytes
.../nodejs/public/images/logo.png | Bin 8148 -> 0 bytes
.../nodejs/public/images/xml.png | Bin 232 -> 0 bytes
.../nodejs/public/stylesheets/style.less | 1125 -----------------
.../web-control-center/nodejs/routes/admin.js | 79 --
.../web-control-center/nodejs/routes/agent.js | 37 -
.../web-control-center/nodejs/routes/caches.js | 95 --
.../nodejs/routes/clusters.js | 104 --
.../nodejs/routes/generator/common.js | 299 -----
.../nodejs/routes/generator/docker.js | 58 -
.../nodejs/routes/generator/java.js | 626 ---------
.../nodejs/routes/generator/xml.js | 580 ---------
.../nodejs/routes/metadata.js | 95 --
.../web-control-center/nodejs/routes/profile.js | 97 --
.../web-control-center/nodejs/routes/public.js | 123 --
modules/web-control-center/nodejs/routes/sql.js | 24 -
.../web-control-center/nodejs/routes/summary.js | 108 --
.../nodejs/tests/routes/agent.js | 94 --
.../nodejs/views/configuration/caches.jade | 70 -
.../nodejs/views/configuration/clusters.jade | 73 --
.../nodejs/views/configuration/metadata.jade | 120 --
.../nodejs/views/configuration/sidebar.jade | 39 -
.../nodejs/views/configuration/summary.jade | 115 --
.../web-control-center/nodejs/views/error.jade | 22 -
.../nodejs/views/includes/controls.jade | 316 -----
.../nodejs/views/includes/footer.jade | 22 -
.../nodejs/views/includes/header.jade | 39 -
.../web-control-center/nodejs/views/index.jade | 30 -
.../web-control-center/nodejs/views/login.jade | 55 -
.../nodejs/views/settings/admin.jade | 58 -
.../nodejs/views/settings/profile.jade | 58 -
.../nodejs/views/sql/sql.jade | 70 -
.../nodejs/views/templates/confirm.jade | 27 -
.../nodejs/views/templates/layout.jade | 61 -
.../nodejs/views/templates/saveAs.jade | 31 -
.../nodejs/views/templates/select.jade | 26 -
.../web-control-center/src/main/js/.gitignore | 4 +
.../web-control-center/src/main/js/DEVNOTES.txt | 21 +
.../src/main/js/agents/agent-manager.js | 283 +++++
.../src/main/js/agents/agent-server.js | 90 ++
modules/web-control-center/src/main/js/app.js | 156 +++
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 | 333 +++++
.../main/js/controllers/clusters-controller.js | 309 +++++
.../src/main/js/controllers/common-module.js | 422 +++++++
.../main/js/controllers/metadata-controller.js | 680 ++++++++++
.../src/main/js/controllers/models/caches.json | 918 ++++++++++++++
.../main/js/controllers/models/clusters.json | 907 +++++++++++++
.../main/js/controllers/models/metadata.json | 230 ++++
.../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 | 60 +
.../main/js/controllers/summary-controller.js | 170 +++
modules/web-control-center/src/main/js/db.js | 358 ++++++
.../src/main/js/helpers/configuration-loader.js | 22 +
.../src/main/js/helpers/data-structures.js | 84 ++
.../src/main/js/keys/test.crt | 13 +
.../src/main/js/keys/test.key | 18 +
.../web-control-center/src/main/js/package.json | 51 +
.../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.less | 1193 ++++++++++++++++++
.../src/main/js/routes/admin.js | 79 ++
.../src/main/js/routes/agent.js | 37 +
.../src/main/js/routes/caches.js | 95 ++
.../src/main/js/routes/clusters.js | 104 ++
.../src/main/js/routes/generator/common.js | 299 +++++
.../src/main/js/routes/generator/docker.js | 58 +
.../src/main/js/routes/generator/java.js | 626 +++++++++
.../src/main/js/routes/generator/xml.js | 580 +++++++++
.../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 | 115 ++
.../src/main/js/views/error.jade | 22 +
.../src/main/js/views/includes/controls.jade | 336 +++++
.../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.jade | 70 +
.../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 | 3 +
.../src/test/js/routes/agent.js | 94 ++
130 files changed, 10496 insertions(+), 10269 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/a45a700c/modules/web-control-center/src/main/js/agents/agent-manager.js
----------------------------------------------------------------------
diff --cc modules/web-control-center/src/main/js/agents/agent-manager.js
index 0000000,0000000..252b984
new file mode 100644
--- /dev/null
+++ b/modules/web-control-center/src/main/js/agents/agent-manager.js
@@@ -1,0 -1,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 ignite = 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 ignite.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/a45a700c/modules/web-control-center/src/main/js/agents/agent-server.js
----------------------------------------------------------------------
diff --cc modules/web-control-center/src/main/js/agents/agent-server.js
index 0000000,0000000..31dee5a
new file mode 100644
--- /dev/null
+++ b/modules/web-control-center/src/main/js/agents/agent-server.js
@@@ -1,0 -1,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/a45a700c/modules/web-control-center/src/main/js/app.js
----------------------------------------------------------------------
diff --cc modules/web-control-center/src/main/js/app.js
index 0000000,8c347db..8cd8494
mode 000000,100644..100644
--- a/modules/web-control-center/src/main/js/app.js
+++ b/modules/web-control-center/src/main/js/app.js
@@@ -1,0 -1,154 +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 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('less-middleware')(path.join(__dirname, 'public'), {
+ render: {
+ compress: false
+ }
+ }));
+
+ 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/a45a700c/modules/web-control-center/src/main/js/bin/www
----------------------------------------------------------------------
diff --cc modules/web-control-center/src/main/js/bin/www
index 0000000,4cf0583..cbc637a
mode 000000,100644..100644
--- a/modules/web-control-center/src/main/js/bin/www
+++ b/modules/web-control-center/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/a45a700c/modules/web-control-center/src/main/js/config/default.json
----------------------------------------------------------------------
diff --cc modules/web-control-center/src/main/js/config/default.json
index 0000000,72dbd4e..f7f7a02
mode 000000,100644..100644
--- a/modules/web-control-center/src/main/js/config/default.json
+++ b/modules/web-control-center/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/a45a700c/modules/web-control-center/src/main/js/controllers/models/sql.json
----------------------------------------------------------------------
diff --cc modules/web-control-center/src/main/js/controllers/models/sql.json
index 0000000,0000000..b00e5dd
new file mode 100644
--- /dev/null
+++ b/modules/web-control-center/src/main/js/controllers/models/sql.json
@@@ -1,0 -1,0 +1,5 @@@
++{
++ "screenTip": [
++ "Execute SQL queries."
++ ]
++}
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/a45a700c/modules/web-control-center/src/main/js/controllers/sql-controller.js
----------------------------------------------------------------------
diff --cc modules/web-control-center/src/main/js/controllers/sql-controller.js
index 0000000,0000000..2562117
new file mode 100644
--- /dev/null
+++ b/modules/web-control-center/src/main/js/controllers/sql-controller.js
@@@ -1,0 -1,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.
++ */
++
++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.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.query = "select u.id, u.firstName, u.lastName from User u where u.name like 'aaaa';";
++
++ $scope.results = demoResults;
++
++ $scope.caches = demoCaches;
++}]);
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/a45a700c/modules/web-control-center/src/main/js/controllers/summary-controller.js
----------------------------------------------------------------------
diff --cc modules/web-control-center/src/main/js/controllers/summary-controller.js
index 0000000,1291683..531dc83
mode 000000,100644..100644
--- a/modules/web-control-center/src/main/js/controllers/summary-controller.js
+++ b/modules/web-control-center/src/main/js/controllers/summary-controller.js
@@@ -1,0 -1,164 +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/a45a700c/modules/web-control-center/src/main/js/keys/test.crt
----------------------------------------------------------------------
diff --cc modules/web-control-center/src/main/js/keys/test.crt
index 0000000,0000000..50c6d5c
new file mode 100644
--- /dev/null
+++ b/modules/web-control-center/src/main/js/keys/test.crt
@@@ -1,0 -1,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/a45a700c/modules/web-control-center/src/main/js/keys/test.key
----------------------------------------------------------------------
diff --cc modules/web-control-center/src/main/js/keys/test.key
index 0000000,0000000..1b395c0
new file mode 100644
--- /dev/null
+++ b/modules/web-control-center/src/main/js/keys/test.key
@@@ -1,0 -1,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/a45a700c/modules/web-control-center/src/main/js/package.json
----------------------------------------------------------------------
diff --cc modules/web-control-center/src/main/js/package.json
index 0000000,5e5463c..477266a
mode 000000,100644..100644
--- a/modules/web-control-center/src/main/js/package.json
+++ b/modules/web-control-center/src/main/js/package.json
@@@ -1,0 -1,50 +1,51 @@@
+ {
+ "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",
+ "less-middleware": "1.0.x",
+ "lodash": "3.10.0",
+ "mongoose": "^4.0.2",
+ "nconf": "^0.7.1",
+ "passport": "^0.2.1",
+ "passport-local": "^1.0.0",
+ "passport-local-mongoose": "^1.0.0",
+ "pg": "^4.4.0",
+ "serve-favicon": "~2.2.0",
- "util": "^0.10.3"
++ "util": "^0.10.3",
++ "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/a45a700c/modules/web-control-center/src/main/js/public/stylesheets/style.less
----------------------------------------------------------------------
diff --cc modules/web-control-center/src/main/js/public/stylesheets/style.less
index 0000000,e05f0ff..3d0ede7
mode 000000,100644..100644
--- a/modules/web-control-center/src/main/js/public/stylesheets/style.less
+++ b/modules/web-control-center/src/main/js/public/stylesheets/style.less
@@@ -1,0 -1,1182 +1,1193 @@@
+ /*
+ * 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-top: 20px;
+ margin-bottom: 20px;
+ }
+
+ .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: 200px;
++ 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 all) {
+ 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 .links table {
+ 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(.theme-line .links table all) {
+ margin-top: 5px;
+ margin-bottom: 5px;
+
+ label {
+ line-height: @input-height;
+ color: #666;
+ }
+ }
+
+ .theme-line table.links-edit-details:extend(.theme-line .links table all) {
+ 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;
+ }
+ }
+ }
+ }
+
+ .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(.theme-line .links table all) {
+ 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;
+ }
+
-.configBox .nav > li > a {
++.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 20px;
+ 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;
++ }
++}
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/a45a700c/modules/web-control-center/src/main/js/routes/agent.js
----------------------------------------------------------------------
diff --cc modules/web-control-center/src/main/js/routes/agent.js
index 0000000,0000000..19379e2
new file mode 100644
--- /dev/null
+++ b/modules/web-control-center/src/main/js/routes/agent.js
@@@ -1,0 -1,0 +1,37 @@@
++/*
++ * Licensed to the Apache Software Foundation (ASF) under one or more
++ * contributor license agreements. See the NOTICE file distributed with
++ * this work for additional information regarding copyright ownership.
++ * The ASF licenses this file to You under the Apache License, Version 2.0
++ * (the "License"); you may not use this file except in compliance with
++ * the License. You may obtain a copy of the License at
++ *
++ * http://www.apache.org/licenses/LICENSE-2.0
++ *
++ * Unless required by applicable law or agreed to in writing, software
++ * distributed under the License is distributed on an "AS IS" BASIS,
++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
++ * See the License for the specific language governing permissions and
++ * limitations under the License.
++ */
++
++var router = require('express').Router();
++var agentManager = require('../agents/agent-manager');
++
++/* GET summary page. */
++router.post('/topology', function(req, res) {
++ var c = agentManager.getAgentManager().getOneClient();
++
++ if (!c)
++ return res.status(500).send("Client not found");
++
++ var ignite = c.ignite();
++
++ ignite.cluster().then(function (cluster) {
++ res.json(cluster);
++ }, function (err) {
++ res.send(err);
++ });
++});
++
++module.exports = router;
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/a45a700c/modules/web-control-center/src/main/js/views/configuration/summary.jade
----------------------------------------------------------------------
diff --cc modules/web-control-center/src/main/js/views/configuration/summary.jade
index 0000000,6f2f6d8..0370ef4
mode 000000,100644..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
@@@ -1,0 -1,117 +1,115 @@@
+ //-
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ 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
+ a(href='clusters') configure
+ | it.
+ .padding-dflt(ng-if='clusters.length > 0')
+ lable.labelHeader Clusters:
+ .links
+ table(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)
- .panel-body
- .configBox(ng-show='selectedItem' bs-tabs)
- div(title='<img src="/images/xml.png" width="16px" height="16px"/> XML' bs-pane)
- .configBox(ui-ace='{ onLoad: aceInit, mode: "xml" }' ng-model='xmlServer' style='margin: 0.65em 0;')
- div(title='<img src="/images/java.png" width="16px" height="16px"/> Java' bs-pane)
- .settings-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')
- .configBox(ui-ace='{ onLoad: aceInit, mode: "java" }' ng-model='javaServer')
- div(title='<img src="/images/docker.png" width="16px" height="16px"/> Dockerfile' bs-pane)
- .settings-row
- p
- +hard-link('https://docs.docker.com/reference/builder', 'Docker')
- | 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
- +hard-link('https://ignite.incubator.apache.org/download.html#docker', 'Apache Ignite docker image')
- | . For more information about using Ignite with Docker please read
- +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')
++ 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')
++ | 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
++ +hard-link('https://ignite.incubator.apache.org/download.html#docker', 'Apache Ignite docker image')
++ | . For more information about using Ignite with Docker please read
++ +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)
- .panel-body
- div(ng-show='selectedItem')
- .settings-row(ng-repeat='field in clientFields')
- +form-row-custom(['col-sm-3'], ['col-sm-3'])
- .configBox(bs-tabs)
- div(title='<img src="/images/xml.png" width="16px" height="16px"/> XML' bs-pane)
- .configBox(ui-ace='{ onLoad: aceInit, mode: "xml" }' ng-model='xmlClient' style='margin: 0.65em 0;')
- div(title='<img src="/images/java.png" width="16px" height="16px"/> Java' bs-pane)
- .settings-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')
++ 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/a45a700c/modules/web-control-center/src/main/js/views/includes/header.jade
----------------------------------------------------------------------
diff --cc modules/web-control-center/src/main/js/views/includes/header.jade
index 0000000,ab2d31e..bfd5275
mode 000000,100644..100644
--- a/modules/web-control-center/src/main/js/views/includes/header.jade
+++ b/modules/web-control-center/src/main/js/views/includes/header.jade
@@@ -1,0 -1,39 +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}}
+ | ",
+ 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('/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
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/a45a700c/modules/web-control-center/src/main/js/views/sql.jade
----------------------------------------------------------------------
diff --cc modules/web-control-center/src/main/js/views/sql.jade
index 0000000,0000000..9ba3056
new file mode 100644
--- /dev/null
+++ b/modules/web-control-center/src/main/js/views/sql.jade
@@@ -1,0 -1,0 +1,70 @@@
++//-
++ 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'}}
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/a45a700c/modules/web-control-center/src/main/js/views/templates/layout.jade
----------------------------------------------------------------------
diff --cc modules/web-control-center/src/main/js/views/templates/layout.jade
index 0000000,a4191ae..8fbcd7e
mode 000000,100644..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
@@@ -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/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
++ 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/a45a700c/modules/web-control-center/src/main/js/views/templates/tab.jade
----------------------------------------------------------------------
diff --cc modules/web-control-center/src/main/js/views/templates/tab.jade
index 0000000,0000000..ce62bd6
new file mode 100644
--- /dev/null
+++ b/modules/web-control-center/src/main/js/views/templates/tab.jade
@@@ -1,0 -1,0 +1,3 @@@
++//
++ Created by nva on 23/07/15.
++