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 2016/02/08 04:44:47 UTC
[1/3] ignite git commit: IGNITE-843 Refactored server side.
Repository: ignite
Updated Branches:
refs/heads/ignite-843-rc2 90735145a -> 721a11654
http://git-wip-us.apache.org/repos/asf/ignite/blob/721a1165/modules/control-center-web/src/main/js/serve/routes/caches.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/serve/routes/caches.js b/modules/control-center-web/src/main/js/serve/routes/caches.js
new file mode 100644
index 0000000..7d719e3
--- /dev/null
+++ b/modules/control-center-web/src/main/js/serve/routes/caches.js
@@ -0,0 +1,196 @@
+/*
+ * 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.
+ */
+
+// Fire me up!
+
+module.exports = {
+ implements: 'caches-routes',
+ inject: ['require(lodash)', 'require(express)', 'mongo']
+};
+
+module.exports.factory = function (_, express, mongo) {
+ return new Promise((resolve) => {
+ const router = express.Router();
+
+ /**
+ * 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.
+ mongo.Space.find({$or: [{owner: user_id}, {usedBy: {$elemMatch: {account: user_id}}}]}, function (err, spaces) {
+ if (mongo.processed(err, res)) {
+ var space_ids = spaces.map(function (value) {
+ return value._id;
+ });
+
+ // Get all clusters for spaces.
+ mongo.Cluster.find({space: {$in: space_ids}}, '_id name caches').sort('name').exec(function (err, clusters) {
+ if (mongo.processed(err, res)) {
+ // Get all domain models for spaces.
+ mongo.DomainModel.find({space: {$in: space_ids}}).sort('name').exec(function (err, domains) {
+ if (mongo.processed(err, res)) {
+ // Get all caches for spaces.
+ mongo.Cache.find({space: {$in: space_ids}}).sort('name').exec(function (err, caches) {
+ if (mongo.processed(err, res)) {
+ _.forEach(clusters, function (cluster) {
+ cluster.caches = _.filter(cluster.caches, function (cacheId) {
+ return _.find(caches, {_id: cacheId});
+ });
+ });
+
+ _.forEach(domains, function (domain) {
+ domain.caches = _.filter(domain.caches, function (cacheId) {
+ return _.find(caches, {_id: cacheId});
+ });
+ });
+
+ _.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 domain models.
+ cache.domains = _.filter(cache.domains, function (metaId) {
+ return _.findIndex(domains, function (domain) {
+ return domain._id.equals(metaId);
+ }) >= 0;
+ });
+ });
+
+ res.json({
+ spaces: spaces,
+ clusters: clusters.map(function (cluster) {
+ return {
+ value: cluster._id,
+ label: cluster.name,
+ caches: cluster.caches
+ };
+ }),
+ domains: domains,
+ caches: caches
+ });
+ }
+ });
+ }
+ });
+ }
+ });
+ }
+ });
+ });
+
+ /**
+ * Save cache.
+ */
+ router.post('/save', function (req, res) {
+ var params = req.body;
+ var cacheId = params._id;
+ var clusters = params.clusters;
+ var domains = params.domains;
+
+ if (params._id) {
+ mongo.Cache.update({_id: cacheId}, params, {upsert: true}, function (err) {
+ if (mongo.processed(err, res))
+ mongo.Cluster.update({_id: {$in: clusters}}, {$addToSet: {caches: cacheId}}, {multi: true}, function (err) {
+ if (mongo.processed(err, res))
+ mongo.Cluster.update({_id: {$nin: clusters}}, {$pull: {caches: cacheId}}, {multi: true}, function (err) {
+ if (mongo.processed(err, res))
+ mongo.DomainModel.update({_id: {$in: domains}}, {$addToSet: {caches: cacheId}}, {multi: true}, function (err) {
+ if (mongo.processed(err, res))
+ mongo.DomainModel.update({_id: {$nin: domains}}, {$pull: {caches: cacheId}}, {multi: true}, function (err) {
+ if (mongo.processed(err, res))
+ res.send(params._id);
+ });
+ });
+ });
+ });
+ })
+ }
+ else
+ mongo.Cache.findOne({space: params.space, name: params.name}, function (err, cache) {
+ if (mongo.processed(err, res)) {
+ if (cache)
+ return res.status(500).send('Cache with name: "' + cache.name + '" already exist.');
+
+ (new mongo.Cache(params)).save(function (err, cache) {
+ if (mongo.processed(err, res)) {
+ cacheId = cache._id;
+
+ mongo.Cluster.update({_id: {$in: clusters}}, {$addToSet: {caches: cacheId}}, {multi: true}, function (err) {
+ if (mongo.processed(err, res))
+ mongo.DomainModel.update({_id: {$in: domains}}, {$addToSet: {caches: cacheId}}, {multi: true}, function (err) {
+ if (mongo.processed(err, res))
+ res.send(cacheId);
+ });
+ });
+ }
+ });
+ }
+ });
+ });
+
+ /**
+ * Remove cache by ._id.
+ */
+ router.post('/remove', function (req, res) {
+ mongo.Cache.remove(req.body, function (err) {
+ if (mongo.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.
+ mongo.Space.find({$or: [{owner: user_id}, {usedBy: {$elemMatch: {account: user_id}}}]}, function (err, spaces) {
+ if (mongo.processed(err, res)) {
+ var space_ids = spaces.map(function (value) {
+ return value._id;
+ });
+
+ mongo.Cache.remove({space: {$in: space_ids}}, function (err) {
+ if (err)
+ return res.status(500).send(err.message);
+
+ mongo.Cluster.update({space: {$in: space_ids}}, {caches: []}, {multi: true}, function (err) {
+ if (mongo.processed(err, res))
+ mongo.DomainModel.update({space: {$in: space_ids}}, {caches: []}, {multi: true}, function (err) {
+ if (mongo.processed(err, res))
+ res.sendStatus(200);
+ });
+ });
+ })
+ }
+ });
+ });
+
+ resolve(router);
+ });
+};
+
http://git-wip-us.apache.org/repos/asf/ignite/blob/721a1165/modules/control-center-web/src/main/js/serve/routes/clusters.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/serve/routes/clusters.js b/modules/control-center-web/src/main/js/serve/routes/clusters.js
new file mode 100644
index 0000000..b740c01
--- /dev/null
+++ b/modules/control-center-web/src/main/js/serve/routes/clusters.js
@@ -0,0 +1,181 @@
+/*
+ * 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.
+ */
+
+// Fire me up!
+
+module.exports = {
+ implements: 'clusters-routes',
+ inject: ['require(lodash)', 'require(express)', 'mongo']
+};
+
+module.exports.factory = function (_, express, mongo) {
+ return new Promise((resolve) => {
+ const router = express.Router();
+
+ /**
+ * 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.
+ mongo.Space.find({$or: [{owner: user_id}, {usedBy: {$elemMatch: {account: user_id}}}]}, function (err, spaces) {
+ if (mongo.processed(err, res)) {
+ var space_ids = spaces.map(function (value) {
+ return value._id;
+ });
+
+ // Get all caches for spaces.
+ mongo.Cache.find({space: {$in: space_ids}}).sort('name').deepPopulate('domains').exec(function (err, caches) {
+ if (mongo.processed(err, res)) {
+ // Get all IGFSs for spaces.
+ mongo.Igfs.find({space: {$in: space_ids}}).sort('name').exec(function (err, igfss) {
+ if (mongo.processed(err, res))
+ // Get all clusters for spaces.
+ mongo.Cluster.find({space: {$in: space_ids}}).sort('name').deepPopulate(mongo.ClusterDefaultPopulate).exec(function (err, clusters) {
+ if (mongo.processed(err, res)) {
+ _.forEach(caches, function (cache) {
+ // Remove deleted caches.
+ cache.clusters = _.filter(cache.clusters, function (clusterId) {
+ return _.find(clusters, {_id: clusterId});
+ });
+ });
+
+ _.forEach(igfss, function (igfs) {
+ // Remove deleted caches.
+ igfs.clusters = _.filter(igfs.clusters, function (clusterId) {
+ return _.find(clusters, {_id: clusterId});
+ });
+ });
+
+ _.forEach(clusters, function (cluster) {
+ // Remove deleted caches.
+ cluster.caches = _.filter(cluster.caches, function (cacheId) {
+ return _.find(caches, {_id: cacheId});
+ });
+
+ // Remove deleted IGFS.
+ cluster.igfss = _.filter(cluster.igfss, function (igfsId) {
+ return _.findIndex(igfss, function (igfs) {
+ return igfs._id.equals(igfsId);
+ }) >= 0;
+ });
+ });
+
+ res.json({
+ spaces: spaces,
+ caches: caches,
+ igfss: igfss,
+ 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)
+ mongo.Cluster.update({_id: params._id}, params, {upsert: true}, function (err) {
+ if (mongo.processed(err, res))
+ mongo.Cache.update({_id: {$in: caches}}, {$addToSet: {clusters: clusterId}}, {multi: true}, function (err) {
+ if (mongo.processed(err, res)) {
+ mongo.Cache.update({_id: {$nin: caches}}, {$pull: {clusters: clusterId}}, {multi: true}, function (err) {
+ if (mongo.processed(err, res))
+ res.send(params._id);
+ });
+ }
+ });
+ });
+ else {
+ mongo.Cluster.findOne({space: params.space, name: params.name}, function (err, cluster) {
+ if (mongo.processed(err, res)) {
+ if (cluster)
+ return res.status(500).send('Cluster with name: "' + cluster.name + '" already exist.');
+
+ (new mongo.Cluster(params)).save(function (err, cluster) {
+ if (mongo.processed(err, res)) {
+ clusterId = cluster._id;
+
+ mongo.Cache.update({_id: {$in: caches}}, {$addToSet: {clusters: clusterId}}, {multi: true}, function (err) {
+ if (mongo.processed(err, res))
+ res.send(clusterId);
+ });
+ }
+ });
+ }
+ });
+ }
+ });
+
+ /**
+ * Remove cluster by ._id.
+ */
+ router.post('/remove', function (req, res) {
+ mongo.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.
+ mongo.Space.find({$or: [{owner: user_id}, {usedBy: {$elemMatch: {account: user_id}}}]}, function (err, spaces) {
+ if (mongo.processed(err, res)) {
+ var space_ids = spaces.map(function (value) {
+ return value._id;
+ });
+
+ mongo.Cluster.remove({space: {$in: space_ids}}, function (err) {
+ if (err)
+ return res.status(500).send(err.message);
+
+ mongo.Cache.update({space: {$in: space_ids}}, {clusters: []}, {multi: true}, function (err) {
+ if (mongo.processed(err, res))
+ mongo.Igfs.update({space: {$in: space_ids}}, {clusters: []}, {multi: true}, function (err) {
+ if (mongo.processed(err, res))
+ res.sendStatus(200);
+ });
+ });
+ })
+ }
+ });
+ });
+
+ resolve(router);
+ });
+};
http://git-wip-us.apache.org/repos/asf/ignite/blob/721a1165/modules/control-center-web/src/main/js/serve/routes/domains.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/serve/routes/domains.js b/modules/control-center-web/src/main/js/serve/routes/domains.js
new file mode 100644
index 0000000..5e6e934
--- /dev/null
+++ b/modules/control-center-web/src/main/js/serve/routes/domains.js
@@ -0,0 +1,285 @@
+/*
+ * 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.
+ */
+
+// Fire me up!
+
+module.exports = {
+ implements: 'domains-routes',
+ inject: ['require(lodash)', 'require(express)', 'require(async)', 'mongo']
+};
+
+module.exports.factory = function (_, express, async, mongo) {
+ return new Promise((resolve) => {
+ const router = express.Router();
+
+ /**
+ * Get spaces and domain models 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.
+ mongo.Space.find({$or: [{owner: user_id}, {usedBy: {$elemMatch: {account: user_id}}}]}, function (err, spaces) {
+ if (mongo.processed(err, res)) {
+ var space_ids = spaces.map(function (value) {
+ return value._id;
+ });
+
+ // Get all clusters for spaces.
+ mongo.Cluster.find({space: {$in: space_ids}}, '_id name').sort('name').exec(function (err, clusters) {
+ if (mongo.processed(err, res)) {
+ // Get all caches for spaces.
+ mongo.Cache.find({space: {$in: space_ids}}).sort('name').exec(function (err, caches) {
+ if (mongo.processed(err, res)) {
+ // Get all domain models for spaces.
+ mongo.DomainModel.find({space: {$in: space_ids}}).sort('valueType').exec(function (err, domains) {
+ if (mongo.processed(err, res)) {
+ _.forEach(caches, function (cache) {
+ cache.domains = _.filter(cache.domains, function (metaId) {
+ return _.find(domains, {_id: metaId});
+ });
+ });
+
+ // Remove deleted caches.
+ _.forEach(domains, function (domain) {
+ domain.caches = _.filter(domain.caches, function (cacheId) {
+ return _.find(caches, {_id: cacheId});
+ });
+ });
+
+ res.json({
+ spaces: spaces,
+ clusters: clusters.map(function (cluster) {
+ return {value: cluster._id, label: cluster.name};
+ }),
+ caches: caches,
+ domains: domains
+ });
+ }
+ });
+ }
+ });
+ }
+ });
+ }
+ });
+ });
+
+ function _saveDomainModel(domain, savedDomains, callback) {
+ var domainId = domain._id;
+ var caches = domain.caches;
+
+ var cacheStoreChanges = domain.cacheStoreChanges;
+
+ if (domainId)
+ mongo.DomainModel.update({_id: domain._id}, domain, {upsert: true}, function (err) {
+ if (err)
+ callback(err);
+ else
+ mongo.Cache.update({_id: {$in: caches}}, {$addToSet: {domains: domainId}}, {multi: true}, function (err) {
+ if (err)
+ callback(err);
+ else
+ mongo.Cache.update({_id: {$nin: caches}}, {$pull: {domains: domainId}}, {multi: true}, function (err) {
+ if (err)
+ callback(err);
+ else {
+ savedDomains.push(domain);
+
+ _updateCacheStore(cacheStoreChanges, callback);
+ }
+ });
+ });
+ });
+ else
+ mongo.DomainModel.findOne({space: domain.space, valueType: domain.valueType}, function (err, found) {
+ if (err)
+ callback(err);
+ else if (found)
+ return callback('Domain model with value type: "' + found.valueType + '" already exist.');
+
+ (new mongo.DomainModel(domain)).save(function (err, domain) {
+ if (err)
+ callback(err);
+ else {
+ domainId = domain._id;
+
+ mongo.Cache.update({_id: {$in: caches}}, {$addToSet: {domains: domainId}}, {multi: true}, function (err) {
+ if (err)
+ callback(err);
+ else {
+ savedDomains.push(domain);
+
+ _updateCacheStore(cacheStoreChanges, callback);
+ }
+ });
+ }
+ });
+ });
+ }
+
+ function _updateCacheStore(cacheStoreChanges, callback) {
+ if (cacheStoreChanges && cacheStoreChanges.length > 0) {
+ async.forEachOf(cacheStoreChanges, function (change, idx, callback) {
+ mongo.Cache.update({_id: {$eq: change.cacheId}}, change.change, {}, function (err) {
+ if (err)
+ callback(err);
+ else
+ callback();
+ });
+ }, callback);
+ }
+ else
+ callback();
+ }
+
+ function _save(domains, res) {
+ var savedDomains = [];
+ var generatedCaches = [];
+
+ if (domains && domains.length > 0)
+ async.forEachOf(domains, function (domain, idx, callback) {
+ if (domain.newCache) {
+ mongo.Cache.findOne({space: domain.space, name: domain.newCache.name}, function (err, cache) {
+ if (mongo.processed(err, res))
+ if (cache) {
+ // Cache already exists, just save domain model.
+ domain.caches = [cache._id];
+
+ _saveDomainModel(domain, savedDomains, callback);
+ }
+ else {
+ // If cache not found, then create it and associate with domain model.
+ var newCache = domain.newCache;
+ newCache.space = domain.space;
+
+ (new mongo.Cache(newCache)).save(function (err, cache) {
+ var cacheId = cache._id;
+
+ if (mongo.processed(err, res)) {
+ mongo.Cluster.update({_id: {$in: cache.clusters}}, {$addToSet: {caches: cacheId}}, {multi: true}, function (err) {
+ if (mongo.processed(err, res)) {
+ domain.caches = [cacheId];
+ generatedCaches.push(cache);
+
+ _saveDomainModel(domain, savedDomains, callback);
+ }
+ });
+ }
+ });
+ }
+ });
+ }
+ else
+ _saveDomainModel(domain, savedDomains, callback);
+ }, function (err) {
+ if (err)
+ res.status(500).send(err.message);
+ else
+ res.send({savedDomains: savedDomains, generatedCaches: generatedCaches});
+ });
+ else
+ res.status(500).send('Nothing to save!');
+ }
+
+ /**
+ * Save domain model.
+ */
+ router.post('/save', function (req, res) {
+ _save([req.body], res);
+ });
+
+ /**
+ * Batch save domain models.
+ */
+ router.post('/save/batch', function (req, res) {
+ _save(req.body, res);
+ });
+
+ /**
+ * Remove domain model by ._id.
+ */
+ router.post('/remove', function (req, res) {
+ mongo.DomainModel.remove(req.body, function (err) {
+ if (mongo.processed(err, res))
+ res.sendStatus(200);
+ })
+ });
+
+ /**
+ * Remove all domain models.
+ */
+ router.post('/remove/all', function (req, res) {
+ var user_id = req.currentUserId();
+
+ // Get owned space and all accessed space.
+ mongo.Space.find({$or: [{owner: user_id}, {usedBy: {$elemMatch: {account: user_id}}}]}, function (err, spaces) {
+ if (mongo.processed(err, res)) {
+ var space_ids = spaces.map(function (value) {
+ return value._id;
+ });
+
+ mongo.DomainModel.remove({space: {$in: space_ids}}, function (err) {
+ if (err)
+ return res.status(500).send(err.message);
+
+ mongo.Cache.update({space: {$in: space_ids}}, {domains: []}, {multi: true}, function (err) {
+ if (mongo.processed(err, res))
+ res.sendStatus(200);
+ });
+ })
+ }
+ });
+ });
+
+ /**
+ * Remove all generated demo domain models and caches.
+ */
+ router.post('/remove/demo', function (req, res) {
+ var user_id = req.currentUserId();
+
+ // Get owned space and all accessed space.
+ mongo.Space.find({$or: [{owner: user_id}, {usedBy: {$elemMatch: {account: user_id}}}]}, function (err, spaces) {
+ if (mongo.processed(err, res)) {
+ var space_ids = spaces.map(function (value) {
+ return value._id;
+ });
+
+ // Remove all demo domain models.
+ mongo.DomainModel.remove({$and: [{space: {$in: space_ids}}, {demo: true}]}, function (err) {
+ if (err)
+ return res.status(500).send(err.message);
+
+ // Remove all demo caches.
+ mongo.Cache.remove({$and: [{space: {$in: space_ids}}, {demo: true}]}, function (err) {
+ if (err)
+ return res.status(500).send(err.message);
+
+ res.sendStatus(200);
+ });
+ });
+ }
+ });
+ });
+
+ resolve(router);
+ });
+};
+
http://git-wip-us.apache.org/repos/asf/ignite/blob/721a1165/modules/control-center-web/src/main/js/serve/routes/igfs.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/serve/routes/igfs.js b/modules/control-center-web/src/main/js/serve/routes/igfs.js
new file mode 100644
index 0000000..cf312f5
--- /dev/null
+++ b/modules/control-center-web/src/main/js/serve/routes/igfs.js
@@ -0,0 +1,154 @@
+/*
+ * 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.
+ */
+
+// Fire me up!
+
+module.exports = {
+ implements: 'igfs-routes',
+ inject: ['require(lodash)', 'require(express)', 'mongo']
+};
+
+module.exports.factory = function (_, express, mongo) {
+ return new Promise((resolve) => {
+ const router = express.Router();
+
+ /**
+ * Get spaces and IGFSs 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.
+ mongo.Space.find({$or: [{owner: user_id}, {usedBy: {$elemMatch: {account: user_id}}}]}, function (err, spaces) {
+ if (mongo.processed(err, res)) {
+ var space_ids = spaces.map(function (value) {
+ return value._id;
+ });
+
+ // Get all clusters for spaces.
+ mongo.Cluster.find({space: {$in: space_ids}}, '_id name').sort('name').exec(function (err, clusters) {
+ if (mongo.processed(err, res)) {
+ // Get all IGFSs for spaces.
+ mongo.Igfs.find({space: {$in: space_ids}}).sort('name').exec(function (err, igfss) {
+ if (mongo.processed(err, res)) {
+ _.forEach(igfss, function (igfs) {
+ // Remove deleted clusters.
+ igfs.clusters = _.filter(igfs.clusters, function (clusterId) {
+ return _.findIndex(clusters, function (cluster) {
+ return cluster._id.equals(clusterId);
+ }) >= 0;
+ });
+ });
+
+ res.json({
+ spaces: spaces,
+ clusters: clusters.map(function (cluster) {
+ return {value: cluster._id, label: cluster.name};
+ }),
+ igfss: igfss
+ });
+ }
+ });
+ }
+ });
+ }
+ });
+ });
+
+ /**
+ * Save IGFS.
+ */
+ router.post('/save', function (req, res) {
+ var params = req.body;
+ var igfsId = params._id;
+ var clusters = params.clusters;
+
+ if (params._id) {
+ mongo.Igfs.update({_id: igfsId}, params, {upsert: true}, function (err) {
+ if (mongo.processed(err, res))
+ mongo.Cluster.update({_id: {$in: clusters}}, {$addToSet: {igfss: igfsId}}, {multi: true}, function (err) {
+ if (mongo.processed(err, res))
+ mongo.Cluster.update({_id: {$nin: clusters}}, {$pull: {igfss: igfsId}}, {multi: true}, function (err) {
+ if (mongo.processed(err, res))
+ res.send(params._id);
+ });
+ });
+ })
+ }
+ else
+ mongo.Igfs.findOne({space: params.space, name: params.name}, function (err, igfs) {
+ if (mongo.processed(err, res)) {
+ if (igfs)
+ return res.status(500).send('IGFS with name: "' + igfs.name + '" already exist.');
+
+ (new mongo.Igfs(params)).save(function (err, igfs) {
+ if (mongo.processed(err, res)) {
+ igfsId = igfs._id;
+
+ mongo.Cluster.update({_id: {$in: clusters}}, {$addToSet: {igfss: igfsId}}, {multi: true}, function (err) {
+ if (mongo.processed(err, res))
+ res.send(igfsId);
+ });
+ }
+ });
+ }
+ });
+ });
+
+ /**
+ * Remove IGFS by ._id.
+ */
+ router.post('/remove', function (req, res) {
+ mongo.Igfs.remove(req.body, function (err) {
+ if (mongo.processed(err, res))
+ res.sendStatus(200);
+ })
+ });
+
+ /**
+ * Remove all IGFSs.
+ */
+ router.post('/remove/all', function (req, res) {
+ var user_id = req.currentUserId();
+
+ // Get owned space and all accessed space.
+ mongo.Space.find({$or: [{owner: user_id}, {usedBy: {$elemMatch: {account: user_id}}}]}, function (err, spaces) {
+ if (mongo.processed(err, res)) {
+ var space_ids = spaces.map(function (value) {
+ return value._id;
+ });
+
+ mongo.Igfs.remove({space: {$in: space_ids}}, function (err) {
+ if (err)
+ return res.status(500).send(err.message);
+
+ mongo.Cluster.update({space: {$in: space_ids}}, {igfss: []}, {multi: true}, function (err) {
+ if (mongo.processed(err, res))
+ res.sendStatus(200);
+ });
+ })
+ }
+ });
+ });
+
+ resolve(router);
+ });
+};
+
http://git-wip-us.apache.org/repos/asf/ignite/blob/721a1165/modules/control-center-web/src/main/js/serve/routes/notebooks.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/serve/routes/notebooks.js b/modules/control-center-web/src/main/js/serve/routes/notebooks.js
new file mode 100644
index 0000000..af272fd
--- /dev/null
+++ b/modules/control-center-web/src/main/js/serve/routes/notebooks.js
@@ -0,0 +1,159 @@
+/*
+ * 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.
+ */
+
+// Fire me up!
+
+module.exports = {
+ implements: 'notebooks-routes',
+ inject: ['require(express)', 'mongo']
+};
+
+module.exports.factory = function (express, mongo) {
+ return new Promise((resolve) => {
+ const router = express.Router();
+
+ /**
+ * Get notebooks names accessed for user account.
+ *
+ * @param req Request.
+ * @param res Response.
+ */
+ router.post('/list', function (req, res) {
+ var user_id = req.currentUserId();
+
+ // Get owned space and all accessed space.
+ mongo.Space.find({$or: [{owner: user_id}, {usedBy: {$elemMatch: {account: user_id}}}]}, function (err, spaces) {
+ if (err)
+ return res.status(500).send(err.message);
+
+ var space_ids = spaces.map(function (value) {
+ return value._id;
+ });
+
+ // Get all metadata for spaces.
+ mongo.Notebook.find({space: {$in: space_ids}}).select('_id name').sort('name').exec(function (err, notebooks) {
+ if (err)
+ return res.status(500).send(err.message);
+
+ res.json(notebooks);
+ });
+ });
+ });
+
+ /**
+ * Get notebook accessed for user account.
+ *
+ * @param req Request.
+ * @param res Response.
+ */
+ router.post('/get', function (req, res) {
+ var user_id = req.currentUserId();
+
+ // Get owned space and all accessed space.
+ mongo.Space.find({$or: [{owner: user_id}, {usedBy: {$elemMatch: {account: user_id}}}]}, function (err, spaces) {
+ if (err)
+ return res.status(500).send(err.message);
+
+ var space_ids = spaces.map(function (value) {
+ return value._id;
+ });
+
+ // Get all metadata for spaces.
+ mongo.Notebook.findOne({space: {$in: space_ids}, _id: req.body.noteId}).exec(function (err, notebook) {
+ if (err)
+ return res.status(500).send(err.message);
+
+ res.json(notebook);
+ });
+ });
+ });
+
+ /**
+ * Save notebook accessed for user account.
+ *
+ * @param req Request.
+ * @param res Response.
+ */
+ router.post('/save', function (req, res) {
+ var note = req.body;
+ var noteId = note._id;
+
+ if (noteId)
+ mongo.Notebook.update({_id: noteId}, note, {upsert: true}, function (err) {
+ if (err)
+ return res.status(500).send(err.message);
+
+ res.send(noteId);
+ });
+ else
+ mongo.Notebook.findOne({space: note.space, name: note.name}, function (err, note) {
+ if (err)
+ return res.status(500).send(err.message);
+
+ if (note)
+ return res.status(500).send('Notebook with name: "' + note.name + '" already exist.');
+
+ (new mongo.Notebook(req.body)).save(function (err, note) {
+ if (err)
+ return res.status(500).send(err.message);
+
+ res.send(note._id);
+ });
+ });
+ });
+
+ /**
+ * Remove notebook by ._id.
+ *
+ * @param req Request.
+ * @param res Response.
+ */
+ router.post('/remove', function (req, res) {
+ mongo.Notebook.remove(req.body, function (err) {
+ if (err)
+ return res.status(500).send(err.message);
+
+ res.sendStatus(200);
+ });
+ });
+
+ /**
+ * Create new notebook for user account.
+ *
+ * @param req Request.
+ * @param res Response.
+ */
+ router.post('/new', function (req, res) {
+ var user_id = req.currentUserId();
+
+ // Get owned space and all accessed space.
+ mongo.Space.findOne({owner: user_id}, function (err, space) {
+ if (err)
+ return res.status(500).send(err.message);
+
+ (new mongo.Notebook({space: space.id, name: req.body.name})).save(function (err, note) {
+ if (err)
+ return res.status(500).send(err.message);
+
+ return res.send(note._id);
+ });
+ });
+ });
+
+ resolve(router);
+ });
+};
http://git-wip-us.apache.org/repos/asf/ignite/blob/721a1165/modules/control-center-web/src/main/js/serve/routes/profile.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/serve/routes/profile.js b/modules/control-center-web/src/main/js/serve/routes/profile.js
new file mode 100644
index 0000000..06db42a
--- /dev/null
+++ b/modules/control-center-web/src/main/js/serve/routes/profile.js
@@ -0,0 +1,93 @@
+/*
+ * 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.
+ */
+
+// Fire me up!
+
+module.exports = {
+ implements: 'profile-routes',
+ inject: ['require(lodash)', 'require(express)', 'mongo']
+};
+
+module.exports.factory = function (_, express, mongo) {
+ return new Promise((resolve) => {
+ const router = express.Router();
+
+ function _updateUser(res, params) {
+ mongo.Account.update({_id: params._id}, params, {upsert: true}, function (err, user) {
+ // TODO IGNITE-843 Send error to admin.
+ if (err)
+ return res.status(500).send('Failed to update profile!');
+
+ if (params.email)
+ user.email = params.email;
+
+ res.sendStatus(200);
+ });
+ }
+
+ function _checkEmail(res, user, params) {
+ if (params.email && user.email != params.email) {
+ mongo.Account.findOne({email: params.email}, function (err, userForEmail) {
+ // TODO send error to admin
+ if (err)
+ return res.status(500).send('Failed to check e-mail!');
+
+ if (userForEmail && userForEmail._id != user._id)
+ return res.status(500).send('User with this e-mail already registered!');
+
+ _updateUser(res, params);
+ });
+ }
+ else
+ _updateUser(res, params);
+ }
+
+ /**
+ * Save user profile.
+ */
+ router.post('/save', function (req, res) {
+ var params = req.body;
+
+ mongo.Account.findById(params._id, function (err, user) {
+ // TODO IGNITE-843 Send error to admin
+ if (err)
+ return res.status(500).send('Failed to find user!');
+
+ if (params.password) {
+ if (_.isEmpty(params.password))
+ return res.status(500).send('Wrong value for new password!');
+
+ user.setPassword(params.password, function (err, user) {
+ if (err)
+ return res.status(500).send(err.message);
+
+ user.save(function (err) {
+ if (err)
+ return res.status(500).send("Failed to change password!");
+
+ _checkEmail(res, user, params);
+ });
+ });
+ }
+ else
+ _checkEmail(res, user, params);
+ });
+ });
+
+ resolve(router);
+ });
+};
http://git-wip-us.apache.org/repos/asf/ignite/blob/721a1165/modules/control-center-web/src/main/js/serve/routes/public.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/serve/routes/public.js b/modules/control-center-web/src/main/js/serve/routes/public.js
new file mode 100644
index 0000000..1aa9bc0
--- /dev/null
+++ b/modules/control-center-web/src/main/js/serve/routes/public.js
@@ -0,0 +1,250 @@
+/*
+ * 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.
+ */
+
+'use strict';
+
+// Fire me up!
+
+module.exports = {
+ implements: 'public-routes',
+ inject: ['require(express)', 'require(passport)', 'require(nodemailer)', 'settings', 'mongo']
+};
+
+module.exports.factory = function (express, passport, nodemailer, settings, mongo) {
+ return new Promise(function (resolve) {
+ const router = express.Router();
+
+ const _randomString = () => {
+ const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
+ const possibleLen = possible.length;
+
+ let res = '';
+
+ for (let i = 0; i < settings.tokenLength; i++)
+ res += possible.charAt(Math.floor(Math.random() * possibleLen));
+
+ return res;
+ };
+
+ // GET user.
+ router.post('/user', function (req, res) {
+ var becomeUsed = req.session.viewedUser && req.user.admin;
+
+ var user = req.user;
+
+ if (becomeUsed) {
+ user = req.session.viewedUser;
+
+ user.becomeUsed = true;
+ }
+
+ res.json(user);
+ });
+
+ /**
+ * Register new account.
+ */
+ router.post('/register', function (req, res) {
+ mongo.Account.count(function (err, cnt) {
+ if (err)
+ return res.status(401).send(err.message);
+
+ req.body.admin = cnt == 0;
+
+ var account = new mongo.Account(req.body);
+
+ account.token = _randomString();
+
+ mongo.Account.register(account, req.body.password, function (err, account) {
+ if (err)
+ return res.status(401).send(err.message);
+
+ if (!account)
+ return res.status(500).send('Failed to create account.');
+
+ new mongo.Space({name: 'Personal space', owner: account._id}).save();
+
+ req.logIn(account, {}, function (err) {
+ if (err)
+ return res.status(401).send(err.message);
+
+ return res.sendStatus(200);
+ });
+ });
+ });
+ });
+
+ /**
+ * Login in exist account.
+ */
+ router.post('/login', function (req, res, next) {
+ passport.authenticate('local', function (err, user) {
+ if (err)
+ return res.status(401).send(err.message);
+
+ if (!user)
+ return res.status(401).send('Invalid email or password');
+
+ req.logIn(user, {}, function (err) {
+ if (err)
+ return res.status(401).send(err.message);
+
+ return res.sendStatus(200);
+ });
+ })(req, res, next);
+ });
+
+ /**
+ * Logout.
+ */
+ router.post('/logout', function (req, res) {
+ req.logout();
+
+ res.sendStatus(200);
+ });
+
+ /**
+ * Send e-mail to user with reset token.
+ */
+ router.post('/password/forgot', function (req, res) {
+ var transporter = {
+ service: settings.smtp.service,
+ auth: {
+ user: settings.smtp.email,
+ pass: settings.smtp.password
+ }
+ };
+
+ if (transporter.service == '' || transporter.auth.user == '' || transporter.auth.pass == '')
+ return res.status(401).send('Can\'t send e-mail with instructions to reset password. Please ask webmaster to setup SMTP server!');
+
+ var token = _randomString();
+
+ mongo.Account.findOne({email: req.body.email}, function (err, user) {
+ if (!user)
+ return res.status(401).send('No account with that email address exists!');
+
+ if (err)
+ // TODO IGNITE-843 Send email to admin
+ return res.status(401).send('Failed to reset password!');
+
+ user.resetPasswordToken = token;
+
+ user.save(function (err) {
+ if (err)
+ // TODO IGNITE-843 Send email to admin
+ return res.status(401).send('Failed to reset password!');
+
+ var mailer = nodemailer.createTransport(transporter);
+
+ var mailOptions = {
+ from: settings.smtp.address(settings.smtp.username, settings.smtp.email),
+ to: settings.smtp.address(user.username, user.email),
+ subject: 'Password Reset',
+ text: 'You are receiving this because you (or someone else) have requested the reset of the password for your account.\n\n' +
+ 'Please click on the following link, or paste this into your browser to complete the process:\n\n' +
+ 'http://' + req.headers.host + '/password/reset?token=' + token + '\n\n' +
+ 'If you did not request this, please ignore this email and your password will remain unchanged.\n\n' +
+ '--------------\n' +
+ 'Apache Ignite Web Console\n'
+ };
+
+ mailer.sendMail(mailOptions, function (err) {
+ if (err)
+ return res.status(401).send('Failed to send e-mail with reset link! ' + err);
+
+ return res.status(200).send('An e-mail has been sent with further instructions.');
+ });
+ });
+ });
+ });
+
+ /**
+ * Change password with given token.
+ */
+ router.post('/password/reset', function (req, res) {
+ mongo.Account.findOne({resetPasswordToken: req.body.token}, function (err, user) {
+ if (!user)
+ return res.status(500).send('Invalid token for password reset!');
+
+ // TODO IGNITE-843 Send email to admin
+ if (err)
+ return res.status(500).send('Failed to reset password!');
+
+ user.setPassword(req.body.password, function (err, updatedUser) {
+ if (err)
+ return res.status(500).send(err.message);
+
+ updatedUser.resetPasswordToken = undefined;
+
+ updatedUser.save(function (err) {
+ if (err)
+ return res.status(500).send(err.message);
+
+ var transporter = {
+ service: settings.smtp.service,
+ auth: {
+ user: settings.smtp.email,
+ pass: settings.smtp.password
+ }
+ };
+
+ var mailer = nodemailer.createTransport(transporter);
+
+ var mailOptions = {
+ from: settings.smtp.address(settings.smtp.username, settings.smtp.email),
+ to: settings.smtp.address(user.username, user.email),
+ subject: 'Your password has been changed',
+ text: 'Hello,\n\n' +
+ 'This is a confirmation that the password for your account ' + user.email + ' has just been changed.\n\n' +
+ 'Now you can login: http://' + req.headers.host + '\n\n' +
+ '--------------\n' +
+ 'Apache Ignite Web Console\n'
+ };
+
+ mailer.sendMail(mailOptions, function (err) {
+ if (err)
+ return res.status(503).send('Password was changed, but failed to send confirmation e-mail!<br />' + err);
+
+ return res.status(200).send(user.email);
+ });
+ });
+ });
+ });
+ });
+
+ /* GET reset password page. */
+ router.post('/validate/token', function (req, res) {
+ var token = req.body.token;
+
+ var data = {token: token};
+
+ mongo.Account.findOne({resetPasswordToken: token}, function (err, user) {
+ if (!user)
+ data.error = 'Invalid token for password reset!';
+ else if (err)
+ data.error = err;
+ else
+ data.email = user.email;
+
+ res.json(data);
+ });
+ });
+
+ resolve(router);
+ });
+};
http://git-wip-us.apache.org/repos/asf/ignite/blob/721a1165/modules/control-center-web/src/main/js/serve/routes/routes.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/serve/routes/routes.js b/modules/control-center-web/src/main/js/serve/routes/routes.js
new file mode 100644
index 0000000..268931f
--- /dev/null
+++ b/modules/control-center-web/src/main/js/serve/routes/routes.js
@@ -0,0 +1,106 @@
+/*
+ * 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.
+ */
+
+'use strict';
+
+// Fire me up!
+
+module.exports = {
+ implements: 'routes',
+ inject: [
+ 'public-routes',
+ 'admin-routes',
+ 'profile-routes',
+ 'clusters-routes',
+ 'domains-routes',
+ 'caches-routes',
+ 'igfs-routes',
+ 'notebooks-routes',
+ 'agent-routes',
+ 'ignite_modules/routes:*' // Loads all routes modules of all plugins
+ ]
+};
+
+module.exports.factory = function (publicRoutes, adminRoutes, profileRoutes,
+ clusterRoutes, domainRoutes, cacheRoutes, igfsRoutes,
+ notebookRoutes, agentRoutes,
+ pluginRoutes) {
+ return {
+ register: (app) => {
+ app.all('*', (req, res, next) => {
+ req.currentUserId = () => {
+ if (!req.user)
+ return null;
+
+ if (req.session.viewedUser && req.user.admin)
+ return req.session.viewedUser._id;
+
+ return req.user._id;
+ };
+
+ next();
+ });
+
+ const _mustAuthenticated = (req, res, next) => {
+ req.isAuthenticated() ? next() : res.redirect('/');
+ };
+
+ const _adminOnly = (req, res, next) => {
+ req.isAuthenticated() && req.user.admin ? next() : res.sendStatus(403);
+ };
+
+ // Registering the standard routes
+ app.use('/', publicRoutes);
+ app.use('/admin', _mustAuthenticated, _adminOnly, adminRoutes);
+ app.use('/profile', _mustAuthenticated, adminRoutes);
+
+ app.all('/configuration/*', _mustAuthenticated);
+
+ app.use('/configuration/clusters', clusterRoutes);
+ app.use('/configuration/domains', domainRoutes);
+ app.use('/configuration/caches', cacheRoutes);
+ app.use('/configuration/igfs', igfsRoutes);
+
+ app.use('/notebooks', _mustAuthenticated, notebookRoutes);
+ app.use('/agent', _mustAuthenticated, agentRoutes);
+
+ // Registering the routes of all plugin modules
+ for (var name in pluginRoutes)
+ if (pluginRoutes.hasOwnProperty(name))
+ pluginRoutes[name].register(app, _mustAuthenticated, _adminOnly);
+
+ // 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);
+ });
+
+ // 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: {}
+ });
+ });
+ }
+ };
+};
http://git-wip-us.apache.org/repos/asf/ignite/blob/721a1165/modules/control-center-web/src/main/js/serve/settings.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/serve/settings.js b/modules/control-center-web/src/main/js/serve/settings.js
new file mode 100644
index 0000000..b85b683
--- /dev/null
+++ b/modules/control-center-web/src/main/js/serve/settings.js
@@ -0,0 +1,78 @@
+/*
+ * 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.
+ */
+
+// Fire me up!
+
+module.exports = {
+ implements: 'settings',
+ inject: ['require(nconf)', 'require(fs)']
+};
+
+module.exports.factory = function (nconf, fs) {
+ nconf.file({'file': './serve/config/default.json'});
+
+ /**
+ * Normalize a port into a number, string, or false.
+ */
+ const _normalizePort = function (val) {
+ var port = parseInt(val, 10);
+
+ // named pipe
+ if (isNaN(port))
+ return val;
+
+ // port number
+ if (port >= 0)
+ return port;
+
+ return false;
+ };
+
+ return {
+ agent: {
+ file: 'ignite-web-agent-1.5.0.final',
+ port: _normalizePort(nconf.get('agent-server:port')),
+ SSLOptions: nconf.get('agent-server:ssl') && {
+ key: fs.readFileSync(nconf.get('agent-server:key')),
+ cert: fs.readFileSync(nconf.get('agent-server:cert')),
+ passphrase: nconf.get('agent-server:keyPassphrase')
+ }
+ },
+ server : {
+ port: _normalizePort(nconf.get('server:port') || 80),
+ SSLOptions: nconf.get('server:ssl') && {
+ enable301Redirects: true,
+ trustXFPHeader: true,
+ port: _normalizePort(nconf.get('server:https-port') || 443),
+ key: fs.readFileSync(nconf.get('server:key')),
+ cert: fs.readFileSync(nconf.get('server:cert')),
+ passphrase: nconf.get('server:keyPassphrase')
+ }
+ },
+ smtp: {
+ service: nconf.get('smtp:service'),
+ username: nconf.get('smtp:username'),
+ email: nconf.get('smtp:email'),
+ password: nconf.get('smtp:password'),
+ address: (username, email) => username ? '"' + username + '" <' + email + '>' : email
+ },
+ mongoUrl: nconf.get('mongoDB:url'),
+ cookieTTL: 3600000 * 24 * 30,
+ sessionSecret: 'keyboard cat',
+ tokenLength: 20
+ };
+};
[2/3] ignite git commit: IGNITE-843 Refactored server side.
Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/721a1165/modules/control-center-web/src/main/js/routes/igfs.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/routes/igfs.js b/modules/control-center-web/src/main/js/routes/igfs.js
deleted file mode 100644
index 2fad048..0000000
--- a/modules/control-center-web/src/main/js/routes/igfs.js
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-var _ = require('lodash');
-var router = require('express').Router();
-var db = require('../db');
-
-/**
- * Get spaces and IGFSs 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 IGFSs for spaces.
- db.Igfs.find({space: {$in: space_ids}}).sort('name').exec(function (err, igfss) {
- if (db.processed(err, res)) {
- _.forEach(igfss, function (igfs) {
- // Remove deleted clusters.
- igfs.clusters = _.filter(igfs.clusters, function (clusterId) {
- return _.findIndex(clusters, function (cluster) {
- return cluster._id.equals(clusterId);
- }) >= 0;
- });
- });
-
- res.json({
- spaces: spaces,
- clusters: clusters.map(function (cluster) {
- return {value: cluster._id, label: cluster.name};
- }),
- igfss: igfss
- });
- }
- }); }
- });
- }
- });
-});
-
-/**
- * Save IGFS.
- */
-router.post('/save', function (req, res) {
- var params = req.body;
- var igfsId = params._id;
- var clusters = params.clusters;
-
- if (params._id) {
- db.Igfs.update({_id: igfsId}, params, {upsert: true}, function (err) {
- if (db.processed(err, res))
- db.Cluster.update({_id: {$in: clusters}}, {$addToSet: {igfss: igfsId}}, {multi: true}, function (err) {
- if (db.processed(err, res))
- db.Cluster.update({_id: {$nin: clusters}}, {$pull: {igfss: igfsId}}, {multi: true}, function (err) {
- if (db.processed(err, res))
- res.send(params._id);
- });
- });
- })
- }
- else
- db.Igfs.findOne({space: params.space, name: params.name}, function (err, igfs) {
- if (db.processed(err, res)) {
- if (igfs)
- return res.status(500).send('IGFS with name: "' + igfs.name + '" already exist.');
-
- (new db.Igfs(params)).save(function (err, igfs) {
- if (db.processed(err, res)) {
- igfsId = igfs._id;
-
- db.Cluster.update({_id: {$in: clusters}}, {$addToSet: {igfss: igfsId}}, {multi: true}, function (err) {
- if (db.processed(err, res))
- res.send(igfsId);
- });
- }
- });
- }
- });
-});
-
-/**
- * Remove IGFS by ._id.
- */
-router.post('/remove', function (req, res) {
- db.Igfs.remove(req.body, function (err) {
- if (db.processed(err, res))
- res.sendStatus(200);
- })
-});
-
-/**
- * Remove all IGFSs.
- */
-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.Igfs.remove({space: {$in: space_ids}}, function (err) {
- if (err)
- return res.status(500).send(err.message);
-
- db.Cluster.update({space: {$in: space_ids}}, {igfss: []}, {multi: true}, function (err) {
- if (db.processed(err, res))
- res.sendStatus(200);
- });
- })
- }
- });
-});
-
-module.exports = router;
http://git-wip-us.apache.org/repos/asf/ignite/blob/721a1165/modules/control-center-web/src/main/js/routes/notebooks.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/routes/notebooks.js b/modules/control-center-web/src/main/js/routes/notebooks.js
deleted file mode 100644
index 93defd4..0000000
--- a/modules/control-center-web/src/main/js/routes/notebooks.js
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-var router = require('express').Router();
-
-var db = require('../db');
-var utils = require('./../helpers/common-utils');
-
-/**
- * Get notebooks names accessed for user account.
- *
- * @param req Request.
- * @param res Response.
- */
-router.post('/list', function (req, res) {
- var user_id = req.currentUserId();
-
- // Get owned space and all accessed space.
- db.Space.find({$or: [{owner: user_id}, {usedBy: {$elemMatch: {account: user_id}}}]}, function (err, spaces) {
- if (err)
- return res.status(500).send(err.message);
-
- var space_ids = spaces.map(function (value) {
- return value._id;
- });
-
- // Get all metadata for spaces.
- db.Notebook.find({space: {$in: space_ids}}).select('_id name').sort('name').exec(function (err, notebooks) {
- if (err)
- return res.status(500).send(err.message);
-
- res.json(notebooks);
- });
- });
-});
-
-/**
- * Get notebook accessed for user account.
- *
- * @param req Request.
- * @param res Response.
- */
-router.post('/get', function (req, res) {
- var user_id = req.currentUserId();
-
- // Get owned space and all accessed space.
- db.Space.find({$or: [{owner: user_id}, {usedBy: {$elemMatch: {account: user_id}}}]}, function (err, spaces) {
- if (err)
- return res.status(500).send(err.message);
-
- var space_ids = spaces.map(function (value) {
- return value._id;
- });
-
- // Get all metadata for spaces.
- db.Notebook.findOne({space: {$in: space_ids}, _id: req.body.noteId}).exec(function (err, notebook) {
- if (err)
- return res.status(500).send(err.message);
-
- res.json(notebook);
- });
- });
-});
-
-/**
- * Save notebook accessed for user account.
- *
- * @param req Request.
- * @param res Response.
- */
-router.post('/save', function (req, res) {
- var note = req.body;
- var noteId = note._id;
-
- if (noteId)
- db.Notebook.update({_id: noteId}, note, {upsert: true}, function (err) {
- if (err)
- return res.status(500).send(err.message);
-
- res.send(noteId);
- });
- else
- db.Notebook.findOne({space: note.space, name: note.name}, function (err, note) {
- if (err)
- return res.status(500).send(err.message);
-
- if (note)
- return res.status(500).send('Notebook with name: "' + note.name + '" already exist.');
-
- (new db.Notebook(req.body)).save(function (err, note) {
- if (err)
- return res.status(500).send(err.message);
-
- res.send(note._id);
- });
- });
-});
-
-/**
- * Remove notebook by ._id.
- *
- * @param req Request.
- * @param res Response.
- */
-router.post('/remove', function (req, res) {
- db.Notebook.remove(req.body, function (err) {
- if (err)
- return res.status(500).send(err.message);
-
- res.sendStatus(200);
- });
-});
-
-/**
- * Create new notebook for user account.
- *
- * @param req Request.
- * @param res Response.
- */
-router.post('/new', function (req, res) {
- var user_id = req.currentUserId();
-
- // Get owned space and all accessed space.
- db.Space.findOne({owner: user_id}, function (err, space) {
- if (err)
- return res.status(500).send(err.message);
-
- (new db.Notebook({space: space.id, name: req.body.name})).save(function (err, note) {
- if (err)
- return res.status(500).send(err.message);
-
- return res.send(note._id);
- });
- });
-});
-
-module.exports = router;
http://git-wip-us.apache.org/repos/asf/ignite/blob/721a1165/modules/control-center-web/src/main/js/routes/profile.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/routes/profile.js b/modules/control-center-web/src/main/js/routes/profile.js
deleted file mode 100644
index ae262cc..0000000
--- a/modules/control-center-web/src/main/js/routes/profile.js
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-var _ = require('lodash');
-
-var router = require('express').Router();
-var db = require('../db');
-
-function _updateUser(res, params) {
- db.Account.update({_id: params._id}, params, {upsert: true}, function (err, user) {
- // TODO IGNITE-843 Send error to admin.
- if (err)
- return res.status(500).send('Failed to update profile!');
-
- if (params.email)
- user.email = params.email;
-
- res.sendStatus(200);
- });
-}
-
-function _checkEmail(res, user, params) {
- if (params.email && user.email != params.email) {
- db.Account.findOne({email: params.email}, function(err, userForEmail) {
- // TODO send error to admin
- if (err)
- return res.status(500).send('Failed to check e-mail!');
-
- if (userForEmail && userForEmail._id != user._id)
- return res.status(500).send('User with this e-mail already registered!');
-
- _updateUser(res, params);
- });
- }
- else
- _updateUser(res, params);
-}
-
-/**
- * Save user profile.
- */
-router.post('/save', function (req, res) {
- var params = req.body;
-
- db.Account.findById(params._id, function (err, user) {
- // TODO IGNITE-843 Send error to admin
- if (err)
- return res.status(500).send('Failed to find user!');
-
- if (params.password) {
- if (_.isEmpty(params.password))
- return res.status(500).send('Wrong value for new password!');
-
- user.setPassword(params.password, function (err, user) {
- if (err)
- return res.status(500).send(err.message);
-
- user.save(function(err) {
- if (err)
- return res.status(500).send("Failed to change password!");
-
- _checkEmail(res, user, params);
- });
- });
- }
- else
- _checkEmail(res, user, params);
- });
-});
-
-module.exports = router;
http://git-wip-us.apache.org/repos/asf/ignite/blob/721a1165/modules/control-center-web/src/main/js/routes/public.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/routes/public.js b/modules/control-center-web/src/main/js/routes/public.js
deleted file mode 100644
index 44786a8..0000000
--- a/modules/control-center-web/src/main/js/routes/public.js
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-var router = require('express').Router();
-var passport = require('passport');
-var nodemailer = require('nodemailer');
-
-var db = require('../db');
-var config = require('../helpers/configuration-loader.js');
-var $commonUtils = require('./../helpers/common-utils');
-
-// GET user.
-router.post('/user', function (req, res) {
- var becomeUsed = req.session.viewedUser && req.user.admin;
-
- var user = req.user;
-
- if (becomeUsed) {
- user = req.session.viewedUser;
-
- user.becomeUsed = true;
- }
-
- res.json(user);
-});
-
-/**
- * Register new account.
- */
-router.post('/register', function (req, res) {
- db.Account.count(function (err, cnt) {
- if (err)
- return res.status(401).send(err.message);
-
- req.body.admin = cnt == 0;
-
- var account = new db.Account(req.body);
-
- account.token = $commonUtils.randomString(20);
-
- db.Account.register(account, req.body.password, function (err, account) {
- if (err)
- return res.status(401).send(err.message);
-
- if (!account)
- return res.status(500).send('Failed to create account.');
-
- new db.Space({name: 'Personal space', owner: account._id}).save();
-
- req.logIn(account, {}, function (err) {
- if (err)
- return res.status(401).send(err.message);
-
- return res.sendStatus(200);
- });
- });
- });
-});
-
-/**
- * Login in exist account.
- */
-router.post('/login', function (req, res, next) {
- passport.authenticate('local', function (err, user) {
- if (err)
- return res.status(401).send(err.message);
-
- if (!user)
- return res.status(401).send('Invalid email or password');
-
- req.logIn(user, {}, function (err) {
- if (err)
- return res.status(401).send(err.message);
-
- return res.sendStatus(200);
- });
- })(req, res, next);
-});
-
-/**
- * Logout.
- */
-router.post('/logout', function (req, res) {
- req.logout();
-
- res.sendStatus(200);
-});
-
-/**
- * Send e-mail to user with reset token.
- */
-router.post('/password/forgot', function(req, res) {
- var transporter = {
- service: config.get('smtp:service'),
- auth: {
- user:config.get('smtp:email'),
- pass: config.get('smtp:password')
- }
- };
-
- if (transporter.service == '' || transporter.auth.user == '' || transporter.auth.pass == '')
- return res.status(401).send('Can\'t send e-mail with instructions to reset password. Please ask webmaster to setup SMTP server!');
-
- var token = $commonUtils.randomString(20);
-
- db.Account.findOne({ email: req.body.email }, function(err, user) {
- if (!user)
- return res.status(401).send('No account with that email address exists!');
-
- if (err)
- // TODO IGNITE-843 Send email to admin
- return res.status(401).send('Failed to reset password!');
-
- user.resetPasswordToken = token;
-
- user.save(function(err) {
- if (err)
- // TODO IGNITE-843 Send email to admin
- return res.status(401).send('Failed to reset password!');
-
- var mailer = nodemailer.createTransport(transporter);
-
- var mailOptions = {
- from: config.address(config.get('smtp:username'), config.get('smtp:email')),
- to: config.address(user.username, user.email),
- subject: 'Password Reset',
- text: 'You are receiving this because you (or someone else) have requested the reset of the password for your account.\n\n' +
- 'Please click on the following link, or paste this into your browser to complete the process:\n\n' +
- 'http://' + req.headers.host + '/password/reset?token=' + token + '\n\n' +
- 'If you did not request this, please ignore this email and your password will remain unchanged.\n\n' +
- '--------------\n' +
- 'Apache Ignite Web Console\n'
- };
-
- mailer.sendMail(mailOptions, function(err){
- if (err)
- return res.status(401).send('Failed to send e-mail with reset link! ' + err);
-
- return res.status(200).send('An e-mail has been sent with further instructions.');
- });
- });
- });
-});
-
-/**
- * Change password with given token.
- */
-router.post('/password/reset', function(req, res) {
- db.Account.findOne({ resetPasswordToken: req.body.token }, function(err, user) {
- if (!user)
- return res.status(500).send('Invalid token for password reset!');
-
- if (err)
- // TODO IGNITE-843 Send email to admin
- return res.status(500).send('Failed to reset password!');
-
- user.setPassword(req.body.password, function (err, updatedUser) {
- if (err)
- return res.status(500).send(err.message);
-
- updatedUser.resetPasswordToken = undefined;
-
- updatedUser.save(function (err) {
- if (err)
- return res.status(500).send(err.message);
-
- var transporter = {
- service: config.get('smtp:service'),
- auth: {
- user: config.get('smtp:email'),
- pass: config.get('smtp:password')
- }
- };
-
- var mailer = nodemailer.createTransport(transporter);
-
- var mailOptions = {
- from: config.address(config.get('smtp:username'), config.get('smtp:email')),
- to: config.address(user.username, user.email),
- subject: 'Your password has been changed',
- text: 'Hello,\n\n' +
- 'This is a confirmation that the password for your account ' + user.email + ' has just been changed.\n\n' +
- 'Now you can login: http://' + req.headers.host + '\n\n' +
- '--------------\n' +
- 'Apache Ignite Web Console\n'
- };
-
- mailer.sendMail(mailOptions, function (err) {
- if (err)
- return res.status(503).send('Password was changed, but failed to send confirmation e-mail!<br />' + err);
-
- return res.status(200).send(user.email);
- });
- });
- });
- });
-});
-
-/* GET reset password page. */
-router.post('/validate/token', function (req, res) {
- var token = req.body.token;
-
- var data = {token: token};
-
- db.Account.findOne({resetPasswordToken: token}, function (err, user) {
- if (!user)
- data.error = 'Invalid token for password reset!';
- else if (err)
- data.error = err;
- else
- data.email = user.email;
-
- res.json(data);
- });
-});
-
-module.exports = router;
http://git-wip-us.apache.org/repos/asf/ignite/blob/721a1165/modules/control-center-web/src/main/js/serve.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/serve.js b/modules/control-center-web/src/main/js/serve.js
index 9fff7a4..b5897a2 100644
--- a/modules/control-center-web/src/main/js/serve.js
+++ b/modules/control-center-web/src/main/js/serve.js
@@ -15,108 +15,94 @@
* limitations under the License.
*/
+const http = require('http'),
+ https = require('https'),
+ path = require('path');
+
/**
- * Module dependencies.
+ * Event listener for HTTP server "error" event.
*/
-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');
+const _onError = (port, error) => {
+ if (error.syscall !== 'listen')
+ throw error;
+
+ var bind = typeof port === 'string' ? 'Pipe ' + port : 'Port ' + port;
-var fs = require('fs');
+ // Handle specific listen errors with friendly messages.
+ switch (error.code) {
+ case 'EACCES':
+ console.error(bind + ' requires elevated privileges');
+ process.exit(1);
-var debug = require('debug')('ignite-web-console:server');
+ break;
+ case 'EADDRINUSE':
+ console.error(bind + ' is already in use');
+ process.exit(1);
+
+ break;
+ default:
+ throw error;
+ }
+};
/**
- * Get port from environment and store in Express.
+ * Event listener for HTTP server "listening" event.
*/
-var port = config.normalizePort(config.get('server:port') || process.env.PORT || 80);
+const _onListening = (addr) => {
+ var bind = typeof addr === 'string' ? 'pipe ' + addr : 'port ' + addr.port;
-// Create HTTP server.
-var server = http.createServer(app);
+ console.log('Start listening on ' + bind);
+};
-app.set('port', port);
+const igniteModules = (process.env.IGNITE_MODULES && path.relative(__dirname, process.env.IGNITE_MODULES)) || './ignite_modules';
-/**
- * Listen on provided port, on all network interfaces.
- */
-server.listen(port);
-server.on('error', onError);
-server.on('listening', onListening);
-
-if (config.get('server:ssl')) {
- httpsServer = https.createServer({
- key: fs.readFileSync(config.get('server:key')),
- cert: fs.readFileSync(config.get('server:cert')),
- passphrase: config.get('server:keyPassphrase')
- }, app);
-
- var httpsPort = config.normalizePort(config.get('server:https-port') || 443);
-
- /**
- * Listen on provided port, on all network interfaces.
- */
- httpsServer.listen(httpsPort);
- httpsServer.on('error', onError);
- httpsServer.on('listening', onListening);
-}
+const fireUp = require('fire-up').newInjector({
+ basePath: __dirname,
+ modules: [
+ './serve/**/*.js',
+ `${igniteModules}/**/*.js`
+ ]
+});
-/**
- * Start agent server.
- */
-var agentServer;
+Promise.all([fireUp('settings'), fireUp('app'), fireUp('agent')])
+ .then((values) => {
+ const settings = values[0], app = values[1], agent = values[2];
-if (config.get('agent-server:ssl')) {
- agentServer = https.createServer({
- key: fs.readFileSync(config.get('agent-server:key')),
- cert: fs.readFileSync(config.get('agent-server:cert')),
- passphrase: config.get('agent-server:keyPassphrase')
- });
-}
-else {
- agentServer = http.createServer();
-}
+ // Create HTTP server.
+ const server = http.createServer(app);
-agentServer.listen(config.get('agent-server:port'));
+ app.set('port', settings.server.port);
-agentManager.createManager(agentServer);
+ server.listen(settings.server.port);
+ server.on('error', _onError.bind(null, settings.server.port));
+ server.on('listening', _onListening.bind(null, server.address()));
-/**
- * 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;
- }
-}
+ // Create HTTPS server if needed.
+ if (settings.serverSSLOptions) {
+ const httpsServer = https.createServer(settings.server.SSLOptions, app);
-/**
- * Event listener for HTTP server "listening" event.
- */
-function onListening() {
- var addr = server.address();
- var bind = typeof addr === 'string'
- ? 'pipe ' + addr
- : 'port ' + addr.port;
-
- console.log('Start listening on ' + bind);
-}
+ const httpsPort = settings.server.SSLOptions.port;
+
+ httpsServer.listen(httpsPort);
+ httpsServer.on('error', _onError.bind(null, httpsPort));
+ httpsServer.on('listening', _onListening.bind(null, httpsServer.address()));
+ }
+
+ // Start agent server.
+ const agentServer = settings.agent.SSLOptions
+ ? https.createServer(settings.agent.SSLOptions) : http.createServer();
+
+ agentServer.listen(settings.agent.port);
+ agentServer.on('error', _onError.bind(null, settings.agent.port));
+ agentServer.on('listening', _onListening.bind(null, agentServer.address()));
+
+ agent.listen(agentServer);
+
+ // Used for automated test.
+ if (process.send)
+ process.send('running');
+ }).catch((err) => {
+ console.error(err);
+
+ process.exit(1);
+ });
http://git-wip-us.apache.org/repos/asf/ignite/blob/721a1165/modules/control-center-web/src/main/js/serve/agent.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/serve/agent.js b/modules/control-center-web/src/main/js/serve/agent.js
new file mode 100644
index 0000000..d1ffe1a
--- /dev/null
+++ b/modules/control-center-web/src/main/js/serve/agent.js
@@ -0,0 +1,380 @@
+/*
+ * 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.
+ */
+
+// Fire me up!
+
+module.exports = {
+ implements: 'agent',
+ inject: ['require(fs)', 'require(ws)', 'require(apache-ignite)', 'mongo']
+};
+
+module.exports.factory = function (fs, ws, apacheIgnite, mongo) {
+ /**
+ * @constructor
+ */
+ function AgentManager() {
+ this._clients = {};
+ }
+
+ /**
+ *
+ */
+ AgentManager.prototype.listen = function (srv) {
+ if (this._server)
+ throw 'Agent server already started!';
+
+ this._server = srv;
+
+ this._wss = new ws.Server({server: this._server});
+
+ var self = this;
+
+ this._wss.on('connection', function (ws) {
+ new Client(ws, self);
+ });
+ };
+
+ /**
+ * @param userId
+ * @param {Client} client
+ */
+ AgentManager.prototype._removeClient = function (userId, client) {
+ var connections = this._clients[userId];
+
+ if (connections) {
+ var idx;
+
+ while ((idx = connections.indexOf(client)) !== -1)
+ connections.splice(idx, 1);
+
+ 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
+ * @returns {Client}
+ */
+ AgentManager.prototype.findClient = function (userId) {
+ const clientsList = this._clients[userId];
+
+ if (!clientsList || clientsList.length == 0)
+ return null;
+
+ return clientsList[0];
+ };
+
+ /**
+ * Creates an instance of server for Ignite
+ *
+ * @constructor
+ * @this {AgentServer}
+ * @param {Client} client Connected client
+ * @param {Boolean} demo Use demo node for request
+ */
+ function AgentServer(client, demo) {
+ this._client = client;
+ this._demo = !!demo;
+ }
+
+ /**
+ * 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 key in cmd._params)
+ params[key] = cmd._params[key];
+
+ var body = undefined;
+
+ var headers = undefined;
+
+ var method = 'GET';
+
+ if (cmd._isPost()) {
+ body = cmd.postData();
+
+ method = 'POST';
+
+ headers = {'JSONObject': 'application/json'};
+ }
+
+ this._client.executeRest("ignite", params, this._demo, method, headers, body, callback);
+ };
+
+ /**
+ * @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 (msgStr) {
+ var msg = JSON.parse(msgStr);
+
+ self['_rmt' + msg.type](msg);
+ });
+
+ this._reqCounter = 0;
+
+ this._cbMap = {};
+ }
+
+ Client.prototype._runCommand = function (method, args) {
+ var self = this;
+
+ return new Promise(function (resolve, reject) {
+ self._invokeRmtMethod(method, args, function (error, res) {
+ if (error != null)
+ return reject(error);
+
+ resolve(res);
+ });
+ });
+ };
+
+ /**
+ * @param {String} uri
+ * @param {Object} params
+ * @param {Boolean} demo
+ * @param {String} [method]
+ * @param {Object} [headers]
+ * @param {String} [body]
+ * @param {callback} [callback] Callback. Take 3 arguments: {Number} successStatus, {String} error, {String} response.
+ */
+ Client.prototype.executeRest = function (uri, params, demo, method, headers, body, callback) {
+ if (typeof(params) != 'object')
+ throw '"params" argument must be an object';
+
+ if (typeof(callback) != '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;
+
+ const cb = function (error, restResult) {
+ if (error)
+ return callback(error);
+
+ const restError = restResult.error;
+
+ if (restError)
+ return callback(restError);
+
+ const restCode = restResult.restCode;
+
+ if (restCode !== 200) {
+ if (restCode === 401)
+ return callback.call({code: restCode, message: "Failed to authenticate on node."});
+
+ return callback.call({
+ code: restCode,
+ message: restError || "Failed connect to node and execute REST command."
+ });
+ }
+
+ try {
+ var nodeResponse = JSON.parse(restResult.response);
+
+ if (nodeResponse.successStatus === 0)
+ return callback(null, nodeResponse.response);
+
+ switch (nodeResponse.successStatus) {
+ case 1:
+ return callback({code: 500, message: nodeResponse.error});
+ case 2:
+ return callback({code: 401, message: nodeResponse.error});
+ case 3:
+ return callback({code: 403, message: nodeResponse.error});
+ }
+
+ callback(nodeResponse.error);
+ }
+ catch (e) {
+ callback(e);
+ }
+ };
+
+ this._invokeRmtMethod('executeRest', [uri, params, demo, method, headers, body], cb);
+ };
+
+ /**
+ * @param {string} error
+ */
+ Client.prototype.authResult = function (error) {
+ return this._runCommand('authResult', [].slice.call(arguments));
+ };
+
+ /**
+ * @param {String} driverPath
+ * @param {String} driverClass
+ * @param {String} url
+ * @param {Object} info
+ * @returns {Promise} Promise on list of tables (see org.apache.ignite.schema.parser.DbTable java class)
+ */
+ Client.prototype.metadataSchemas = function (driverPath, driverClass, url, info) {
+ return this._runCommand('schemas', [].slice.call(arguments));
+ };
+
+ /**
+ * @param {String} driverPath
+ * @param {String} driverClass
+ * @param {String} url
+ * @param {Object} info
+ * @param {Array} schemas
+ * @param {Boolean} tablesOnly
+ * @returns {Promise} Promise on list of tables (see org.apache.ignite.schema.parser.DbTable java class)
+ */
+ Client.prototype.metadataTables = function (driverPath, driverClass, url, info, schemas, tablesOnly) {
+ return this._runCommand('metadata', [].slice.call(arguments));
+ };
+
+ /**
+ * @returns {Promise} Promise on list of jars from driver folder.
+ */
+ Client.prototype.availableDrivers = function () {
+ return this._runCommand('availableDrivers', [].slice.call(arguments));
+ };
+
+ /**
+ * Run http request
+ *
+ * @this {AgentServer}
+ * @param {String} method Command name.
+ * @param {Array} args Command params.
+ * @param {Function} callback on finish
+ */
+ Client.prototype._invokeRmtMethod = function (method, args, callback) {
+ if (this._ws.readyState != 1) {
+ if (callback)
+ callback('org.apache.ignite.agent.AgentException: Connection is closed');
+
+ return;
+ }
+
+ var msg = {
+ method: method,
+ args: args
+ };
+
+ if (callback) {
+ var reqId = this._reqCounter++;
+
+ this._cbMap[reqId] = callback;
+
+ msg.reqId = reqId;
+ }
+
+ this._ws.send(JSON.stringify(msg))
+ };
+
+ Client.prototype._rmtAuthMessage = function (msg) {
+ var self = this;
+
+ fs.stat('public/agent/ignite-web-agent-1.5.0.final.zip', function (err, stats) {
+ var relDate = 0;
+
+ if (!err)
+ relDate = stats.birthtime.getTime();
+
+ if ((msg.relDate || 0) < relDate)
+ self.authResult('You are using an older version of the agent. Please reload agent archive');
+
+ mongo.Account.findOne({token: msg.token}, function (err, account) {
+ if (err) {
+ self.authResult('Failed to authorize user');
+ // TODO IGNITE-1379 send error to web master.
+ }
+ else if (!account)
+ self.authResult('Invalid token, user not found');
+ else {
+ self.authResult(null);
+
+ self._user = account;
+
+ self._manager._addClient(account._id, self);
+
+ self._cluster = new apacheIgnite.Ignite(new AgentServer(self));
+
+ self._demo = new apacheIgnite.Ignite(new AgentServer(self, true));
+ }
+ });
+ });
+ };
+
+ Client.prototype._rmtCallRes = function (msg) {
+ var callback = this._cbMap[msg.reqId];
+
+ if (!callback) return;
+
+ delete this._cbMap[msg.reqId];
+
+ callback(msg.error, msg.response);
+ };
+
+ /**
+ * @returns {Ignite}
+ */
+ Client.prototype.ignite = function (demo) {
+ return demo ? this._demo : this._cluster;
+ };
+
+ return new AgentManager();
+};
http://git-wip-us.apache.org/repos/asf/ignite/blob/721a1165/modules/control-center-web/src/main/js/serve/app.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/serve/app.js b/modules/control-center-web/src/main/js/serve/app.js
new file mode 100644
index 0000000..cc93ed9
--- /dev/null
+++ b/modules/control-center-web/src/main/js/serve/app.js
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+
+// Fire me up!
+
+module.exports = {
+ implements: 'app',
+ inject: ['require(express)', 'configure', 'routes']
+};
+
+module.exports.factory = function(express, configure, routes) {
+ const app = new express();
+
+ configure(app);
+
+ routes.register(app);
+
+ return app;
+};
http://git-wip-us.apache.org/repos/asf/ignite/blob/721a1165/modules/control-center-web/src/main/js/serve/config/default.json
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/serve/config/default.json b/modules/control-center-web/src/main/js/serve/config/default.json
new file mode 100644
index 0000000..574d42a
--- /dev/null
+++ b/modules/control-center-web/src/main/js/serve/config/default.json
@@ -0,0 +1,26 @@
+{
+ "server": {
+ "port": 3000,
+ "https-port": 8443,
+ "ssl": false,
+ "key": "serve/keys/test.key",
+ "cert": "serve/keys/test.crt",
+ "keyPassphrase": "password"
+ },
+ "mongoDB": {
+ "url": "mongodb://localhost/web-control-center"
+ },
+ "agent-server": {
+ "port": 3001,
+ "ssl": true,
+ "key": "serve/keys/test.key",
+ "cert": "serve/keys/test.crt",
+ "keyPassphrase": "password"
+ },
+ "smtp": {
+ "service": "",
+ "username": "",
+ "email": "",
+ "password": ""
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/721a1165/modules/control-center-web/src/main/js/serve/configure.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/serve/configure.js b/modules/control-center-web/src/main/js/serve/configure.js
new file mode 100644
index 0000000..c16b516
--- /dev/null
+++ b/modules/control-center-web/src/main/js/serve/configure.js
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Fire me up!
+
+module.exports = {
+ implements: 'configure',
+ inject: ['require(morgan)', 'require(cookie-parser)', 'require(body-parser)', 'require(express-force-ssl)',
+ 'require(express-session)', 'require(connect-mongo)', 'require(passport)', 'settings', 'mongo']
+};
+
+module.exports.factory = function (logger, cookieParser, bodyParser, forceSSL, session, connectMongo, passport,
+ settings, mongo) {
+ return (app) => {
+ app.use(logger('dev', {
+ skip: function (req, res) {
+ return res.statusCode < 400;
+ }
+ }));
+
+ app.use(cookieParser(settings.sessionSecret));
+
+ app.use(bodyParser.json({limit: '50mb'}));
+ app.use(bodyParser.urlencoded({limit: '50mb', extended: true}));
+
+ var mongoStore = connectMongo(session);
+
+ app.use(session({
+ secret: settings.sessionSecret,
+ resave: false,
+ saveUninitialized: true,
+ cookie: {
+ expires: new Date(Date.now() + settings.cookieTTL),
+ maxAge: settings.cookieTTL
+ }
+ , store: new mongoStore({mongooseConnection: mongo.connection})
+ }));
+
+ app.use(passport.initialize());
+ app.use(passport.session());
+
+ passport.serializeUser(mongo.Account.serializeUser());
+ passport.deserializeUser(mongo.Account.deserializeUser());
+
+ passport.use(mongo.Account.createStrategy());
+
+ if (settings.SSLOptions) {
+ app.set('forceSSLOptions', settings.SSLOptions);
+
+ app.use(forceSSL);
+ }
+ };
+};
http://git-wip-us.apache.org/repos/asf/ignite/blob/721a1165/modules/control-center-web/src/main/js/serve/keys/test.crt
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/serve/keys/test.crt b/modules/control-center-web/src/main/js/serve/keys/test.crt
new file mode 100644
index 0000000..50c6d5c
--- /dev/null
+++ b/modules/control-center-web/src/main/js/serve/keys/test.crt
@@ -0,0 +1,13 @@
+-----BEGIN CERTIFICATE-----
+MIIB6zCCAVQCCQDcAphbU6UcLjANBgkqhkiG9w0BAQsFADA6MRIwEAYDVQQDDAls
+b2NhbGhvc3QxJDAiBgkqhkiG9w0BCQEWFXNldmRva2ltb3ZAYXBhY2hlLm9yZzAe
+Fw0xNTA3MTQxMzAyNTNaFw0xODA2MjMxMzAyNTNaMDoxEjAQBgNVBAMMCWxvY2Fs
+aG9zdDEkMCIGCSqGSIb3DQEJARYVc2V2ZG9raW1vdkBhcGFjaGUub3JnMIGfMA0G
+CSqGSIb3DQEBAQUAA4GNADCBiQKBgQDP/zpJrdHqCj6lPpeFF6LQtzKef6UiyBBo
+rbuOtCCgW8KMJJciluBWk2126qLt9smBN4jBpSNU3pq0r9gBMUTd/LSe7aY4D5ED
+Pjp7XsypNVKeHaHbFi7KhfHy0LYxsWiNPmmHJv4dtYOp+pGK25rkXNfyJxxjgxN6
+wo34+MnZIQIDAQABMA0GCSqGSIb3DQEBCwUAA4GBAFk9XEjcdyihws+fVmdGGUFo
+bVxI9YGH6agiNbU3WNF4B4VRzcPPW8z2mEo7eF9kgYmq/YzH4T8tgi/qkL/u8eZV
+Wmi9bg6RThLN6/hj3wVoOFKykbDQ05FFdhIJXN5UOjPmxYM97EKqg6J0W2HAb8SG
++UekPnmAo/2HTKsLykH8
+-----END CERTIFICATE-----
http://git-wip-us.apache.org/repos/asf/ignite/blob/721a1165/modules/control-center-web/src/main/js/serve/keys/test.key
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/serve/keys/test.key b/modules/control-center-web/src/main/js/serve/keys/test.key
new file mode 100644
index 0000000..1b395c0
--- /dev/null
+++ b/modules/control-center-web/src/main/js/serve/keys/test.key
@@ -0,0 +1,18 @@
+-----BEGIN RSA PRIVATE KEY-----
+Proc-Type: 4,ENCRYPTED
+DEK-Info: DES-EDE3-CBC,6798185330CE2EE2
+
+sOwkmD8rvjx11l09V26dJhLhl+SyPIhyeZ3TqHXrYCATKoXlzidT+uPu1jVYtrwr
+nBLA6TrIDYRrBNlEsqGZ0cSvWTIczzVW1xZKHEJo5q2vUT/W8u/Q1QQtS3P3GeKF
+dEzx496rpZqwwVw59GNbuIwyYoVvQf3iEXzfhplGmLPELYIplDFOLgNuXQyXSGx6
+rwKsCxXMLsDyrA6DCz0Odf08p2HvWk/s5Ne3DFcQlqRNtIrBVGD2O0/Fp8ZZ2I4E
+Yn2OIIWJff3HanOjLOWKdN8YAn5UleNmlEUdIHeS5qaQ68mabOxLkSef9qglV+sd
+FHTtUq0cG6t6nhxZBziexha6v1yl/xABAHHhNPOfak+HthWxRD4N9f1yFYAeTmkn
+4kwBWoSUe12XRf2pGNqhEUKN/KhDmWk85wI55i/Cu2XmNoiBFlS9BXrRYU8uVCJw
+KlxjKTDWl1opCyvxTDxJnMkt44ZT445LRePKVueGIIKSUIXNQypOE+C1I0CL0N2W
+Ts3m9nthquvLeMx92k7b8yW69BER5uac3SIlGCOJObQXsHgyk8wYiyd/zLKfjctG
+PXieaW81UKjp+GqWpvWPz3VqnKwoyUWeVOOTviurli6kYOrHuySTMqMb6hxJctw9
+grAQTT0UPiAKWcM7InLzZnRjco+v9QLLEokjVngXPba16K/CItFY16xuGlaFLW7Y
+XTc67AkL8b76HBZelMjmCsqjvSoULhuMFwTOvUMm/mSM8rMoi9asrJRLQHRMWCST
+/6RENPLzPlOMnNLBujpBbn8V3/aYzEZsHMI+6S3d27WYlTJIqpabSA==
+-----END RSA PRIVATE KEY-----
http://git-wip-us.apache.org/repos/asf/ignite/blob/721a1165/modules/control-center-web/src/main/js/serve/mongo.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/serve/mongo.js b/modules/control-center-web/src/main/js/serve/mongo.js
new file mode 100644
index 0000000..edfb5f8
--- /dev/null
+++ b/modules/control-center-web/src/main/js/serve/mongo.js
@@ -0,0 +1,551 @@
+/*
+ * 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.
+ */
+
+// Fire me up!
+
+module.exports = {
+ implements: 'mongo',
+ inject: ['require(mongoose-deep-populate)', 'require(passport-local-mongoose)', 'settings', 'ignite_modules/mongo:*']
+};
+
+module.exports.factory = function (deepPopulatePlugin, passportMongo, settings, pluginMongo) {
+ var mongoose = require('mongoose');
+
+ const deepPopulate = deepPopulatePlugin(mongoose);
+
+ // Connect to mongoDB database.
+ mongoose.connect(settings.mongoUrl, {server: {poolSize: 4}});
+
+ const Schema = mongoose.Schema, ObjectId = mongoose.Schema.Types.ObjectId,
+ result = { connection: mongoose.connection };
+
+ // Define Account schema.
+ var AccountSchema = new Schema({
+ username: String,
+ email: String,
+ company: String,
+ country: String,
+ lastLogin: Date,
+ admin: Boolean,
+ token: String,
+ resetPasswordToken: String
+ });
+
+ // Install passport plugin.
+ AccountSchema.plugin(passportMongo, {
+ usernameField: 'email', limitAttempts: true, lastLoginField: 'lastLogin',
+ usernameLowerCase: true
+ });
+
+ // Configure transformation to JSON.
+ AccountSchema.set('toJSON', {
+ transform: function (doc, ret) {
+ return {
+ _id: ret._id,
+ email: ret.email,
+ username: ret.username,
+ company: ret.company,
+ country: ret.country,
+ admin: ret.admin,
+ token: ret.token,
+ lastLogin: ret.lastLogin
+ };
+ }
+ });
+
+ // Define Account model.
+ result.Account = mongoose.model('Account', AccountSchema);
+
+ // Define Space model.
+ result.Space = mongoose.model('Space', new Schema({
+ name: String,
+ owner: {type: ObjectId, ref: 'Account'},
+ usedBy: [{
+ permission: {type: String, enum: ['VIEW', 'FULL']},
+ account: {type: ObjectId, ref: 'Account'}
+ }]
+ }));
+
+ // Define Domain model schema.
+ var DomainModelSchema = new Schema({
+ space: {type: ObjectId, ref: 'Space'},
+ caches: [{type: ObjectId, ref: 'Cache'}],
+ queryMetadata: {type: String, enum: ['Annotations', 'Configuration']},
+ kind: {type: String, enum: ['query', 'store', 'both']},
+ databaseSchema: String,
+ databaseTable: String,
+ keyType: String,
+ valueType: String,
+ keyFields: [{
+ databaseFieldName: String,
+ databaseFieldType: String,
+ javaFieldName: String,
+ javaFieldType: String
+ }],
+ valueFields: [{
+ databaseFieldName: String,
+ databaseFieldType: String,
+ javaFieldName: String,
+ javaFieldType: String
+ }],
+ fields: [{name: String, className: String}],
+ aliases: [{field: String, alias: String}],
+ indexes: [{
+ name: String,
+ indexType: {type: String, enum: ['SORTED', 'FULLTEXT', 'GEOSPATIAL']},
+ fields: [{name: String, direction: Boolean}]
+ }],
+ demo: Boolean
+ });
+
+ // Define model of Domain models.
+ result.DomainModel = mongoose.model('DomainModel', DomainModelSchema);
+
+ // Define Cache schema.
+ var CacheSchema = new Schema({
+ space: {type: ObjectId, ref: 'Space'},
+ name: String,
+ clusters: [{type: ObjectId, ref: 'Cluster'}],
+ domains: [{type: ObjectId, ref: 'DomainModel'}],
+ cacheMode: {type: String, enum: ['PARTITIONED', 'REPLICATED', 'LOCAL']},
+ atomicityMode: {type: String, enum: ['ATOMIC', 'TRANSACTIONAL']},
+
+ backups: Number,
+ memoryMode: {type: String, enum: ['ONHEAP_TIERED', 'OFFHEAP_TIERED', 'OFFHEAP_VALUES']},
+ offHeapMaxMemory: Number,
+ startSize: Number,
+ swapEnabled: Boolean,
+
+ evictionPolicy: {
+ kind: {type: String, enum: ['LRU', 'FIFO', 'Sorted']},
+ LRU: {
+ batchSize: Number,
+ maxMemorySize: Number,
+ maxSize: Number
+ },
+ FIFO: {
+ batchSize: Number,
+ maxMemorySize: Number,
+ maxSize: Number
+ },
+ SORTED: {
+ batchSize: Number,
+ maxMemorySize: Number,
+ maxSize: Number
+ }
+ },
+
+ rebalanceMode: {type: String, enum: ['SYNC', 'ASYNC', 'NONE']},
+ rebalanceBatchSize: Number,
+ rebalanceBatchesPrefetchCount: Number,
+ rebalanceOrder: Number,
+ rebalanceDelay: Number,
+ rebalanceTimeout: Number,
+ rebalanceThrottle: Number,
+
+ cacheStoreFactory: {
+ kind: {
+ type: String,
+ enum: ['CacheJdbcPojoStoreFactory', 'CacheJdbcBlobStoreFactory', 'CacheHibernateBlobStoreFactory']
+ },
+ CacheJdbcPojoStoreFactory: {
+ dataSourceBean: String,
+ dialect: {
+ type: String,
+ enum: ['Generic', 'Oracle', 'DB2', 'SQLServer', 'MySQL', 'PostgreSQL', 'H2']
+ }
+ },
+ CacheJdbcBlobStoreFactory: {
+ connectVia: {type: String, enum: ['URL', 'DataSource']},
+ connectionUrl: String,
+ user: String,
+ dataSourceBean: String,
+ dialect: {
+ type: String,
+ enum: ['Generic', 'Oracle', 'DB2', 'SQLServer', 'MySQL', 'PostgreSQL', 'H2']
+ },
+ initSchema: Boolean,
+ createTableQuery: String,
+ loadQuery: String,
+ insertQuery: String,
+ updateQuery: String,
+ deleteQuery: String
+ },
+ CacheHibernateBlobStoreFactory: {
+ hibernateProperties: [String]
+ }
+ },
+ storeKeepBinary: Boolean,
+ loadPreviousValue: Boolean,
+ readThrough: Boolean,
+ writeThrough: Boolean,
+
+ writeBehindEnabled: Boolean,
+ writeBehindBatchSize: Number,
+ writeBehindFlushSize: Number,
+ writeBehindFlushFrequency: Number,
+ writeBehindFlushThreadCount: Number,
+
+ invalidate: Boolean,
+ defaultLockTimeout: Number,
+ atomicWriteOrderMode: {type: String, enum: ['CLOCK', 'PRIMARY']},
+ writeSynchronizationMode: {type: String, enum: ['FULL_SYNC', 'FULL_ASYNC', 'PRIMARY_SYNC']},
+
+ sqlEscapeAll: Boolean,
+ sqlSchema: String,
+ sqlOnheapRowCacheSize: Number,
+ longQueryWarningTimeout: Number,
+ sqlFunctionClasses: [String],
+ snapshotableIndex: Boolean,
+ statisticsEnabled: Boolean,
+ managementEnabled: Boolean,
+ readFromBackup: Boolean,
+ copyOnRead: Boolean,
+ maxConcurrentAsyncOperations: Number,
+ nearCacheEnabled: Boolean,
+ nearConfiguration: {
+ nearStartSize: Number,
+ nearEvictionPolicy: {
+ kind: {type: String, enum: ['LRU', 'FIFO', 'Sorted']},
+ LRU: {
+ batchSize: Number,
+ maxMemorySize: Number,
+ maxSize: Number
+ },
+ FIFO: {
+ batchSize: Number,
+ maxMemorySize: Number,
+ maxSize: Number
+ },
+ SORTED: {
+ batchSize: Number,
+ maxMemorySize: Number,
+ maxSize: Number
+ }
+ }
+ },
+ demo: Boolean
+ });
+
+ // Install deep populate plugin.
+ CacheSchema.plugin(deepPopulate, {
+ whitelist: ['domains']
+ });
+
+ // Define Cache model.
+ result.Cache = mongoose.model('Cache', CacheSchema);
+
+ var IgfsSchema = new Schema({
+ space: {type: ObjectId, ref: 'Space'},
+ name: String,
+ clusters: [{type: ObjectId, ref: 'Cluster'}],
+ affinnityGroupSize: Number,
+ blockSize: Number,
+ streamBufferSize: Number,
+ dataCacheName: String,
+ metaCacheName: String,
+ defaultMode: {type: String, enum: ['PRIMARY', 'PROXY', 'DUAL_SYNC', 'DUAL_ASYNC']},
+ dualModeMaxPendingPutsSize: Number,
+ dualModePutExecutorService: String,
+ dualModePutExecutorServiceShutdown: Boolean,
+ fragmentizerConcurrentFiles: Number,
+ fragmentizerEnabled: Boolean,
+ fragmentizerThrottlingBlockLength: Number,
+ fragmentizerThrottlingDelay: Number,
+ ipcEndpointConfiguration: {
+ type: {type: String, enum: ['SHMEM', 'TCP']},
+ host: String,
+ port: Number,
+ memorySize: Number,
+ tokenDirectoryPath: String
+ },
+ ipcEndpointEnabled: Boolean,
+ maxSpaceSize: Number,
+ maximumTaskRangeLength: Number,
+ managementPort: Number,
+ pathModes: [{path: String, mode: {type: String, enum: ['PRIMARY', 'PROXY', 'DUAL_SYNC', 'DUAL_ASYNC']}}],
+ perNodeBatchSize: Number,
+ perNodeParallelBatchCount: Number,
+ prefetchBlocks: Number,
+ sequentialReadsBeforePrefetch: Number,
+ trashPurgeTimeout: Number,
+ secondaryFileSystemEnabled: Boolean,
+ secondaryFileSystem: {
+ uri: String,
+ cfgPath: String,
+ userName: String
+ }
+ });
+
+ // Define IGFS model.
+ result.Igfs = mongoose.model('Igfs', IgfsSchema);
+
+ // Define Cluster schema.
+ var ClusterSchema = new Schema({
+ space: {type: ObjectId, ref: 'Space'},
+ name: String,
+ localHost: String,
+ discovery: {
+ localAddress: String,
+ localPort: Number,
+ localPortRange: Number,
+ addressResolver: String,
+ socketTimeout: Number,
+ ackTimeout: Number,
+ maxAckTimeout: Number,
+ networkTimeout: Number,
+ joinTimeout: Number,
+ threadPriority: Number,
+ heartbeatFrequency: Number,
+ maxMissedHeartbeats: Number,
+ maxMissedClientHeartbeats: Number,
+ topHistorySize: Number,
+ listener: String,
+ dataExchange: String,
+ metricsProvider: String,
+ reconnectCount: Number,
+ statisticsPrintFrequency: Number,
+ ipFinderCleanFrequency: Number,
+ authenticator: String,
+ forceServerMode: Boolean,
+ clientReconnectDisabled: Boolean,
+ kind: {type: String, enum: ['Vm', 'Multicast', 'S3', 'Cloud', 'GoogleStorage', 'Jdbc', 'SharedFs']},
+ Vm: {
+ addresses: [String]
+ },
+ Multicast: {
+ multicastGroup: String,
+ multicastPort: Number,
+ responseWaitTime: Number,
+ addressRequestAttempts: Number,
+ localAddress: String,
+ addresses: [String]
+ },
+ S3: {
+ bucketName: String
+ },
+ Cloud: {
+ credential: String,
+ credentialPath: String,
+ identity: String,
+ provider: String,
+ regions: [String],
+ zones: [String]
+ },
+ GoogleStorage: {
+ projectName: String,
+ bucketName: String,
+ serviceAccountP12FilePath: String,
+ serviceAccountId: String,
+ addrReqAttempts: String
+ },
+ Jdbc: {
+ initSchema: Boolean
+ },
+ SharedFs: {
+ path: String
+ }
+ },
+ atomicConfiguration: {
+ backups: Number,
+ cacheMode: {type: String, enum: ['LOCAL', 'REPLICATED', 'PARTITIONED']},
+ atomicSequenceReserveSize: Number
+ },
+ binaryConfiguration: {
+ idMapper: String,
+ serializer: String,
+ typeConfigurations: [{typeName: String, idMapper: String, serializer: String, enum: Boolean}],
+ compactFooter: Boolean
+ },
+ caches: [{type: ObjectId, ref: 'Cache'}],
+ clockSyncSamples: Number,
+ clockSyncFrequency: Number,
+ deploymentMode: {type: String, enum: ['PRIVATE', 'ISOLATED', 'SHARED', 'CONTINUOUS']},
+ discoveryStartupDelay: Number,
+ igfsThreadPoolSize: Number,
+ igfss: [{type: ObjectId, ref: 'Igfs'}],
+ includeEventTypes: [String],
+ managementThreadPoolSize: Number,
+ marshaller: {
+ kind: {type: String, enum: ['OptimizedMarshaller', 'JdkMarshaller']},
+ OptimizedMarshaller: {
+ poolSize: Number,
+ requireSerializable: Boolean
+ }
+ },
+ marshalLocalJobs: Boolean,
+ marshallerCacheKeepAliveTime: Number,
+ marshallerCacheThreadPoolSize: Number,
+ metricsExpireTime: Number,
+ metricsHistorySize: Number,
+ metricsLogFrequency: Number,
+ metricsUpdateFrequency: Number,
+ networkTimeout: Number,
+ networkSendRetryDelay: Number,
+ networkSendRetryCount: Number,
+ communication: {
+ listener: String,
+ localAddress: String,
+ localPort: Number,
+ localPortRange: Number,
+ sharedMemoryPort: Number,
+ directBuffer: Boolean,
+ directSendBuffer: Boolean,
+ idleConnectionTimeout: Number,
+ connectTimeout: Number,
+ maxConnectTimeout: Number,
+ reconnectCount: Number,
+ socketSendBuffer: Number,
+ socketReceiveBuffer: Number,
+ messageQueueLimit: Number,
+ slowClientQueueLimit: Number,
+ tcpNoDelay: Boolean,
+ ackSendThreshold: Number,
+ unacknowledgedMessagesBufferSize: Number,
+ socketWriteTimeout: Number,
+ selectorsCount: Number,
+ addressResolver: String
+ },
+ connector: {
+ enabled: Boolean,
+ jettyPath: String,
+ host: String,
+ port: Number,
+ portRange: Number,
+ idleTimeout: Number,
+ idleQueryCursorTimeout: Number,
+ idleQueryCursorCheckFrequency: Number,
+ receiveBufferSize: Number,
+ sendBufferSize: Number,
+ directBuffer: Boolean,
+ noDelay: Boolean,
+ selectorCount: Number,
+ threadPoolSize: Number,
+ messageInterceptor: String,
+ secretKey: String,
+ sslEnabled: Boolean,
+ sslClientAuth: Boolean,
+ sslFactory: String
+ },
+ peerClassLoadingEnabled: Boolean,
+ peerClassLoadingLocalClassPathExclude: [String],
+ peerClassLoadingMissedResourcesCacheSize: Number,
+ peerClassLoadingThreadPoolSize: Number,
+ publicThreadPoolSize: Number,
+ swapSpaceSpi: {
+ kind: {type: String, enum: ['FileSwapSpaceSpi']},
+ FileSwapSpaceSpi: {
+ baseDirectory: String,
+ readStripesNumber: Number,
+ maximumSparsity: Number,
+ maxWriteQueueSize: Number,
+ writeBufferSize: Number
+ }
+ },
+ systemThreadPoolSize: Number,
+ timeServerPortBase: Number,
+ timeServerPortRange: Number,
+ transactionConfiguration: {
+ defaultTxConcurrency: {type: String, enum: ['OPTIMISTIC', 'PESSIMISTIC']},
+ defaultTxIsolation: {type: String, enum: ['READ_COMMITTED', 'REPEATABLE_READ', 'SERIALIZABLE']},
+ defaultTxTimeout: Number,
+ pessimisticTxLogLinger: Number,
+ pessimisticTxLogSize: Number,
+ txSerializableEnabled: Boolean,
+ txManagerFactory: String
+ },
+ sslEnabled: Boolean,
+ sslContextFactory: {
+ keyAlgorithm: String,
+ keyStoreFilePath: String,
+ keyStoreType: String,
+ protocol: String,
+ trustStoreFilePath: String,
+ trustStoreType: String,
+ trustManagers: [String]
+ },
+ rebalanceThreadPoolSize: Number
+ });
+
+ // Install deep populate plugin.
+ ClusterSchema.plugin(deepPopulate, {
+ whitelist: [
+ 'caches',
+ 'caches.domains',
+ 'igfss'
+ ]
+ });
+
+ // Define Cluster model.
+ result.Cluster = mongoose.model('Cluster', ClusterSchema);
+
+ result.ClusterDefaultPopulate = '';
+
+ // Define Notebook schema.
+ var NotebookSchema = new Schema({
+ space: {type: ObjectId, ref: 'Space'},
+ name: String,
+ expandedParagraphs: [Number],
+ paragraphs: [{
+ name: String,
+ query: String,
+ editor: Boolean,
+ result: {type: String, enum: ['none', 'table', 'bar', 'pie', 'line', 'area']},
+ pageSize: Number,
+ timeLineSpan: String,
+ hideSystemColumns: Boolean,
+ cacheName: String,
+ chartsOptions: {barChart: {stacked: Boolean}, areaChart: {style: String}},
+ rate: {
+ value: Number,
+ unit: Number
+ }
+ }]
+ });
+
+ // Define Notebook model.
+ result.Notebook = mongoose.model('Notebook', NotebookSchema);
+
+ result.upsert = function (model, data, cb) {
+ if (data._id) {
+ var id = data._id;
+
+ delete data._id;
+
+ model.findOneAndUpdate({_id: id}, data, cb);
+ }
+ else
+ new model(data).save(cb);
+ };
+
+ result.processed = function(err, res) {
+ if (err) {
+ res.status(500).send(err);
+
+ return false;
+ }
+
+ return true;
+ };
+
+ // Registering the routes of all plugin modules
+ for (var name in pluginMongo)
+ if (pluginMongo.hasOwnProperty(name))
+ pluginMongo[name].register(mongoose, deepPopulate, result);
+
+ return result;
+};
http://git-wip-us.apache.org/repos/asf/ignite/blob/721a1165/modules/control-center-web/src/main/js/serve/routes/admin.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/serve/routes/admin.js b/modules/control-center-web/src/main/js/serve/routes/admin.js
new file mode 100644
index 0000000..a79d584
--- /dev/null
+++ b/modules/control-center-web/src/main/js/serve/routes/admin.js
@@ -0,0 +1,126 @@
+/*
+ * 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.
+ */
+
+// Fire me up!
+
+module.exports = {
+ implements: 'admin-routes',
+ inject: ['require(lodash)', 'require(express)', 'require(nodemailer)', 'mongo']
+};
+
+module.exports.factory = function (_, express, nodemailer, mongo) {
+ return new Promise((resolve) => {
+ const router = express.Router();
+
+ /**
+ * Get list of user accounts.
+ */
+ router.post('/list', function (req, res) {
+ mongo.Account.find({}).sort('username').exec(function (err, users) {
+ if (err)
+ return res.status(500).send(err.message);
+
+ res.json(users);
+ });
+ });
+
+ // Remove user.
+ router.post('/remove', function (req, res) {
+ var userId = req.body.userId;
+
+ mongo.Account.findByIdAndRemove(userId, function (err, user) {
+ if (err)
+ return res.status(500).send(err.message);
+
+ mongo.Space.find({owner: userId}, function (err, spaces) {
+ _.forEach(spaces, function (space) {
+ mongo.Cluster.remove({space: space._id}).exec();
+ mongo.Cache.remove({space: space._id}).exec();
+ mongo.DomainModel.remove({space: space._id}).exec();
+ mongo.Notebook.remove({space: space._id}).exec();
+ mongo.Space.remove({owner: space._id}).exec();
+ });
+ });
+
+ var transporter = {
+ service: settings.smtp.service,
+ auth: {
+ user: settings.smtp.email,
+ pass: settings.smtp.password
+ }
+ };
+
+ if (transporter.service != '' || transporter.auth.user != '' || transporter.auth.pass != '') {
+ var mailer = nodemailer.createTransport(transporter);
+
+ var mailOptions = {
+ from: settings.smtp.address(settings.smtp.username, settings.smtp.email),
+ to: settings.smtp.address(user.username, user.email),
+ subject: 'Your account was deleted',
+ text: 'You are receiving this e-mail because admin remove your account.\n\n' +
+ '--------------\n' +
+ 'Apache Ignite Web Console http://' + req.headers.host + '\n'
+ };
+
+ mailer.sendMail(mailOptions, function (err) {
+ if (err)
+ return res.status(503).send('Account was removed, but failed to send e-mail notification to user!<br />' + err);
+
+ res.sendStatus(200);
+ });
+ }
+ else
+ res.sendStatus(200);
+ });
+ });
+
+ // Save user.
+ router.post('/save', function (req, res) {
+ var userId = req.body.userId;
+ var adminFlag = req.body.adminFlag;
+
+ mongo.Account.findByIdAndUpdate(userId, {admin: adminFlag}, function (err) {
+ if (err)
+ return res.status(500).send(err.message);
+
+ res.sendStatus(200);
+ });
+ });
+
+ // Become user.
+ router.get('/become', function (req, res) {
+ mongo.Account.findById(req.query.viewedUserId).exec(function (err, viewedUser) {
+ if (err)
+ return res.sendStatus(404);
+
+ req.session.viewedUser = viewedUser;
+
+ return res.sendStatus(200);
+ })
+ });
+
+ // Become user.
+ router.get('/revert/identity', function (req, res) {
+ req.session.viewedUser = null;
+
+ return res.sendStatus(200);
+ });
+
+ resolve(router);
+ });
+};
+
http://git-wip-us.apache.org/repos/asf/ignite/blob/721a1165/modules/control-center-web/src/main/js/serve/routes/agent.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/serve/routes/agent.js b/modules/control-center-web/src/main/js/serve/routes/agent.js
new file mode 100644
index 0000000..e5abf0f
--- /dev/null
+++ b/modules/control-center-web/src/main/js/serve/routes/agent.js
@@ -0,0 +1,331 @@
+/*
+ * 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.
+ */
+
+// Fire me up!
+
+module.exports = {
+ implements: 'agent-routes',
+ inject: ['require(lodash)', 'require(express)', 'require(apache-ignite)', 'require(fs)', 'require(jszip)', 'settings', 'agent']
+};
+
+/**
+ * @param _
+ * @param express
+ * @param apacheIgnite
+ * @param fs
+ * @param JSZip
+ * @param settings
+ * @param {AgentManager} agent
+ * @returns {Promise}
+ */
+module.exports.factory = function (_, express, apacheIgnite, fs, JSZip, settings, agent) {
+ return new Promise((resolve) => {
+ const router = express.Router();
+
+ const SqlFieldsQuery = apacheIgnite.SqlFieldsQuery, ScanQuery = apacheIgnite.ScanQuery;
+
+ const _client = (userId) => {
+ return new Promise(function (resolve, reject) {
+ var client = agent.findClient(userId);
+
+ if (client)
+ return resolve(client);
+
+ reject({code: 503, message: 'Connection to Ignite Web Agent is not established'});
+ });
+ };
+
+ const _compact = (className) => {
+ return className.replace('java.lang.', '').replace('java.util.', '').replace('java.sql.', '');
+ };
+
+ const _handleException = (res) => {
+ return function (error) {
+ if (_.isObject(error))
+ return res.status(error.code).send(error.message);
+
+ return res.status(500).send(error);
+ }
+ };
+
+ /* Get grid topology. */
+ router.get('/download/zip', function (req, res) {
+ var agentFld = settings.agentFile;
+ var agentZip = agentFld + '.zip';
+ var agentPathZip = 'public/agent/' + agentFld + '.zip';
+
+ fs.stat(agentPathZip, function (err, stats) {
+ if (err)
+ return res.download(agentPathZip, agentZip);
+
+ // Read a zip file.
+ fs.readFile(agentPathZip, function (err, data) {
+ if (err)
+ return res.download(agentPathZip, agentZip);
+
+ var zip = new JSZip(data);
+
+ var prop = [];
+
+ var host = req.hostname.match(/:/g) ? req.hostname.slice(0, req.hostname.indexOf(':')) : req.hostname;
+
+ prop.push('token=' + req.user.token);
+ prop.push('server-uri=wss://' + host + ':' + settings.agentPort);
+ prop.push('#Uncomment following options if needed:');
+ prop.push('#node-uri=http://localhost:8080');
+ prop.push('#driver-folder=./jdbc-drivers');
+ prop.push('');
+ prop.push("#Note: Don't change this auto generated line");
+ prop.push('rel-date=' + stats.birthtime.getTime());
+
+ zip.file(agentFld + '/default.properties', prop.join('\n'));
+
+ var buffer = zip.generate({type: 'nodebuffer', platform: 'UNIX'});
+
+ // Set the archive name.
+ res.attachment(agentZip);
+
+ res.send(buffer);
+ });
+ });
+ });
+
+ /* Get grid topology. */
+ router.post('/topology', function (req, res) {
+ _client(req.currentUserId())
+ .then((client) => client.ignite(req.body.demo).cluster(req.body.attr, req.body.mtr))
+ .then((clusters) => res.json(clusters))
+ .catch(_handleException(res));
+ });
+
+ /* Execute query. */
+ router.post('/query', function (req, res) {
+ _client(req.currentUserId())
+ .then((client) => {
+ // Create sql query.
+ var qry = new SqlFieldsQuery(req.body.query);
+
+ // Set page size for query.
+ qry.setPageSize(req.body.pageSize);
+
+ return client.ignite(req.body.demo).cache(req.body.cacheName).query(qry).nextPage()
+ })
+ .then((cursor) => res.json({
+ meta: cursor.fieldsMetadata(),
+ rows: cursor.page(),
+ queryId: cursor.queryId()
+ }))
+ .catch(_handleException(res));
+ });
+
+ /* Execute query getAll. */
+ router.post('/query/getAll', function (req, res) {
+ _client(req.currentUserId())
+ .then((client) => {
+ // Create sql query.
+ const qry = req.body.query ? new SqlFieldsQuery(req.body.query) : new ScanQuery();
+
+ // Set page size for query.
+ qry.setPageSize(1024);
+
+ // Get query cursor.
+ const cursor = client.ignite(req.body.demo).cache(req.body.cacheName).query(qry);
+
+ return new Promise(function (resolve) {
+ cursor.getAll().then(rows => resolve({meta: cursor.fieldsMetadata(), rows}))
+ });
+ })
+ .then(response => res.json(response))
+ .catch(_handleException(res));
+ });
+
+ /* Execute query. */
+ router.post('/scan', function (req, res) {
+ _client(req.currentUserId())
+ .then((client) => {
+ // Create sql query.
+ var qry = new ScanQuery();
+
+ // Set page size for query.
+ qry.setPageSize(req.body.pageSize);
+
+ // Get query cursor.
+ return client.ignite(req.body.demo).cache(req.body.cacheName).query(qry).nextPage()
+ })
+ .then((cursor) => res.json({
+ meta: cursor.fieldsMetadata(),
+ rows: cursor.page(),
+ queryId: cursor.queryId()
+ }))
+ .catch(_handleException(res));
+ });
+
+ /* Get next query page. */
+ router.post('/query/fetch', function (req, res) {
+ _client(req.currentUserId())
+ .then((client) => {
+ var cache = client.ignite(req.body.demo).cache(req.body.cacheName);
+
+ var cmd = cache._createCommand('qryfetch')
+ .addParam('qryId', req.body.queryId)
+ .addParam('pageSize', req.body.pageSize);
+
+ return cache.__createPromise(cmd);
+ })
+ .then((page) => res.json({rows: page['items'], last: page === null || page['last']}))
+ .catch(_handleException(res));
+ });
+
+ /* Close query cursor by id. */
+ router.post('/query/close', function (req, res) {
+ _client(req.currentUserId())
+ .then((client) => {
+ var cache = client.ignite(req.body.demo).cache(req.body.cacheName);
+
+ return cache.__createPromise(cache._createCommand('qrycls').addParam('qryId', req.body.queryId))
+ })
+ .then(() => res.sendStatus(200))
+ .catch(_handleException(res));
+ });
+
+ /* Get metadata for cache. */
+ router.post('/cache/metadata', function (req, res) {
+ _client(req.currentUserId())
+ .then((client) => client.ignite(req.body.demo).cache(req.body.cacheName).metadata())
+ .then((caches) => {
+ var types = [];
+
+ for (var meta of caches) {
+ var cacheTypes = meta.types.map(function (typeName) {
+ var fields = meta.fields[typeName];
+
+ var columns = [];
+
+ for (var fieldName in fields) {
+ var fieldClass = _compact(fields[fieldName]);
+
+ columns.push({
+ type: 'field',
+ name: fieldName,
+ clazz: fieldClass,
+ system: fieldName == "_KEY" || fieldName == "_VAL",
+ cacheName: meta.cacheName,
+ typeName: typeName
+ });
+ }
+
+ var indexes = [];
+
+ for (var index of meta.indexes[typeName]) {
+ fields = [];
+
+ for (var field of index.fields) {
+ fields.push({
+ type: 'index-field',
+ name: field,
+ order: index.descendings.indexOf(field) < 0,
+ unique: index.unique,
+ cacheName: meta.cacheName,
+ typeName: typeName
+ });
+ }
+
+ if (fields.length > 0)
+ indexes.push({
+ type: 'index',
+ name: index.name,
+ children: fields,
+ cacheName: meta.cacheName,
+ typeName: typeName
+ });
+ }
+
+ columns = _.sortBy(columns, 'name');
+
+ if (!_.isEmpty(indexes))
+ columns = columns.concat({
+ type: 'indexes',
+ name: 'Indexes',
+ cacheName: meta.cacheName,
+ typeName: typeName,
+ children: indexes
+ });
+
+ return {
+ type: 'type',
+ cacheName: meta.cacheName || "",
+ typeName: typeName,
+ children: columns
+ };
+ });
+
+ if (!_.isEmpty(cacheTypes))
+ types = types.concat(cacheTypes);
+ }
+
+ res.json(types);
+ })
+ .catch(_handleException(res));
+ });
+
+ /* Ping client. */
+ router.post('/ping', function (req, res) {
+ _client(req.currentUserId())
+ .then(() => res.sendStatus(200))
+ .catch(_handleException(res));
+ });
+
+ /* Get JDBC drivers list. */
+ router.post('/drivers', function (req, res) {
+ _client(req.currentUserId())
+ .then((client) => client.availableDrivers())
+ .then((arr) => res.json(arr))
+ .catch(_handleException(res));
+ });
+
+ /** Get database schemas. */
+ router.post('/schemas', function (req, res) {
+ _client(req.currentUserId())
+ .then((client) => {
+ var args = req.body;
+
+ args.jdbcInfo = {user: args.user, password: args.password};
+
+ return client.metadataSchemas(args.jdbcDriverJar, args.jdbcDriverClass, args.jdbcUrl, args.jdbcInfo)
+ })
+ .then((arr) => res.json(arr))
+ .catch(_handleException(res));
+ });
+
+ /** Get database tables. */
+ router.post('/tables', function (req, res) {
+ _client(req.currentUserId())
+ .then((client) => {
+ var args = req.body;
+
+ args.jdbcInfo = {user: args.user, password: args.password};
+
+ return client.metadataTables(args.jdbcDriverJar, args.jdbcDriverClass, args.jdbcUrl, args.jdbcInfo, args.schemas, args.tablesOnly)
+ })
+ .then((arr) => res.json(arr))
+ .catch(_handleException(res));
+ });
+
+ resolve(router);
+ });
+};
+
[3/3] ignite git commit: IGNITE-843 Refactored server side.
Posted by an...@apache.org.
IGNITE-843 Refactored server side.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/721a1165
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/721a1165
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/721a1165
Branch: refs/heads/ignite-843-rc2
Commit: 721a116542c5bae0d891b0e674ee9f6e9ee3c1a7
Parents: 9073514
Author: Andrey <an...@gridgain.com>
Authored: Mon Feb 8 10:44:34 2016 +0700
Committer: Andrey <an...@gridgain.com>
Committed: Mon Feb 8 10:44:34 2016 +0700
----------------------------------------------------------------------
.../src/main/js/agents/agent-manager.js | 351 ------------
.../src/main/js/agents/agent-server.js | 64 ---
modules/control-center-web/src/main/js/app.js | 164 ------
.../src/main/js/config/default.json | 26 -
modules/control-center-web/src/main/js/db.js | 534 ------------------
.../src/main/js/helpers/configuration-loader.js | 75 ---
.../src/main/js/keys/test.crt | 13 -
.../src/main/js/keys/test.key | 18 -
.../src/main/js/routes/admin.js | 119 ----
.../src/main/js/routes/agent.js | 298 ----------
.../src/main/js/routes/caches.js | 182 ------
.../src/main/js/routes/clusters.js | 167 ------
.../src/main/js/routes/domains.js | 277 ----------
.../src/main/js/routes/igfs.js | 143 -----
.../src/main/js/routes/notebooks.js | 151 -----
.../src/main/js/routes/profile.js | 85 ---
.../src/main/js/routes/public.js | 231 --------
modules/control-center-web/src/main/js/serve.js | 164 +++---
.../src/main/js/serve/agent.js | 380 +++++++++++++
.../control-center-web/src/main/js/serve/app.js | 33 ++
.../src/main/js/serve/config/default.json | 26 +
.../src/main/js/serve/configure.js | 67 +++
.../src/main/js/serve/keys/test.crt | 13 +
.../src/main/js/serve/keys/test.key | 18 +
.../src/main/js/serve/mongo.js | 551 +++++++++++++++++++
.../src/main/js/serve/routes/admin.js | 126 +++++
.../src/main/js/serve/routes/agent.js | 331 +++++++++++
.../src/main/js/serve/routes/caches.js | 196 +++++++
.../src/main/js/serve/routes/clusters.js | 181 ++++++
.../src/main/js/serve/routes/domains.js | 285 ++++++++++
.../src/main/js/serve/routes/igfs.js | 154 ++++++
.../src/main/js/serve/routes/notebooks.js | 159 ++++++
.../src/main/js/serve/routes/profile.js | 93 ++++
.../src/main/js/serve/routes/public.js | 250 +++++++++
.../src/main/js/serve/routes/routes.js | 106 ++++
.../src/main/js/serve/settings.js | 78 +++
36 files changed, 3122 insertions(+), 2987 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/721a1165/modules/control-center-web/src/main/js/agents/agent-manager.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/agents/agent-manager.js b/modules/control-center-web/src/main/js/agents/agent-manager.js
deleted file mode 100644
index 354a163..0000000
--- a/modules/control-center-web/src/main/js/agents/agent-manager.js
+++ /dev/null
@@ -1,351 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-var WebSocketServer = require('ws').Server;
-
-var apacheIgnite = require('apache-ignite');
-
-var db = require('../db');
-
-var AgentServer = require('./agent-server').AgentServer;
-
-/**
- * @constructor
- */
-function AgentManager(srv) {
- this._clients = {};
-
- this._server = srv;
-
- this._wss = new WebSocketServer({ server: this._server });
-
- var self = this;
-
- this._wss.on('connection', function(ws) {
- 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
- * @returns {Client}
- */
-AgentManager.prototype.findClient = function(userId) {
- var clientsList = this._clients[userId];
-
- if (!clientsList || clientsList.length == 0)
- return null;
-
- return clientsList[0];
-};
-
-/**
- * @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 (msgStr) {
- var msg = JSON.parse(msgStr);
-
- self['_rmt' + msg.type](msg);
- });
-
- this._reqCounter = 0;
-
- this._cbMap = {};
-}
-
-Client.prototype._runCommand = function(method, args) {
- var self = this;
-
- return new Promise(function(resolve, reject) {
- self._invokeRmtMethod(method, args, function(error, res) {
- if (error != null)
- return reject(error);
-
- resolve(res);
- });
- });
-};
-
-/**
- * @param {String} uri
- * @param {Object} params
- * @param {Boolean} demo
- * @param {String} [method]
- * @param {Object} [headers]
- * @param {String} [body]
- * @param {callback} [callback] Callback. Take 3 arguments: {Number} successStatus, {String} error, {String} response.
- */
-Client.prototype.executeRest = function(uri, params, demo, method, headers, body, callback) {
- if (typeof(params) != 'object')
- throw '"params" argument must be an object';
-
- if (typeof(callback) != '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;
-
- const cb = function(error, restResult) {
- if (error)
- return callback(error);
-
- const restError = restResult.error;
-
- if (restError)
- return callback(restError);
-
- const restCode = restResult.restCode;
-
- if (restCode !== 200) {
- if (restCode === 401)
- return callback.call({code: restCode, message: "Failed to authenticate on node."});
-
- return callback.call({code: restCode, message: restError || "Failed connect to node and execute REST command."});
- }
-
- try {
- var nodeResponse = JSON.parse(restResult.response);
-
- if (nodeResponse.successStatus === 0)
- return callback(null, nodeResponse.response);
-
- switch (nodeResponse.successStatus) {
- case 1:
- return callback({code: 500, message: nodeResponse.error});
- case 2:
- return callback({code: 401, message: nodeResponse.error});
- case 3:
- return callback({code: 403, message: nodeResponse.error});
- }
-
- callback(nodeResponse.error);
- }
- catch (e) {
- callback(e);
- }
- };
-
- this._invokeRmtMethod('executeRest', [uri, params, demo, method, headers, body], cb);
-};
-
-/**
- * @param {string} error
- */
-Client.prototype.authResult = function(error) {
- return this._runCommand('authResult', [].slice.call(arguments));
-};
-
-/**
- * @param {String} driverPath
- * @param {String} driverClass
- * @param {String} url
- * @param {Object} info
- * @returns {Promise} Promise on list of tables (see org.apache.ignite.schema.parser.DbTable java class)
- */
-Client.prototype.metadataSchemas = function(driverPath, driverClass, url, info) {
- return this._runCommand('schemas', [].slice.call(arguments));
-};
-
-/**
- * @param {String} driverPath
- * @param {String} driverClass
- * @param {String} url
- * @param {Object} info
- * @param {Array} schemas
- * @param {Boolean} tablesOnly
- * @returns {Promise} Promise on list of tables (see org.apache.ignite.schema.parser.DbTable java class)
- */
-Client.prototype.metadataTables = function(driverPath, driverClass, url, info, schemas, tablesOnly) {
- return this._runCommand('metadata', [].slice.call(arguments));
-};
-
-/**
- * @returns {Promise} Promise on list of jars from driver folder.
- */
-Client.prototype.availableDrivers = function() {
- return this._runCommand('availableDrivers', [].slice.call(arguments));
-};
-
-/**
- * Run http request
- *
- * @this {AgentServer}
- * @param {String} method Command name.
- * @param {Array} args Command params.
- * @param {Function} callback on finish
- */
-Client.prototype._invokeRmtMethod = function(method, args, callback) {
- if (this._ws.readyState != 1) {
- if (callback)
- callback('org.apache.ignite.agent.AgentException: Connection is closed');
-
- return;
- }
-
- var msg = {
- method: method,
- args: args
- };
-
- if (callback) {
- var reqId = this._reqCounter++;
-
- this._cbMap[reqId] = callback;
-
- msg.reqId = reqId;
- }
-
- this._ws.send(JSON.stringify(msg))
-};
-
-Client.prototype._rmtAuthMessage = function(msg) {
- var self = this;
-
- var fs = require('fs');
-
- fs.stat('public/agent/ignite-web-agent-1.5.0.final.zip', function(err, stats) {
- var relDate = 0;
-
- if (!err)
- relDate = stats.birthtime.getTime();
-
- if ((msg.relDate || 0) < relDate)
- self.authResult('You are using an older version of the agent. Please reload agent archive');
-
- db.Account.findOne({ token: msg.token }, function (err, account) {
- if (err) {
- self.authResult('Failed to authorize user');
- // TODO IGNITE-1379 send error to web master.
- }
- else if (!account)
- self.authResult('Invalid token, user not found');
- else {
- self.authResult(null);
-
- self._user = account;
-
- self._manager._addClient(account._id, self);
-
- self._cluster = new apacheIgnite.Ignite(new AgentServer(self));
-
- self._demo = new apacheIgnite.Ignite(new AgentServer(self, true));
- }
- });
- });
-};
-
-Client.prototype._rmtCallRes = function(msg) {
- var callback = this._cbMap[msg.reqId];
-
- if (!callback) return;
-
- delete this._cbMap[msg.reqId];
-
- callback(msg.error, msg.response);
-};
-
-/**
- * @returns {Ignite}
- */
-Client.prototype.ignite = function(demo) {
- return demo ? this._demo : this._cluster;
-};
-
-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);
-};
-
-/**
- * @returns {AgentManager}
- */
-exports.getAgentManager = function() {
- return manager;
-};
http://git-wip-us.apache.org/repos/asf/ignite/blob/721a1165/modules/control-center-web/src/main/js/agents/agent-server.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/agents/agent-server.js b/modules/control-center-web/src/main/js/agents/agent-server.js
deleted file mode 100644
index 51303ba..0000000
--- a/modules/control-center-web/src/main/js/agents/agent-server.js
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-var _ = require('lodash');
-
-/**
- * Creates an instance of server for Ignite
- *
- * @constructor
- * @this {AgentServer}
- * @param {Client} client Connected client
- * @param {Boolean} demo Use demo node for request
- */
-function AgentServer(client, demo) {
- this._client = client;
- this._demo = !!demo;
-}
-
-/**
- * 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()};
-
- _.forEach(cmd._params, function (p) {
- params[p.key] = p.value;
- });
-
- var body = undefined;
-
- var headers = undefined;
-
- var method = 'GET';
-
- if (cmd._isPost()) {
- body = cmd.postData();
-
- method = 'POST';
-
- headers = {'JSONObject': 'application/json'};
- }
-
- this._client.executeRest("ignite", params, this._demo, method, headers, body, callback);
-};
-
-exports.AgentServer = AgentServer;
http://git-wip-us.apache.org/repos/asf/ignite/blob/721a1165/modules/control-center-web/src/main/js/app.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/app.js b/modules/control-center-web/src/main/js/app.js
deleted file mode 100644
index c6dd247..0000000
--- a/modules/control-center-web/src/main/js/app.js
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-var fs = require('fs');
-var express = require('express');
-var path = require('path');
-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 forceSSL = require('express-force-ssl');
-var config = require('./helpers/configuration-loader.js');
-
-var publicRoutes = require('./routes/public');
-var notebooksRoutes = require('./routes/notebooks');
-var clustersRouter = require('./routes/clusters');
-var cachesRouter = require('./routes/caches');
-var domainsRouter = require('./routes/domains');
-var igfsRouter = require('./routes/igfs');
-var adminRouter = require('./routes/admin');
-var profileRouter = require('./routes/profile');
-var agentRouter = require('./routes/agent');
-
-var passport = require('passport');
-
-var db = require('./db');
-
-var app = express();
-
-app.use(cookieParser('keyboard cat'));
-
-app.use(bodyParser.json({limit: '50mb'}));
-app.use(bodyParser.urlencoded({limit: '50mb', extended: true}));
-
-app.use(logger('dev', {
- skip: function (req, res) {
- return res.statusCode < 400;
- }
-}));
-
-var month = 3600000 * 24 * 30;
-
-app.use(session({
- secret: 'keyboard cat',
- resave: false,
- saveUninitialized: true,
- cookie: {
- expires: new Date(Date.now() + month),
- maxAge: month
- },
- store: new mongoStore({
- mongooseConnection: db.mongoose.connection
- })
-}));
-
-app.use(passport.initialize());
-app.use(passport.session());
-
-passport.serializeUser(db.Account.serializeUser());
-passport.deserializeUser(db.Account.deserializeUser());
-
-passport.use(db.Account.createStrategy());
-
-if (config.get('server:ssl')) {
- var httpsPort = config.normalizePort(config.get('server:https-port') || 443);
-
- app.set('forceSSLOptions', {
- enable301Redirects: true,
- trustXFPHeader: true,
- httpsPort: httpsPort
- });
-
- app.use(forceSSL);
-}
-
-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) {
- 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/domains', domainsRouter);
-app.use('/configuration/igfs', igfsRouter);
-
-app.use('/agent', mustAuthenticated, agentRouter);
-app.use('/notebooks', mustAuthenticated, notebooksRoutes);
-
-config.findIgniteModules()
- .filter(function(path) { return path.match(/\/routes\/.+\.js$/); })
- .forEach(function(route) { require(route)(app); });
-
-// 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/ignite/blob/721a1165/modules/control-center-web/src/main/js/config/default.json
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/config/default.json b/modules/control-center-web/src/main/js/config/default.json
deleted file mode 100644
index 4be4ef5..0000000
--- a/modules/control-center-web/src/main/js/config/default.json
+++ /dev/null
@@ -1,26 +0,0 @@
-{
- "server": {
- "port": 3000,
- "https-port": 8443,
- "ssl": false,
- "key": "keys/test.key",
- "cert": "keys/test.crt",
- "keyPassphrase": "password"
- },
- "mongoDB": {
- "url": "mongodb://localhost/web-control-center"
- },
- "agent-server": {
- "port": 3001,
- "ssl": true,
- "key": "keys/test.key",
- "cert": "keys/test.crt",
- "keyPassphrase": "password"
- },
- "smtp": {
- "service": "",
- "username": "",
- "email": "",
- "password": ""
- }
-}
http://git-wip-us.apache.org/repos/asf/ignite/blob/721a1165/modules/control-center-web/src/main/js/db.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/db.js b/modules/control-center-web/src/main/js/db.js
deleted file mode 100644
index ea859e1..0000000
--- a/modules/control-center-web/src/main/js/db.js
+++ /dev/null
@@ -1,534 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-var config = require('./helpers/configuration-loader.js');
-var path = require('path');
-
-// Mongoose for mongodb.
-var mongoose = require('mongoose'),
- Schema = mongoose.Schema,
- ObjectId = mongoose.Schema.Types.ObjectId,
- passportLocalMongoose = require('passport-local-mongoose');
-
-var deepPopulate = require('mongoose-deep-populate')( mongoose);
-
-// Connect to mongoDB database.
-mongoose.connect(config.get('mongoDB:url'), {server: {poolSize: 4}});
-
-// Define Account schema.
-var AccountSchema = new Schema({
- username: String,
- email: String,
- company: String,
- country: String,
- lastLogin: Date,
- admin: Boolean,
- token: String,
- resetPasswordToken: String
-});
-
-// Install passport plugin.
-AccountSchema.plugin(passportLocalMongoose, {usernameField: 'email', limitAttempts: true, lastLoginField: 'lastLogin',
- usernameLowerCase: true});
-
-// Configure transformation to JSON.
-AccountSchema.set('toJSON', {
- transform: function(doc, ret) {
- return {
- _id: ret._id,
- email: ret.email,
- username: ret.username,
- company: ret.company,
- country: ret.country,
- admin: ret.admin,
- token: ret.token,
- lastLogin: ret.lastLogin
- };
- }
-});
-
-// Define Account model.
-exports.Account = mongoose.model('Account', AccountSchema);
-
-// Define Space model.
-exports.Space = mongoose.model('Space', new Schema({
- name: String,
- owner: {type: ObjectId, ref: 'Account'},
- usedBy: [{
- permission: {type: String, enum: ['VIEW', 'FULL']},
- account: {type: ObjectId, ref: 'Account'}
- }]
-}));
-
-// Define Domain model schema.
-var DomainModelSchema = new Schema({
- space: {type: ObjectId, ref: 'Space'},
- caches: [{type: ObjectId, ref: 'Cache'}],
- queryMetadata: {type: String, enum: ['Annotations', 'Configuration']},
- kind: {type: String, enum: ['query', 'store', 'both']},
- databaseSchema: String,
- databaseTable: String,
- keyType: String,
- valueType: String,
- keyFields: [{databaseFieldName: String, databaseFieldType: String, javaFieldName: String, javaFieldType: String}],
- valueFields: [{databaseFieldName: String, databaseFieldType: String, javaFieldName: String, javaFieldType: String}],
- fields: [{name: String, className: String}],
- aliases: [{field: String, alias: String}],
- indexes: [{name: String, indexType: {type: String, enum: ['SORTED', 'FULLTEXT', 'GEOSPATIAL']}, fields: [{name: String, direction: Boolean}]}],
- demo: Boolean
-});
-
-// Define model of Domain models.
-exports.DomainModel = mongoose.model('DomainModel', DomainModelSchema);
-
-// Define Cache schema.
-var CacheSchema = new Schema({
- space: {type: ObjectId, ref: 'Space'},
- name: String,
- clusters: [{type: ObjectId, ref: 'Cluster'}],
- domains: [{type: ObjectId, ref: 'DomainModel'}],
- cacheMode: {type: String, enum: ['PARTITIONED', 'REPLICATED', 'LOCAL']},
- atomicityMode: {type: String, enum: ['ATOMIC', 'TRANSACTIONAL']},
-
- backups: Number,
- memoryMode: {type: String, enum: ['ONHEAP_TIERED', 'OFFHEAP_TIERED', 'OFFHEAP_VALUES']},
- offHeapMaxMemory: Number,
- startSize: Number,
- swapEnabled: Boolean,
-
- evictionPolicy: {
- kind: {type: String, enum: ['LRU', 'FIFO', 'Sorted']},
- LRU: {
- batchSize: Number,
- maxMemorySize: Number,
- maxSize: Number
- },
- FIFO: {
- batchSize: Number,
- maxMemorySize: Number,
- maxSize: Number
- },
- SORTED: {
- batchSize: Number,
- maxMemorySize: Number,
- maxSize: Number
- }
- },
-
- rebalanceMode: {type: String, enum: ['SYNC', 'ASYNC', 'NONE']},
- rebalanceBatchSize: Number,
- rebalanceBatchesPrefetchCount: Number,
- rebalanceOrder: Number,
- rebalanceDelay: Number,
- rebalanceTimeout: Number,
- rebalanceThrottle: Number,
-
- cacheStoreFactory: {
- kind: {
- type: String,
- enum: ['CacheJdbcPojoStoreFactory', 'CacheJdbcBlobStoreFactory', 'CacheHibernateBlobStoreFactory']
- },
- CacheJdbcPojoStoreFactory: {
- dataSourceBean: String,
- dialect: {
- type: String,
- enum: ['Generic', 'Oracle', 'DB2', 'SQLServer', 'MySQL', 'PostgreSQL', 'H2']
- }
- },
- CacheJdbcBlobStoreFactory: {
- connectVia: {type: String, enum: ['URL', 'DataSource']},
- connectionUrl: String,
- user: String,
- dataSourceBean: String,
- dialect: {
- type: String,
- enum: ['Generic', 'Oracle', 'DB2', 'SQLServer', 'MySQL', 'PostgreSQL', 'H2']
- },
- initSchema: Boolean,
- createTableQuery: String,
- loadQuery: String,
- insertQuery: String,
- updateQuery: String,
- deleteQuery: String
- },
- CacheHibernateBlobStoreFactory: {
- hibernateProperties: [String]
- }
- },
- storeKeepBinary: Boolean,
- loadPreviousValue: Boolean,
- readThrough: Boolean,
- writeThrough: Boolean,
-
- writeBehindEnabled: Boolean,
- writeBehindBatchSize: Number,
- writeBehindFlushSize: Number,
- writeBehindFlushFrequency: Number,
- writeBehindFlushThreadCount: Number,
-
- invalidate: Boolean,
- defaultLockTimeout: Number,
- atomicWriteOrderMode: {type: String, enum: ['CLOCK', 'PRIMARY']},
- writeSynchronizationMode: {type: String, enum: ['FULL_SYNC', 'FULL_ASYNC', 'PRIMARY_SYNC']},
-
- sqlEscapeAll: Boolean,
- sqlSchema: String,
- sqlOnheapRowCacheSize: Number,
- longQueryWarningTimeout: Number,
- sqlFunctionClasses: [String],
- snapshotableIndex: Boolean,
- statisticsEnabled: Boolean,
- managementEnabled: Boolean,
- readFromBackup: Boolean,
- copyOnRead: Boolean,
- maxConcurrentAsyncOperations: Number,
- nearCacheEnabled: Boolean,
- nearConfiguration: {
- nearStartSize: Number,
- nearEvictionPolicy: {
- kind: {type: String, enum: ['LRU', 'FIFO', 'Sorted']},
- LRU: {
- batchSize: Number,
- maxMemorySize: Number,
- maxSize: Number
- },
- FIFO: {
- batchSize: Number,
- maxMemorySize: Number,
- maxSize: Number
- },
- SORTED: {
- batchSize: Number,
- maxMemorySize: Number,
- maxSize: Number
- }
- }
- },
- demo: Boolean
-});
-
-// Install deep populate plugin.
-CacheSchema.plugin(deepPopulate, {
- whitelist: ['domains']
-});
-
-// Define Cache model.
-exports.Cache = mongoose.model('Cache', CacheSchema);
-
-var IgfsSchema = new Schema({
- space: {type: ObjectId, ref: 'Space'},
- name: String,
- clusters: [{type: ObjectId, ref: 'Cluster'}],
- affinnityGroupSize: Number,
- blockSize: Number,
- streamBufferSize: Number,
- dataCacheName: String,
- metaCacheName: String,
- defaultMode: {type: String, enum: ['PRIMARY', 'PROXY', 'DUAL_SYNC', 'DUAL_ASYNC']},
- dualModeMaxPendingPutsSize: Number,
- dualModePutExecutorService: String,
- dualModePutExecutorServiceShutdown: Boolean,
- fragmentizerConcurrentFiles: Number,
- fragmentizerEnabled: Boolean,
- fragmentizerThrottlingBlockLength: Number,
- fragmentizerThrottlingDelay: Number,
- ipcEndpointConfiguration: {
- type: {type: String, enum: ['SHMEM', 'TCP']},
- host: String,
- port: Number,
- memorySize: Number,
- tokenDirectoryPath: String
- },
- ipcEndpointEnabled: Boolean,
- maxSpaceSize: Number,
- maximumTaskRangeLength: Number,
- managementPort: Number,
- pathModes: [{path: String, mode: {type: String, enum: ['PRIMARY', 'PROXY', 'DUAL_SYNC', 'DUAL_ASYNC']}}],
- perNodeBatchSize: Number,
- perNodeParallelBatchCount: Number,
- prefetchBlocks: Number,
- sequentialReadsBeforePrefetch: Number,
- trashPurgeTimeout: Number,
- secondaryFileSystemEnabled: Boolean,
- secondaryFileSystem: {
- uri: String,
- cfgPath: String,
- userName: String
- }
-});
-
-// Define IGFS model.
-exports.Igfs = mongoose.model('Igfs', IgfsSchema);
-
-// Define Cluster schema.
-var ClusterSchema = new Schema({
- space: {type: ObjectId, ref: 'Space'},
- name: String,
- localHost: String,
- discovery: {
- localAddress: String,
- localPort: Number,
- localPortRange: Number,
- addressResolver: String,
- socketTimeout: Number,
- ackTimeout: Number,
- maxAckTimeout: Number,
- networkTimeout: Number,
- joinTimeout: Number,
- threadPriority: Number,
- heartbeatFrequency: Number,
- maxMissedHeartbeats: Number,
- maxMissedClientHeartbeats: Number,
- topHistorySize: Number,
- listener: String,
- dataExchange: String,
- metricsProvider: String,
- reconnectCount: Number,
- statisticsPrintFrequency: Number,
- ipFinderCleanFrequency: Number,
- authenticator: String,
- forceServerMode: Boolean,
- clientReconnectDisabled: Boolean,
- kind: {type: String, enum: ['Vm', 'Multicast', 'S3', 'Cloud', 'GoogleStorage', 'Jdbc', 'SharedFs']},
- Vm: {
- addresses: [String]
- },
- Multicast: {
- multicastGroup: String,
- multicastPort: Number,
- responseWaitTime: Number,
- addressRequestAttempts: Number,
- localAddress: String,
- addresses: [String]
- },
- S3: {
- bucketName: String
- },
- Cloud: {
- credential: String,
- credentialPath: String,
- identity: String,
- provider: String,
- regions: [String],
- zones: [String]
- },
- GoogleStorage: {
- projectName: String,
- bucketName: String,
- serviceAccountP12FilePath: String,
- serviceAccountId: String,
- addrReqAttempts: String
- },
- Jdbc: {
- initSchema: Boolean
- },
- SharedFs: {
- path: String
- }
- },
- atomicConfiguration: {
- backups: Number,
- cacheMode: {type: String, enum: ['LOCAL', 'REPLICATED', 'PARTITIONED']},
- atomicSequenceReserveSize: Number
- },
- binaryConfiguration: {
- idMapper: String,
- serializer: String,
- typeConfigurations: [{typeName: String, idMapper: String, serializer: String, enum: Boolean}],
- compactFooter: Boolean
- },
- caches: [{type: ObjectId, ref: 'Cache'}],
- clockSyncSamples: Number,
- clockSyncFrequency: Number,
- deploymentMode: {type: String, enum: ['PRIVATE', 'ISOLATED', 'SHARED', 'CONTINUOUS']},
- discoveryStartupDelay: Number,
- igfsThreadPoolSize: Number,
- igfss: [{type: ObjectId, ref: 'Igfs'}],
- includeEventTypes: [String],
- managementThreadPoolSize: Number,
- marshaller: {
- kind: {type: String, enum: ['OptimizedMarshaller', 'JdkMarshaller']},
- OptimizedMarshaller: {
- poolSize: Number,
- requireSerializable: Boolean
- }
- },
- marshalLocalJobs: Boolean,
- marshallerCacheKeepAliveTime: Number,
- marshallerCacheThreadPoolSize: Number,
- metricsExpireTime: Number,
- metricsHistorySize: Number,
- metricsLogFrequency: Number,
- metricsUpdateFrequency: Number,
- networkTimeout: Number,
- networkSendRetryDelay: Number,
- networkSendRetryCount: Number,
- communication: {
- listener: String,
- localAddress: String,
- localPort: Number,
- localPortRange: Number,
- sharedMemoryPort: Number,
- directBuffer: Boolean,
- directSendBuffer: Boolean,
- idleConnectionTimeout: Number,
- connectTimeout: Number,
- maxConnectTimeout: Number,
- reconnectCount: Number,
- socketSendBuffer: Number,
- socketReceiveBuffer: Number,
- messageQueueLimit: Number,
- slowClientQueueLimit: Number,
- tcpNoDelay: Boolean,
- ackSendThreshold: Number,
- unacknowledgedMessagesBufferSize: Number,
- socketWriteTimeout: Number,
- selectorsCount: Number,
- addressResolver: String
- },
- connector: {
- enabled: Boolean,
- jettyPath: String,
- host: String,
- port: Number,
- portRange: Number,
- idleTimeout: Number,
- idleQueryCursorTimeout: Number,
- idleQueryCursorCheckFrequency: Number,
- receiveBufferSize: Number,
- sendBufferSize: Number,
- directBuffer: Boolean,
- noDelay: Boolean,
- selectorCount: Number,
- threadPoolSize: Number,
- messageInterceptor: String,
- secretKey: String,
- sslEnabled: Boolean,
- sslClientAuth: Boolean,
- sslFactory: String
- },
- peerClassLoadingEnabled: Boolean,
- peerClassLoadingLocalClassPathExclude: [String],
- peerClassLoadingMissedResourcesCacheSize: Number,
- peerClassLoadingThreadPoolSize: Number,
- publicThreadPoolSize: Number,
- swapSpaceSpi: {
- kind: {type: String, enum: ['FileSwapSpaceSpi']},
- FileSwapSpaceSpi: {
- baseDirectory: String,
- readStripesNumber: Number,
- maximumSparsity: Number,
- maxWriteQueueSize: Number,
- writeBufferSize: Number
- }
- },
- systemThreadPoolSize: Number,
- timeServerPortBase: Number,
- timeServerPortRange: Number,
- transactionConfiguration: {
- defaultTxConcurrency: {type: String, enum: ['OPTIMISTIC', 'PESSIMISTIC']},
- defaultTxIsolation: {type: String, enum: ['READ_COMMITTED', 'REPEATABLE_READ', 'SERIALIZABLE']},
- defaultTxTimeout: Number,
- pessimisticTxLogLinger: Number,
- pessimisticTxLogSize: Number,
- txSerializableEnabled: Boolean,
- txManagerFactory: String
- },
- sslEnabled: Boolean,
- sslContextFactory: {
- keyAlgorithm: String,
- keyStoreFilePath: String,
- keyStoreType: String,
- protocol: String,
- trustStoreFilePath: String,
- trustStoreType: String,
- trustManagers: [String]
- },
- rebalanceThreadPoolSize: Number
-});
-
-// Install deep populate plugin.
-ClusterSchema.plugin(deepPopulate, {
- whitelist: [
- 'caches',
- 'caches.domains',
- 'igfss'
- ]
-});
-
-// Define Cluster model.
-exports.Cluster = mongoose.model('Cluster', ClusterSchema);
-
-exports.ClusterDefaultPopulate = '';
-
-// Define Notebook schema.
-var NotebookSchema = new Schema({
- space: {type: ObjectId, ref: 'Space'},
- name: String,
- expandedParagraphs: [Number],
- paragraphs: [{
- name: String,
- query: String,
- editor: Boolean,
- result: {type: String, enum: ['none', 'table', 'bar', 'pie', 'line', 'area']},
- pageSize: Number,
- timeLineSpan: String,
- hideSystemColumns: Boolean,
- cacheName: String,
- chartsOptions: {barChart: {stacked: Boolean}, areaChart: {style: String}},
- rate: {
- value: Number,
- unit: Number
- }
- }]
-});
-
-// Define Notebook model.
-exports.Notebook = mongoose.model('Notebook', NotebookSchema);
-
-exports.upsert = function (model, data, cb) {
- if (data._id) {
- var id = data._id;
-
- delete data._id;
-
- model.findOneAndUpdate({_id: id}, data, cb);
- }
- else
- new model(data).save(cb);
-};
-
-exports.processed = function(err, res) {
- if (err) {
- res.status(500).send(err);
-
- return false;
- }
-
- return true;
-};
-
-config.findIgniteModules()
- .filter(function(path) { return path.match(/.+\/db\.js$/); })
- .forEach(function(db) {
- var moduleExports = require(db)(mongoose, exports);
-
- for (var name in moduleExports)
- exports[name] = moduleExports[name];
- });
-
-exports.mongoose = mongoose;
http://git-wip-us.apache.org/repos/asf/ignite/blob/721a1165/modules/control-center-web/src/main/js/helpers/configuration-loader.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/helpers/configuration-loader.js b/modules/control-center-web/src/main/js/helpers/configuration-loader.js
deleted file mode 100644
index 5342cc3..0000000
--- a/modules/control-center-web/src/main/js/helpers/configuration-loader.js
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-var config = require('nconf');
-
-config.file({'file': 'config/default.json'});
-
-/**
- * Normalize a port into a number, string, or false.
- */
-config.normalizePort = function (val) {
- var port = parseInt(val, 10);
-
- if (isNaN(port)) {
- // named pipe
- return val;
- }
-
- if (port >= 0) {
- // port number
- return port;
- }
-
- return false;
-};
-
-config.findIgniteModules = function () {
- var fs = require('fs');
- var path = require('path');
-
- var igniteModules = process.env.IGNITE_MODULES || path.resolve(__dirname, 'ignite_modules');
-
- function _find (root, filter, files, prefix) {
- prefix = prefix || '';
- files = files || [];
-
- var dir = path.join(root, prefix);
-
- if (!fs.existsSync(dir))
- return files;
-
- if (fs.statSync(dir).isDirectory())
- fs.readdirSync(dir)
- .filter(function (name) { return name[0] !== '.' })
- .forEach(function (name) {
- _find(root, filter, files, path.join(prefix, name))
- });
- else
- files.push(path.join(igniteModules, prefix).replace(/\\/g, '/')); // Replace backslashes to work under Windows
-
- return files;
- }
-
- return _find(igniteModules);
-};
-
-config.address = function (username, email) {
- return username ? '"' + username + '" <' + email + '>' : email;
-};
-
-module.exports = config;
http://git-wip-us.apache.org/repos/asf/ignite/blob/721a1165/modules/control-center-web/src/main/js/keys/test.crt
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/keys/test.crt b/modules/control-center-web/src/main/js/keys/test.crt
deleted file mode 100644
index 50c6d5c..0000000
--- a/modules/control-center-web/src/main/js/keys/test.crt
+++ /dev/null
@@ -1,13 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIB6zCCAVQCCQDcAphbU6UcLjANBgkqhkiG9w0BAQsFADA6MRIwEAYDVQQDDAls
-b2NhbGhvc3QxJDAiBgkqhkiG9w0BCQEWFXNldmRva2ltb3ZAYXBhY2hlLm9yZzAe
-Fw0xNTA3MTQxMzAyNTNaFw0xODA2MjMxMzAyNTNaMDoxEjAQBgNVBAMMCWxvY2Fs
-aG9zdDEkMCIGCSqGSIb3DQEJARYVc2V2ZG9raW1vdkBhcGFjaGUub3JnMIGfMA0G
-CSqGSIb3DQEBAQUAA4GNADCBiQKBgQDP/zpJrdHqCj6lPpeFF6LQtzKef6UiyBBo
-rbuOtCCgW8KMJJciluBWk2126qLt9smBN4jBpSNU3pq0r9gBMUTd/LSe7aY4D5ED
-Pjp7XsypNVKeHaHbFi7KhfHy0LYxsWiNPmmHJv4dtYOp+pGK25rkXNfyJxxjgxN6
-wo34+MnZIQIDAQABMA0GCSqGSIb3DQEBCwUAA4GBAFk9XEjcdyihws+fVmdGGUFo
-bVxI9YGH6agiNbU3WNF4B4VRzcPPW8z2mEo7eF9kgYmq/YzH4T8tgi/qkL/u8eZV
-Wmi9bg6RThLN6/hj3wVoOFKykbDQ05FFdhIJXN5UOjPmxYM97EKqg6J0W2HAb8SG
-+UekPnmAo/2HTKsLykH8
------END CERTIFICATE-----
http://git-wip-us.apache.org/repos/asf/ignite/blob/721a1165/modules/control-center-web/src/main/js/keys/test.key
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/keys/test.key b/modules/control-center-web/src/main/js/keys/test.key
deleted file mode 100644
index 1b395c0..0000000
--- a/modules/control-center-web/src/main/js/keys/test.key
+++ /dev/null
@@ -1,18 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-Proc-Type: 4,ENCRYPTED
-DEK-Info: DES-EDE3-CBC,6798185330CE2EE2
-
-sOwkmD8rvjx11l09V26dJhLhl+SyPIhyeZ3TqHXrYCATKoXlzidT+uPu1jVYtrwr
-nBLA6TrIDYRrBNlEsqGZ0cSvWTIczzVW1xZKHEJo5q2vUT/W8u/Q1QQtS3P3GeKF
-dEzx496rpZqwwVw59GNbuIwyYoVvQf3iEXzfhplGmLPELYIplDFOLgNuXQyXSGx6
-rwKsCxXMLsDyrA6DCz0Odf08p2HvWk/s5Ne3DFcQlqRNtIrBVGD2O0/Fp8ZZ2I4E
-Yn2OIIWJff3HanOjLOWKdN8YAn5UleNmlEUdIHeS5qaQ68mabOxLkSef9qglV+sd
-FHTtUq0cG6t6nhxZBziexha6v1yl/xABAHHhNPOfak+HthWxRD4N9f1yFYAeTmkn
-4kwBWoSUe12XRf2pGNqhEUKN/KhDmWk85wI55i/Cu2XmNoiBFlS9BXrRYU8uVCJw
-KlxjKTDWl1opCyvxTDxJnMkt44ZT445LRePKVueGIIKSUIXNQypOE+C1I0CL0N2W
-Ts3m9nthquvLeMx92k7b8yW69BER5uac3SIlGCOJObQXsHgyk8wYiyd/zLKfjctG
-PXieaW81UKjp+GqWpvWPz3VqnKwoyUWeVOOTviurli6kYOrHuySTMqMb6hxJctw9
-grAQTT0UPiAKWcM7InLzZnRjco+v9QLLEokjVngXPba16K/CItFY16xuGlaFLW7Y
-XTc67AkL8b76HBZelMjmCsqjvSoULhuMFwTOvUMm/mSM8rMoi9asrJRLQHRMWCST
-/6RENPLzPlOMnNLBujpBbn8V3/aYzEZsHMI+6S3d27WYlTJIqpabSA==
------END RSA PRIVATE KEY-----
http://git-wip-us.apache.org/repos/asf/ignite/blob/721a1165/modules/control-center-web/src/main/js/routes/admin.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/routes/admin.js b/modules/control-center-web/src/main/js/routes/admin.js
deleted file mode 100644
index 8c02507..0000000
--- a/modules/control-center-web/src/main/js/routes/admin.js
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-var _ = require('lodash');
-var router = require('express').Router();
-var nodemailer = require('nodemailer');
-
-var db = require('../db');
-var config = require('../helpers/configuration-loader.js');
-
-/**
- * Get list of user accounts.
- */
-router.post('/list', function (req, res) {
- db.Account.find({}).sort('username').exec(function (err, users) {
- if (err)
- return res.status(500).send(err.message);
-
- res.json(users);
- });
-});
-
-// Remove user.
-router.post('/remove', function (req, res) {
- var userId = req.body.userId;
-
- db.Account.findByIdAndRemove(userId, function (err, user) {
- if (err)
- return res.status(500).send(err.message);
-
- db.Space.find({owner: userId}, function(err, spaces) {
- _.forEach(spaces, function (space) {
- db.Cluster.remove({space: space._id}).exec();
- db.Cache.remove({space: space._id}).exec();
- db.DomainModel.remove({space: space._id}).exec();
- db.Notebook.remove({space: space._id}).exec();
- db.Space.remove({owner: space._id}).exec();
- });
- });
-
- var transporter = {
- service: config.get('smtp:service'),
- auth: {
- user:config.get('smtp:email'),
- pass: config.get('smtp:password')
- }
- };
-
- if (transporter.service != '' || transporter.auth.user != '' || transporter.auth.pass != '') {
- var mailer = nodemailer.createTransport(transporter);
-
- var mailOptions = {
- from: config.address(config.get('smtp:username'), config.get('smtp:email')),
- to: config.address(user.username, user.email),
- subject: 'Your account was deleted',
- text: 'You are receiving this e-mail because admin remove your account.\n\n' +
- '--------------\n' +
- 'Apache Ignite Web Console http://' + req.headers.host + '\n'
- };
-
- mailer.sendMail(mailOptions, function(err){
- if (err)
- return res.status(503).send('Account was removed, but failed to send e-mail notification to user!<br />' + err);
-
- res.sendStatus(200);
- });
- }
- else
- res.sendStatus(200);
- });
-});
-
-// Save user.
-router.post('/save', function (req, res) {
- var userId = req.body.userId;
- var adminFlag = req.body.adminFlag;
-
- db.Account.findByIdAndUpdate(userId, {admin: adminFlag}, function (err) {
- if (err)
- return res.status(500).send(err.message);
-
- res.sendStatus(200);
- });
-});
-
-// Become user.
-router.get('/become', function (req, res) {
- db.Account.findById(req.query.viewedUserId).exec(function (err, viewedUser) {
- if (err)
- return res.sendStatus(404);
-
- req.session.viewedUser = viewedUser;
-
- return res.sendStatus(200);
- })
-});
-
-// Become user.
-router.get('/revert/identity', function (req, res) {
- req.session.viewedUser = null;
-
- return res.sendStatus(200);
-});
-
-module.exports = router;
http://git-wip-us.apache.org/repos/asf/ignite/blob/721a1165/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
deleted file mode 100644
index 8c2326c..0000000
--- a/modules/control-center-web/src/main/js/routes/agent.js
+++ /dev/null
@@ -1,298 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-var _ = require('lodash');
-var 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(userId) {
- return new Promise(function(resolve, reject) {
- var client = agentManager.getAgentManager().findClient(userId);
-
- if (client)
- return resolve(client);
-
- reject({code: 503, message: 'Connection to Ignite Web Agent is not established'});
- });
-}
-
-function _compact(className) {
- return className.replace('java.lang.', '').replace('java.util.', '').replace('java.sql.', '');
-}
-
-function _handleException(res) {
- return function (error) {
- if (_.isObject(error))
- return res.status(error.code).send(error.message);
-
- return res.status(500).send(error);
- }
-}
-
-/* Get grid topology. */
-router.get('/download/zip', function (req, res) {
- var fs = require('fs');
- var JSZip = require('jszip');
- var config = require('../helpers/configuration-loader.js');
-
- var agentFld = 'ignite-web-agent-1.5.0.final';
- var agentZip = agentFld + '.zip';
- var agentPathZip = 'public/agent/' + agentFld + '.zip';
-
- fs.stat(agentPathZip, function(err, stats) {
- if (err)
- return res.download(agentPathZip, agentZip);
-
- // Read a zip file.
- fs.readFile(agentPathZip, function(err, data) {
- if (err)
- return res.download(agentPathZip, agentZip);
-
- var zip = new JSZip(data);
-
- var prop = [];
-
- var host = req.hostname.match(/:/g) ? req.hostname.slice(0, req.hostname.indexOf(':')) : req.hostname;
-
- prop.push('token=' + req.user.token);
- prop.push('server-uri=wss://' + host + ':' + config.get('agent-server:port'));
- prop.push('#Uncomment following options if needed:');
- prop.push('#node-uri=http://localhost:8080');
- prop.push('#driver-folder=./jdbc-drivers');
- prop.push('');
- prop.push("#Note: Don't change this auto generated line");
- prop.push('rel-date=' + stats.birthtime.getTime());
-
- zip.file(agentFld + '/default.properties', prop.join('\n'));
-
- var buffer = zip.generate({type: 'nodebuffer', platform: 'UNIX'});
-
- // Set the archive name.
- res.attachment(agentZip);
-
- res.send(buffer);
- });
- });
-});
-
-/* Get grid topology. */
-router.post('/topology', function (req, res) {
- _client(req.currentUserId())
- .then((client) => client.ignite(req.body.demo).cluster(req.body.attr, req.body.mtr))
- .then((clusters) => res.json(clusters))
- .catch(_handleException(res));
-});
-
-/* Execute query. */
-router.post('/query', function (req, res) {
- _client(req.currentUserId())
- .then((client) => {
- // Create sql query.
- var qry = new SqlFieldsQuery(req.body.query);
-
- // Set page size for query.
- qry.setPageSize(req.body.pageSize);
-
- return client.ignite(req.body.demo).cache(req.body.cacheName).query(qry).nextPage()
- })
- .then((cursor) => res.json({meta: cursor.fieldsMetadata(), rows: cursor.page(), queryId: cursor.queryId()}))
- .catch(_handleException(res));
-});
-
-/* Execute query getAll. */
-router.post('/query/getAll', function (req, res) {
- _client(req.currentUserId())
- .then((client) => {
- // Create sql query.
- const qry = req.body.query ? new SqlFieldsQuery(req.body.query) : new ScanQuery();
-
- // Set page size for query.
- qry.setPageSize(1024);
-
- // Get query cursor.
- const cursor = client.ignite(req.body.demo).cache(req.body.cacheName).query(qry);
-
- return new Promise(function (resolve) {
- cursor.getAll().then(rows => resolve({meta: cursor.fieldsMetadata(), rows}))
- });
- })
- .then(response => res.json(response))
- .catch(_handleException(res));
-});
-
-/* Execute query. */
-router.post('/scan', function (req, res) {
- _client(req.currentUserId())
- .then((client) => {
- // Create sql query.
- var qry = new ScanQuery();
-
- // Set page size for query.
- qry.setPageSize(req.body.pageSize);
-
- // Get query cursor.
- return client.ignite(req.body.demo).cache(req.body.cacheName).query(qry).nextPage()
- })
- .then((cursor) => res.json({meta: cursor.fieldsMetadata(), rows: cursor.page(), queryId: cursor.queryId()}))
- .catch(_handleException(res));
-});
-
-/* Get next query page. */
-router.post('/query/fetch', function (req, res) {
- _client(req.currentUserId())
- .then((client) => {
- var cache = client.ignite(req.body.demo).cache(req.body.cacheName);
-
- var cmd = cache._createCommand('qryfetch')
- .addParam('qryId', req.body.queryId)
- .addParam('pageSize', req.body.pageSize);
-
- return cache.__createPromise(cmd);
- })
- .then((page) => res.json({rows: page['items'], last: page === null || page['last']}))
- .catch(_handleException(res));
-});
-
-/* Close query cursor by id. */
-router.post('/query/close', function (req, res) {
- _client(req.currentUserId())
- .then((client) => {
- var cache = client.ignite(req.body.demo).cache(req.body.cacheName);
-
- return cache.__createPromise(cache._createCommand('qrycls').addParam('qryId', req.body.queryId))
- })
- .then(() => res.sendStatus(200))
- .catch(_handleException(res));
-});
-
-/* Get metadata for cache. */
-router.post('/cache/metadata', function (req, res) {
- _client(req.currentUserId())
- .then((client) => client.ignite(req.body.demo).cache(req.body.cacheName).metadata())
- .then((caches) => {
- var types = [];
-
- for (var meta of caches) {
- var cacheTypes = meta.types.map(function (typeName) {
- var fields = meta.fields[typeName];
-
- var columns = [];
-
- for (var fieldName in fields) {
- var fieldClass = _compact(fields[fieldName]);
-
- columns.push({
- type: 'field',
- name: fieldName,
- clazz: fieldClass,
- system: fieldName == "_KEY" || fieldName == "_VAL",
- cacheName: meta.cacheName,
- typeName: typeName
- });
- }
-
- var indexes = [];
-
- for (var index of meta.indexes[typeName]) {
- fields = [];
-
- for (var field of index.fields) {
- fields.push({
- type: 'index-field',
- name: field,
- order: index.descendings.indexOf(field) < 0,
- unique: index.unique,
- cacheName: meta.cacheName,
- typeName: typeName
- });
- }
-
- if (fields.length > 0)
- indexes.push({
- type: 'index',
- name: index.name,
- children: fields,
- cacheName: meta.cacheName,
- typeName: typeName
- });
- }
-
- columns = _.sortBy(columns, 'name');
-
- if (!_.isEmpty(indexes))
- columns = columns.concat({type: 'indexes', name: 'Indexes', cacheName: meta.cacheName, typeName: typeName, children: indexes });
-
- return {type: 'type', cacheName: meta.cacheName || "", typeName: typeName, children: columns };
- });
-
- if (!_.isEmpty(cacheTypes))
- types = types.concat(cacheTypes);
- }
-
- res.json(types);
- })
- .catch(_handleException(res));
-});
-
-/* Ping client. */
-router.post('/ping', function (req, res) {
- _client(req.currentUserId())
- .then(() => res.sendStatus(200))
- .catch(_handleException(res));
-});
-
-/* Get JDBC drivers list. */
-router.post('/drivers', function (req, res) {
- _client(req.currentUserId())
- .then((client) => client.availableDrivers())
- .then((arr) => res.json(arr))
- .catch(_handleException(res));
-});
-
-/** Get database schemas. */
-router.post('/schemas', function (req, res) {
- _client(req.currentUserId())
- .then((client) => {
- var args = req.body;
-
- args.jdbcInfo = {user: args.user, password: args.password};
-
- return client.metadataSchemas(args.jdbcDriverJar, args.jdbcDriverClass, args.jdbcUrl, args.jdbcInfo)
- })
- .then((arr) => res.json(arr))
- .catch(_handleException(res));
-});
-
-/** Get database tables. */
-router.post('/tables', function (req, res) {
- _client(req.currentUserId())
- .then((client) => {
- var args = req.body;
-
- args.jdbcInfo = {user: args.user, password: args.password};
-
- return client.metadataTables(args.jdbcDriverJar, args.jdbcDriverClass, args.jdbcUrl, args.jdbcInfo, args.schemas, args.tablesOnly)
- })
- .then((arr) => res.json(arr))
- .catch(_handleException(res));
-});
-
-module.exports = router;
http://git-wip-us.apache.org/repos/asf/ignite/blob/721a1165/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
deleted file mode 100644
index 0fda48e..0000000
--- a/modules/control-center-web/src/main/js/routes/caches.js
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-var _ = require('lodash');
-var router = require('express').Router();
-var db = require('../db');
-
-/**
- * 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 caches').sort('name').exec(function (err, clusters) {
- if (db.processed(err, res)) {
- // Get all domain models for spaces.
- db.DomainModel.find({space: {$in: space_ids}}).sort('name').exec(function (err, domains) {
- 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(clusters, function (cluster) {
- cluster.caches = _.filter(cluster.caches, function (cacheId) {
- return _.find(caches, {_id: cacheId});
- });
- });
-
- _.forEach(domains, function (domain) {
- domain.caches = _.filter(domain.caches, function (cacheId) {
- return _.find(caches, {_id: cacheId});
- });
- });
-
- _.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 domain models.
- cache.domains = _.filter(cache.domains, function (metaId) {
- return _.findIndex(domains, function (domain) {
- return domain._id.equals(metaId);
- }) >= 0;
- });
- });
-
- res.json({
- spaces: spaces,
- clusters: clusters.map(function (cluster) {
- return {value: cluster._id, label: cluster.name, caches: cluster.caches};
- }),
- domains: domains,
- caches: caches
- });
- }
- });
- }
- });
- }
- });
- }
- });
-});
-
-/**
- * Save cache.
- */
-router.post('/save', function (req, res) {
- var params = req.body;
- var cacheId = params._id;
- var clusters = params.clusters;
- var domains = params.domains;
-
- 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.DomainModel.update({_id: {$in: domains}}, {$addToSet: {caches: cacheId}}, {multi: true}, function (err) {
- if (db.processed(err, res))
- db.DomainModel.update({_id: {$nin: domains}}, {$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.DomainModel.update({_id: {$in: domains}}, {$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);
-
- db.Cluster.update({space: {$in: space_ids}}, {caches: []}, {multi: true}, function (err) {
- if (db.processed(err, res))
- db.DomainModel.update({space: {$in: space_ids}}, {caches: []}, {multi: true}, function (err) {
- if (db.processed(err, res))
- res.sendStatus(200);
- });
- });
- })
- }
- });
-});
-
-module.exports = router;
http://git-wip-us.apache.org/repos/asf/ignite/blob/721a1165/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
deleted file mode 100644
index b29af37..0000000
--- a/modules/control-center-web/src/main/js/routes/clusters.js
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-var _ = require('lodash');
-var router = require('express').Router();
-var db = require('../db');
-
-/**
- * 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('domains').exec(function (err, caches) {
- if (db.processed(err, res)) {
- // Get all IGFSs for spaces.
- db.Igfs.find({space: {$in: space_ids}}).sort('name').exec(function (err, igfss) {
- if (db.processed(err, res))
- // Get all clusters for spaces.
- db.Cluster.find({space: {$in: space_ids}}).sort('name').deepPopulate(db.ClusterDefaultPopulate).exec(function (err, clusters) {
- if (db.processed(err, res)) {
- _.forEach(caches, function (cache) {
- // Remove deleted caches.
- cache.clusters = _.filter(cache.clusters, function (clusterId) {
- return _.find(clusters, {_id: clusterId});
- });
- });
-
- _.forEach(igfss, function (igfs) {
- // Remove deleted caches.
- igfs.clusters = _.filter(igfs.clusters, function (clusterId) {
- return _.find(clusters, {_id: clusterId});
- });
- });
-
- _.forEach(clusters, function (cluster) {
- // Remove deleted caches.
- cluster.caches = _.filter(cluster.caches, function (cacheId) {
- return _.find(caches, {_id: cacheId});
- });
-
- // Remove deleted IGFS.
- cluster.igfss = _.filter(cluster.igfss, function (igfsId) {
- return _.findIndex(igfss, function (igfs) {
- return igfs._id.equals(igfsId);
- }) >= 0;
- });
- });
-
- res.json({spaces: spaces, caches: caches, igfss: igfss, 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);
-
- db.Cache.update({space: {$in: space_ids}}, {clusters: []}, {multi: true}, function (err) {
- if (db.processed(err, res))
- db.Igfs.update({space: {$in: space_ids}}, {clusters: []}, {multi: true}, function (err) {
- if (db.processed(err, res))
- res.sendStatus(200);
- });
- });
- })
- }
- });
-});
-
-module.exports = router;
http://git-wip-us.apache.org/repos/asf/ignite/blob/721a1165/modules/control-center-web/src/main/js/routes/domains.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/routes/domains.js b/modules/control-center-web/src/main/js/routes/domains.js
deleted file mode 100644
index 302cb59..0000000
--- a/modules/control-center-web/src/main/js/routes/domains.js
+++ /dev/null
@@ -1,277 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-var async = require('async');
-var _ = require('lodash');
-var router = require('express').Router();
-var db = require('../db');
-
-/**
- * Get spaces and domain models 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 for spaces.
- db.Cache.find({space: {$in: space_ids}}).sort('name').exec(function (err, caches) {
- if (db.processed(err, res)) {
- // Get all domain models for spaces.
- db.DomainModel.find({space: {$in: space_ids}}).sort('valueType').exec(function (err, domains) {
- if (db.processed(err, res)) {
- _.forEach(caches, function (cache) {
- cache.domains = _.filter(cache.domains, function (metaId) {
- return _.find(domains, {_id: metaId});
- });
- });
-
- // Remove deleted caches.
- _.forEach(domains, function (domain) {
- domain.caches = _.filter(domain.caches, function (cacheId) {
- return _.find(caches, {_id: cacheId});
- });
- });
-
- res.json({
- spaces: spaces,
- clusters: clusters.map(function (cluster) {
- return {value: cluster._id, label: cluster.name};
- }),
- caches: caches,
- domains: domains
- });
- }
- });
- }
- });
- }
- });
- }
- });
-});
-
-function _saveDomainModel(domain, savedDomains, callback) {
- var domainId = domain._id;
- var caches = domain.caches;
-
- var cacheStoreChanges = domain.cacheStoreChanges;
-
- if (domainId)
- db.DomainModel.update({_id: domain._id}, domain, {upsert: true}, function (err) {
- if (err)
- callback(err);
- else
- db.Cache.update({_id: {$in: caches}}, {$addToSet: {domains: domainId}}, {multi: true}, function (err) {
- if (err)
- callback(err);
- else
- db.Cache.update({_id: {$nin: caches}}, {$pull: {domains: domainId}}, {multi: true}, function (err) {
- if (err)
- callback(err);
- else {
- savedDomains.push(domain);
-
- _updateCacheStore(cacheStoreChanges, callback);
- }
- });
- });
- });
- else
- db.DomainModel.findOne({space: domain.space, valueType: domain.valueType}, function (err, found) {
- if (err)
- callback(err);
- else if (found)
- return callback('Domain model with value type: "' + found.valueType + '" already exist.');
-
- (new db.DomainModel(domain)).save(function (err, domain) {
- if (err)
- callback(err);
- else {
- domainId = domain._id;
-
- db.Cache.update({_id: {$in: caches}}, {$addToSet: {domains: domainId}}, {multi: true}, function (err) {
- if (err)
- callback(err);
- else {
- savedDomains.push(domain);
-
- _updateCacheStore(cacheStoreChanges, callback);
- }
- });
- }
- });
- });
-}
-
-function _updateCacheStore(cacheStoreChanges, callback) {
- if (cacheStoreChanges && cacheStoreChanges.length > 0) {
- async.forEachOf(cacheStoreChanges, function (change, idx, callback) {
- db.Cache.update({_id: {$eq: change.cacheId}}, change.change, {}, function (err) {
- if (err)
- callback(err);
- else
- callback();
- });
- }, callback);
- }
- else
- callback();
-}
-
-function _save(domains, res) {
- var savedDomains = [];
- var generatedCaches = [];
-
- if (domains && domains.length > 0)
- async.forEachOf(domains, function(domain, idx, callback) {
- if (domain.newCache) {
- db.Cache.findOne({space: domain.space, name: domain.newCache.name}, function (err, cache) {
- if (db.processed(err, res))
- if (cache) {
- // Cache already exists, just save domain model.
- domain.caches = [cache._id];
-
- _saveDomainModel(domain, savedDomains, callback);
- }
- else {
- // If cache not found, then create it and associate with domain model.
- var newCache = domain.newCache;
- newCache.space = domain.space;
-
- (new db.Cache(newCache)).save(function (err, cache) {
- var cacheId = cache._id;
-
- if (db.processed(err, res)) {
- db.Cluster.update({_id: {$in: cache.clusters}}, {$addToSet: {caches: cacheId}}, {multi: true}, function (err) {
- if (db.processed(err, res)) {
- domain.caches = [cacheId];
- generatedCaches.push(cache);
-
- _saveDomainModel(domain, savedDomains, callback);
- }
- });
- }
- });
- }
- });
- }
- else
- _saveDomainModel(domain, savedDomains, callback);
- }, function (err) {
- if (err)
- res.status(500).send(err.message);
- else
- res.send({ savedDomains: savedDomains, generatedCaches: generatedCaches });
- });
- else
- res.status(500).send('Nothing to save!');
-}
-
-/**
- * Save domain model.
- */
-router.post('/save', function (req, res) {
- _save([req.body], res);
-});
-
-/**
- * Batch save domain models.
- */
-router.post('/save/batch', function (req, res) {
- _save(req.body, res);
-});
-
-/**
- * Remove domain model by ._id.
- */
-router.post('/remove', function (req, res) {
- db.DomainModel.remove(req.body, function (err) {
- if (db.processed(err, res))
- res.sendStatus(200);
- })
-});
-
-/**
- * Remove all domain models.
- */
-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.DomainModel.remove({space: {$in: space_ids}}, function (err) {
- if (err)
- return res.status(500).send(err.message);
-
- db.Cache.update({space: {$in: space_ids}}, {domains: []}, {multi: true}, function (err) {
- if (db.processed(err, res))
- res.sendStatus(200);
- });
- })
- }
- });
-});
-
-/**
- * Remove all generated demo domain models and caches.
- */
-router.post('/remove/demo', 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;
- });
-
- // Remove all demo domain models.
- db.DomainModel.remove({$and: [{space: {$in: space_ids}}, {demo: true}]}, function (err) {
- if (err)
- return res.status(500).send(err.message);
-
- // Remove all demo caches.
- db.Cache.remove({$and: [{space: {$in: space_ids}}, {demo: true}]}, function (err) {
- if (err)
- return res.status(500).send(err.message);
-
- res.sendStatus(200);
- });
- });
- }
- });
-});
-
-
-module.exports = router;