http://git-wip-us.apache.org/repos/asf/ignite/blob/323e3870/modules/web-console/frontend/app/modules/agent/AgentManager.service.js ---------------------------------------------------------------------- diff --git a/modules/web-console/frontend/app/modules/agent/AgentManager.service.js b/modules/web-console/frontend/app/modules/agent/AgentManager.service.js new file mode 100644 index 0000000..3b39463 --- /dev/null +++ b/modules/web-console/frontend/app/modules/agent/AgentManager.service.js @@ -0,0 +1,529 @@ +/* + * 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. + */ + +import io from 'socket.io-client'; // eslint-disable-line no-unused-vars + +const maskNull = (val) => _.isNil(val) ? 'null' : val; + +const State = { + INIT: 'INIT', + AGENT_DISCONNECTED: 'AGENT_DISCONNECTED', + CLUSTER_DISCONNECTED: 'CLUSTER_DISCONNECTED', + CONNECTED: 'CONNECTED' +}; + +export default class IgniteAgentManager { + static $inject = ['$rootScope', '$q', 'igniteSocketFactory', 'AgentModal']; + + constructor($root, $q, socketFactory, AgentModal) { + this.$root = $root; + this.$q = $q; + this.socketFactory = socketFactory; + + /** + * @type {AgentModal} + */ + this.AgentModal = AgentModal; + + this.clusters = []; + + $root.$on('$stateChangeSuccess', _.bind(this.stopWatch, this)); + + /** + * Connection to backend. + * @type {Socket} + */ + this.socket = null; + + this.connectionState = State.INIT; + + /** + * Has agent with enabled demo mode. + * @type {boolean} + */ + this.hasDemo = false; + + this.clusters = []; + } + + connect() { + const self = this; + + if (_.nonNil(self.socket)) + return; + + self.socket = self.socketFactory(); + + const onDisconnect = () => { + self.connected = false; + }; + + self.socket.on('connect_error', onDisconnect); + self.socket.on('disconnect', onDisconnect); + + self.connected = null; + + try { + self.cluster = JSON.parse(localStorage.cluster); + + localStorage.removeItem('cluster'); + } + catch (ignore) { + // No-op. + } + + self.socket.on('agents:stat', ({count, hasDemo, clusters}) => { + self.hasDemo = hasDemo; + + const removed = _.differenceBy(self.clusters, clusters, 'id'); + + if (_.nonEmpty(removed)) { + _.pullAll(self.clusters, removed); + + if (self.cluster && _.find(removed, {id: self.cluster.id})) + self.cluster.disconnect = true; + } + + const added = _.differenceBy(clusters, self.clusters, 'id'); + + if (_.nonEmpty(added)) { + self.clusters.push(...added); + + if (_.isNil(self.cluster)) + self.cluster = _.head(added); + + if (self.cluster && _.find(added, {id: self.cluster.id})) + self.cluster.disconnect = false; + } + + if (count === 0) + self.connectionState = State.AGENT_DISCONNECTED; + else { + self.connectionState = self.$root.IgniteDemoMode || _.get(self.cluster, 'disconnect') === false ? + State.CONNECTED : State.CLUSTER_DISCONNECTED; + } + }); + } + + saveToStorage(cluster = this.cluster) { + try { + localStorage.cluster = JSON.stringify(cluster); + } catch (ignore) { + // No-op. + } + } + + /** + * @returns {Promise} + */ + awaitAgent() { + this.latchAwaitAgent = this.$q.defer(); + + this.offAwaitAgent = this.$root.$watch(() => this.connectionState, (state) => { + if (state === State.CONNECTED) { + this.offAwaitAgent(); + + this.latchAwaitAgent.resolve(); + } + }); + + return this.latchAwaitAgent.promise; + } + + /** + * @param {String} backText + * @param {String} [backState] + * @returns {Promise} + */ + startWatch(backText, backState) { + const self = this; + + self.backText = backText; + self.backState = backState; + + if (_.nonEmpty(self.clusters) && _.get(self.cluster, 'disconnect') === true) { + self.cluster = _.head(self.clusters); + + self.connectionState = State.CONNECTED; + } + + self.offStateWatch = this.$root.$watch(() => self.connectionState, (state) => { + switch (state) { + case State.AGENT_DISCONNECTED: + this.AgentModal.agentDisconnected(self.backText, self.backState); + + break; + + case State.CLUSTER_DISCONNECTED: + self.AgentModal.clusterDisconnected(self.backText, self.backState); + + break; + + case State.CONNECTED: + this.AgentModal.hide(); + + break; + + default: + // Connection to backend is not established yet. + } + }); + + return self.awaitAgent(); + } + + stopWatch() { + if (!_.isFunction(this.offStateWatch)) + return; + + this.offStateWatch(); + + this.AgentModal.hide(); + + if (this.latchAwaitAgent) { + this.offAwaitAgent(); + + this.latchAwaitAgent.reject('Agent watch stopped.'); + } + } + + /** + * + * @param {String} event + * @param {Object} [args] + * @returns {Promise} + * @private + */ + _emit(event, ...args) { + if (!this.socket) + return this.$q.reject('Failed to connect to server'); + + const latch = this.$q.defer(); + + const onDisconnect = () => { + this.socket.removeListener('disconnect', onDisconnect); + + latch.reject('Connection to server was closed'); + }; + + this.socket.on('disconnect', onDisconnect); + + args.push((err, res) => { + this.socket.removeListener('disconnect', onDisconnect); + + if (err) + latch.reject(err); + + latch.resolve(res); + }); + + this.socket.emit(event, ...args); + + return latch.promise; + } + + drivers() { + return this._emit('schemaImport:drivers'); + } + + /** + * @param {Object} driverPath + * @param {Object} driverClass + * @param {Object} url + * @param {Object} user + * @param {Object} password + * @returns {Promise} + */ + schemas({driverPath, driverClass, url, user, password}) { + const info = {user, password}; + + return this._emit('schemaImport:schemas', {driverPath, driverClass, url, info}); + } + + /** + * @param {Object} driverPath + * @param {Object} driverClass + * @param {Object} url + * @param {Object} user + * @param {Object} password + * @param {Object} schemas + * @param {Object} tablesOnly + * @returns {Promise} Promise on list of tables (see org.apache.ignite.schema.parser.DbTable java class) + */ + tables({driverPath, driverClass, url, user, password, schemas, tablesOnly}) { + const info = {user, password}; + + return this._emit('schemaImport:tables', {driverPath, driverClass, url, info, schemas, tablesOnly}); + } + + /** + * + * @param {String} event + * @param {Object} [args] + * @returns {Promise} + * @private + */ + _rest(event, ...args) { + return this._emit(event, _.get(this, 'cluster.id'), ...args); + } + + /** + * @param {Boolean} [attr] + * @param {Boolean} [mtr] + * @returns {Promise} + */ + topology(attr = false, mtr = false) { + return this._rest('node:rest', {cmd: 'top', attr, mtr}); + } + + /** + * @param {String} [cacheName] Cache name. + * @returns {Promise} + */ + metadata(cacheName) { + return this._rest('node:rest', {cmd: 'metadata', cacheName: maskNull(cacheName)}) + .then((caches) => { + let types = []; + + const _compact = (className) => { + return className.replace('java.lang.', '').replace('java.util.', '').replace('java.sql.', ''); + }; + + const _typeMapper = (meta, typeName) => { + const maskedName = _.isEmpty(meta.cacheName) ? '<default>' : meta.cacheName; + + let fields = meta.fields[typeName]; + + let columns = []; + + for (const fieldName in fields) { + if (fields.hasOwnProperty(fieldName)) { + const fieldClass = _compact(fields[fieldName]); + + columns.push({ + type: 'field', + name: fieldName, + clazz: fieldClass, + system: fieldName === '_KEY' || fieldName === '_VAL', + cacheName: meta.cacheName, + typeName, + maskedName + }); + } + } + + const indexes = []; + + for (const index of meta.indexes[typeName]) { + fields = []; + + for (const field of index.fields) { + fields.push({ + type: 'index-field', + name: field, + order: index.descendings.indexOf(field) < 0, + unique: index.unique, + cacheName: meta.cacheName, + typeName, + maskedName + }); + } + + if (fields.length > 0) { + indexes.push({ + type: 'index', + name: index.name, + children: fields, + cacheName: meta.cacheName, + typeName, + maskedName + }); + } + } + + columns = _.sortBy(columns, 'name'); + + if (!_.isEmpty(indexes)) { + columns = columns.concat({ + type: 'indexes', + name: 'Indexes', + cacheName: meta.cacheName, + typeName, + maskedName, + children: indexes + }); + } + + return { + type: 'type', + cacheName: meta.cacheName || '', + typeName, + maskedName, + children: columns + }; + }; + + for (const meta of caches) { + const cacheTypes = meta.types.map(_typeMapper.bind(null, meta)); + + if (!_.isEmpty(cacheTypes)) + types = types.concat(cacheTypes); + } + + return types; + }); + } + + /** + * @param {String} taskId + * @param {Array.<String>|String} nids + * @param {Array.<Object>} args + */ + visorTask(taskId, nids, ...args) { + args = _.map(args, (arg) => maskNull(arg)); + + nids = _.isArray(nids) ? nids.join(';') : maskNull(nids); + + return this._rest('node:visor', taskId, nids, ...args); + } + + /** + * @param {String} nid Node id. + * @param {String} cacheName Cache name. + * @param {String} [query] Query if null then scan query. + * @param {Boolean} nonCollocatedJoins Flag whether to execute non collocated joins. + * @param {Boolean} enforceJoinOrder Flag whether enforce join order is enabled. + * @param {Boolean} replicatedOnly Flag whether query contains only replicated tables. + * @param {Boolean} local Flag whether to execute query locally. + * @param {int} pageSz + * @returns {Promise} + */ + querySql(nid, cacheName, query, nonCollocatedJoins, enforceJoinOrder, replicatedOnly, local, pageSz) { + return this.visorTask('querySql', nid, cacheName, query, nonCollocatedJoins, enforceJoinOrder, replicatedOnly, local, pageSz) + .then(({error, result}) => { + if (_.isEmpty(error)) + return result; + + return Promise.reject(error); + }); + } + + /** + * @param {String} nid Node id. + * @param {int} queryId + * @param {int} pageSize + * @returns {Promise} + */ + queryNextPage(nid, queryId, pageSize) { + return this.visorTask('queryFetch', nid, queryId, pageSize); + } + + /** + * @param {String} nid Node id. + * @param {String} cacheName Cache name. + * @param {String} [query] Query if null then scan query. + * @param {Boolean} nonCollocatedJoins Flag whether to execute non collocated joins. + * @param {Boolean} enforceJoinOrder Flag whether enforce join order is enabled. + * @param {Boolean} replicatedOnly Flag whether query contains only replicated tables. + * @param {Boolean} local Flag whether to execute query locally. + * @returns {Promise} + */ + querySqlGetAll(nid, cacheName, query, nonCollocatedJoins, enforceJoinOrder, replicatedOnly, local) { + // Page size for query. + const pageSz = 1024; + + const fetchResult = (acc) => { + if (!acc.hasMore) + return acc; + + return this.queryNextPage(acc.responseNodeId, acc.queryId, pageSz) + .then((res) => { + acc.rows = acc.rows.concat(res.rows); + + acc.hasMore = res.hasMore; + + return fetchResult(acc); + }); + }; + + return this.querySql(nid, cacheName, query, nonCollocatedJoins, enforceJoinOrder, replicatedOnly, local, pageSz) + .then(fetchResult); + } + + /** + * @param {String} nid Node id. + * @param {int} [queryId] + * @returns {Promise} + */ + queryClose(nid, queryId) { + return this.visorTask('queryClose', nid, queryId); + } + + /** + * @param {String} nid Node id. + * @param {String} cacheName Cache name. + * @param {String} filter Filter text. + * @param {Boolean} regEx Flag whether filter by regexp. + * @param {Boolean} caseSensitive Case sensitive filtration. + * @param {Boolean} near Scan near cache. + * @param {Boolean} local Flag whether to execute query locally. + * @param {int} pageSize Page size. + * @returns {Promise} + */ + queryScan(nid, cacheName, filter, regEx, caseSensitive, near, local, pageSize) { + return this.visorTask('queryScan', nid, cacheName, filter, regEx, caseSensitive, near, local, pageSize) + .then(({error, result}) => { + if (_.isEmpty(error)) + return result; + + return Promise.reject(error); + }); + } + + /** + /** + * @param {String} nid Node id. + * @param {String} cacheName Cache name. + * @param {String} filter Filter text. + * @param {Boolean} regEx Flag whether filter by regexp. + * @param {Boolean} caseSensitive Case sensitive filtration. + * @param {Boolean} near Scan near cache. + * @param {Boolean} local Flag whether to execute query locally. + * @returns {Promise} + */ + queryScanGetAll(nid, cacheName, filter, regEx, caseSensitive, near, local) { + // Page size for query. + const pageSz = 1024; + + const fetchResult = (acc) => { + if (!acc.hasMore) + return acc; + + return this.queryNextPage(acc.responseNodeId, acc.queryId, pageSz) + .then((res) => { + acc.rows = acc.rows.concat(res.rows); + + acc.hasMore = res.hasMore; + + return fetchResult(acc); + }); + }; + + return this.queryScan(nid, cacheName, filter, regEx, caseSensitive, near, local, pageSz) + .then(fetchResult); + } +}
http://git-wip-us.apache.org/repos/asf/ignite/blob/323e3870/modules/web-console/frontend/app/modules/agent/AgentModal.service.js ---------------------------------------------------------------------- diff --git a/modules/web-console/frontend/app/modules/agent/AgentModal.service.js b/modules/web-console/frontend/app/modules/agent/AgentModal.service.js new file mode 100644 index 0000000..54f8e52 --- /dev/null +++ b/modules/web-console/frontend/app/modules/agent/AgentModal.service.js @@ -0,0 +1,89 @@ +/* + * 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. + */ + +import templateUrl from 'views/templates/agent-download.tpl.pug'; + +export default class AgentModal { + static $inject = ['$rootScope', '$state', '$modal', 'IgniteMessages']; + + constructor($root, $state, $modal, Messages) { + const self = this; + + self.$state = $state; + self.Messages = Messages; + + // Pre-fetch modal dialogs. + self.modal = $modal({ + templateUrl, + show: false, + backdrop: 'static', + keyboard: false, + controller: () => self, + controllerAs: 'ctrl' + }); + + self.modal.$scope.$on('modal.hide.before', () => { + Messages.hideAlert(); + }); + + $root.$on('user', (event, user) => self.user = user); + } + + hide() { + this.modal.hide(); + } + + /** + * Close dialog and go by specified link. + */ + back() { + this.hide(); + + if (this.backState) + this.$state.go(this.backState); + } + + /** + * @param {String} backState + * @param {String} [backText] + */ + agentDisconnected(backText, backState) { + const self = this; + + self.backText = backText; + self.backState = backState; + + self.status = 'agentMissing'; + + self.modal.$promise.then(self.modal.show); + } + + /** + * @param {String} backState + * @param {String} [backText] + */ + clusterDisconnected(backText, backState) { + const self = this; + + self.backText = backText; + self.backState = backState; + + self.status = 'nodeMissing'; + + self.modal.$promise.then(self.modal.show); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/323e3870/modules/web-console/frontend/app/modules/agent/agent.module.js ---------------------------------------------------------------------- diff --git a/modules/web-console/frontend/app/modules/agent/agent.module.js b/modules/web-console/frontend/app/modules/agent/agent.module.js index b20a5bc..63257c5 100644 --- a/modules/web-console/frontend/app/modules/agent/agent.module.js +++ b/modules/web-console/frontend/app/modules/agent/agent.module.js @@ -16,352 +16,13 @@ */ import angular from 'angular'; -import io from 'socket.io-client'; // eslint-disable-line no-unused-vars -import templateUrl from 'views/templates/agent-download.tpl.pug'; - -const maskNull = (val) => _.isEmpty(val) ? 'null' : val; - -class IgniteAgentMonitor { - constructor(socketFactory, $root, $q, $state, $modal, Messages) { - this._scope = $root.$new(); - - $root.$watch('user', () => { - this._scope.user = $root.user; - }); - - $root.$on('$stateChangeStart', () => { - this.stopWatch(); - }); - - // Pre-fetch modal dialogs. - this._downloadAgentModal = $modal({ - scope: this._scope, - templateUrl, - show: false, - backdrop: 'static', - keyboard: false - }); - - const _modalHide = this._downloadAgentModal.hide; - - /** - * Special dialog hide function. - */ - this._downloadAgentModal.hide = () => { - Messages.hideAlert(); - - _modalHide(); - }; - - /** - * Close dialog and go by specified link. - */ - this._scope.back = () => { - this.stopWatch(); - - if (this._scope.backState) - this._scope.$$postDigest(() => $state.go(this._scope.backState)); - }; - - this._scope.hasAgents = null; - this._scope.showModal = false; - - /** - * @type {Socket} - */ - this._socket = null; - - this._socketFactory = socketFactory; - - this._$q = $q; - - this.Messages = Messages; - } - - /** - * @private - */ - checkModal() { - if (this._scope.showModal && !this._scope.hasAgents) - this._downloadAgentModal.$promise.then(this._downloadAgentModal.show); - else if ((this._scope.hasAgents || !this._scope.showModal) && this._downloadAgentModal.$isShown) - this._downloadAgentModal.hide(); - } - - /** - * @returns {Promise} - */ - awaitAgent() { - if (this._scope.hasAgents) - return this._$q.when(); - - const latch = this._$q.defer(); - - const offConnected = this._scope.$on('agent:watch', (event, state) => { - if (state !== 'DISCONNECTED') - offConnected(); - - if (state === 'CONNECTED') - return latch.resolve(); - - if (state === 'STOPPED') - return latch.reject('Agent watch stopped.'); - }); - - return latch.promise; - } - - init() { - if (this._socket) - return; - - this._socket = this._socketFactory(); - - const disconnectFn = () => { - this._scope.hasAgents = false; - - this.checkModal(); - - this._scope.$broadcast('agent:watch', 'DISCONNECTED'); - }; - - this._socket.on('connect_error', disconnectFn); - this._socket.on('disconnect', disconnectFn); - - this._socket.on('agent:count', ({count}) => { - this._scope.hasAgents = count > 0; - - this.checkModal(); - - this._scope.$broadcast('agent:watch', this._scope.hasAgents ? 'CONNECTED' : 'DISCONNECTED'); - }); - } - - /** - * @param {Object} back - * @returns {Promise} - */ - startWatch(back) { - this._scope.backState = back.state; - this._scope.backText = back.text; - - this._scope.agentGoal = back.goal; - - if (back.onDisconnect) { - this._scope.offDisconnect = this._scope.$on('agent:watch', (e, state) => - state === 'DISCONNECTED' && back.onDisconnect()); - } - - this._scope.showModal = true; - - // Remove blinking on init. - if (this._scope.hasAgents !== null) - this.checkModal(); - - return this.awaitAgent(); - } - - /** - * - * @param {String} event - * @param {Object} [args] - * @returns {Promise} - * @private - */ - _emit(event, ...args) { - if (!this._socket) - return this._$q.reject('Failed to connect to server'); - - const latch = this._$q.defer(); - - const onDisconnect = () => { - this._socket.removeListener('disconnect', onDisconnect); - - latch.reject('Connection to server was closed'); - }; - - this._socket.on('disconnect', onDisconnect); - - args.push((err, res) => { - this._socket.removeListener('disconnect', onDisconnect); - - if (err) - latch.reject(err); - - latch.resolve(res); - }); - - this._socket.emit(event, ...args); - - return latch.promise; - } - - drivers() { - return this._emit('schemaImport:drivers'); - } - - /** - * - * @param {Object} preset - * @returns {Promise} - */ - schemas(preset) { - return this._emit('schemaImport:schemas', preset); - } - - /** - * - * @param {Object} preset - * @returns {Promise} - */ - tables(preset) { - return this._emit('schemaImport:tables', preset); - } - - /** - * @param {Object} err - */ - showNodeError(err) { - if (this._scope.showModal) { - this._downloadAgentModal.$promise.then(this._downloadAgentModal.show); - - this.Messages.showError(err); - } - } - - /** - * - * @param {String} event - * @param {Object} [args] - * @returns {Promise} - * @private - */ - _rest(event, ...args) { - return this._downloadAgentModal.$promise - .then(() => this._emit(event, ...args)); - } - - /** - * @param {Boolean} [attr] - * @param {Boolean} [mtr] - * @returns {Promise} - */ - topology(attr, mtr) { - return this._rest('node:topology', !!attr, !!mtr); - } - - /** - * @param {String} nid Node id. - * @param {int} [queryId] - * @returns {Promise} - */ - queryClose(nid, queryId) { - return this._rest('node:query:close', nid, queryId); - } - - /** - * @param {String} nid Node id. - * @param {String} cacheName Cache name. - * @param {String} [query] Query if null then scan query. - * @param {Boolean} nonCollocatedJoins Flag whether to execute non collocated joins. - * @param {Boolean} enforceJoinOrder Flag whether enforce join order is enabled. - * @param {Boolean} local Flag whether to execute query locally. - * @param {int} pageSize - * @returns {Promise} - */ - query(nid, cacheName, query, nonCollocatedJoins, enforceJoinOrder, local, pageSize) { - return this._rest('node:query', nid, maskNull(cacheName), maskNull(query), nonCollocatedJoins, enforceJoinOrder, local, pageSize) - .then(({result}) => { - if (_.isEmpty(result.error)) - return result.result; - - return Promise.reject(result.error); - }); - } - - /** - * @param {String} nid Node id. - * @param {String} cacheName Cache name. - * @param {String} [query] Query if null then scan query. - * @param {Boolean} nonCollocatedJoins Flag whether to execute non collocated joins. - * @param {Boolean} enforceJoinOrder Flag whether enforce join order is enabled. - * @param {Boolean} local Flag whether to execute query locally. - * @returns {Promise} - */ - queryGetAll(nid, cacheName, query, nonCollocatedJoins, enforceJoinOrder, local) { - return this._rest('node:query:getAll', nid, maskNull(cacheName), maskNull(query), nonCollocatedJoins, enforceJoinOrder, local); - } - - /** - * @param {String} nid Node id. - * @param {String} cacheName Cache name. - * @param {String} filter Optional filter for scan query. - * @param {Boolean} regEx Flag whether filter by regexp. - * @param {Boolean} caseSensitive Case sensitive filtration. - * @param {Boolean} near Scan near cache. - * @param {Boolean} local Flag whether to execute query locally. - * @param {int} pageSize - * @returns {Promise} - */ - scan(nid, cacheName, filter, regEx, caseSensitive, near, local, pageSize) { - return this._rest('node:scan', nid, maskNull(cacheName), maskNull(filter), regEx, caseSensitive, near, local, pageSize) - .then(({result}) => { - if (_.isEmpty(result.error)) - return result.result; - - return Promise.reject(result.error); - }); - } - - /** - * @param {String} nid Node id. - * @param {String} cacheName Cache name. - * @param {String} filter Optional filter for scan query. - * @param {Boolean} regEx Flag whether filter by regexp. - * @param {Boolean} caseSensitive Case sensitive filtration. - * @param {Boolean} near Scan near cache. - * @param {Boolean} local Flag whether to execute query locally. - * @returns {Promise} - */ - scanGetAll(nid, cacheName, filter, regEx, caseSensitive, near, local) { - return this._rest('node:scan:getAll', nid, maskNull(cacheName), maskNull(filter), regEx, caseSensitive, near, local); - } - - /** - * @param {String} nid Node id. - * @param {int} queryId - * @param {int} pageSize - * @returns {Promise} - */ - next(nid, queryId, pageSize) { - return this._rest('node:query:fetch', nid, queryId, pageSize) - .then(({result}) => result); - } - - /** - * @param {String} [cacheName] Cache name. - * @returns {Promise} - */ - metadata(cacheName) { - return this._rest('node:cache:metadata', maskNull(cacheName)); - } - - stopWatch() { - this._scope.showModal = false; - - this.checkModal(); - - this._scope.offDisconnect && this._scope.offDisconnect(); - - this._scope.$broadcast('agent:watch', 'STOPPED'); - } -} - -IgniteAgentMonitor.$inject = ['igniteSocketFactory', '$rootScope', '$q', '$state', '$modal', 'IgniteMessages']; +import AgentModal from './AgentModal.service'; +import AgentManager from './AgentManager.service'; angular .module('ignite-console.agent', [ ]) - .service('IgniteAgentMonitor', IgniteAgentMonitor); + .service('AgentModal', AgentModal) + .service('AgentManager', AgentManager); http://git-wip-us.apache.org/repos/asf/ignite/blob/323e3870/modules/web-console/frontend/app/modules/cluster/Cache.js ---------------------------------------------------------------------- diff --git a/modules/web-console/frontend/app/modules/cluster/Cache.js b/modules/web-console/frontend/app/modules/cluster/Cache.js new file mode 100644 index 0000000..5007900 --- /dev/null +++ b/modules/web-console/frontend/app/modules/cluster/Cache.js @@ -0,0 +1,51 @@ +/* + * Copyright (C) GridGain Systems. All Rights Reserved. + * _________ _____ __________________ _____ + * __ ____/___________(_)______ /__ ____/______ ____(_)_______ + * _ / __ __ ___/__ / _ __ / _ / __ _ __ `/__ / __ __ \ + * / /_/ / _ / _ / / /_/ / / /_/ / / /_/ / _ / _ / / / + * \____/ /_/ /_/ \_,__/ \____/ \__,_/ /_/ /_/ /_/ + */ + +export default class Cache { + constructor(cache) { + this.dynamicDeploymentId = cache.dynamicDeploymentId; + + // Name. + this.name = cache.name; + + // Mode. + this.mode = cache.mode; + + // Memory Usage. + this.memorySize = cache.memorySize; + + // Heap. + this.size = cache.size; + this.primarySize = cache.primarySize; + this.backupSize = cache.dhtSize - cache.primarySize; + this.nearSize = cache.nearSize; + + // Off-heap. + this.offHeapAllocatedSize = cache.offHeapAllocatedSize; + this.offHeapSize = cache.offHeapEntriesCount; + this.offHeapPrimarySize = cache.offHeapPrimaryEntriesCount || 0; + this.offHeapBackupSize = cache.offHeapBackupEntriesCount || 0; + + // Swap. + this.swapSize = cache.swapSize; + this.swapKeys = cache.swapKeys; + + const m = cache.metrics; + + // Read/write metrics. + this.hits = m.hits; + this.misses = m.misses; + this.reads = m.reads; + this.writes = m.writes; + + // Transaction metrics. + this.commits = m.txCommits; + this.rollbacks = m.txRollbacks; + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/323e3870/modules/web-console/frontend/app/modules/cluster/CacheMetrics.js ---------------------------------------------------------------------- diff --git a/modules/web-console/frontend/app/modules/cluster/CacheMetrics.js b/modules/web-console/frontend/app/modules/cluster/CacheMetrics.js new file mode 100644 index 0000000..ab1fd8c --- /dev/null +++ b/modules/web-console/frontend/app/modules/cluster/CacheMetrics.js @@ -0,0 +1,51 @@ +/* + * Copyright (C) GridGain Systems. All Rights Reserved. + * _________ _____ __________________ _____ + * __ ____/___________(_)______ /__ ____/______ ____(_)_______ + * _ / __ __ ___/__ / _ __ / _ / __ _ __ `/__ / __ __ \ + * / /_/ / _ / _ / / /_/ / / /_/ / / /_/ / _ / _ / / / + * \____/ /_/ /_/ \_,__/ \____/ \__,_/ /_/ /_/ /_/ + */ + +export default class CacheMetrics { + constructor(cache) { + this.dynamicDeploymentId = cache.dynamicDeploymentId; + + // Name. + this.name = cache.name; + + // Mode. + this.mode = cache.mode; + + // Memory Usage. + this.memorySize = cache.memorySize; + + // Heap. + this.size = cache.size; + this.primarySize = cache.primarySize; + this.backupSize = cache.dhtSize - cache.primarySize; + this.nearSize = cache.nearSize; + + // Off-heap. + this.offHeapAllocatedSize = cache.offHeapAllocatedSize; + this.offHeapSize = cache.offHeapEntriesCount; + this.offHeapPrimarySize = cache.offHeapPrimaryEntriesCount || 0; + this.offHeapBackupSize = cache.offHeapBackupEntriesCount || 0; + + // Swap. + this.swapSize = cache.swapSize; + this.swapKeys = cache.swapKeys; + + const m = cache.metrics; + + // Read/write metrics. + this.hits = m.hits; + this.misses = m.misses; + this.reads = m.reads; + this.writes = m.writes; + + // Transaction metrics. + this.commits = m.txCommits; + this.rollbacks = m.txRollbacks; + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/323e3870/modules/web-console/frontend/app/modules/cluster/Node.js ---------------------------------------------------------------------- diff --git a/modules/web-console/frontend/app/modules/cluster/Node.js b/modules/web-console/frontend/app/modules/cluster/Node.js new file mode 100644 index 0000000..dac7c70 --- /dev/null +++ b/modules/web-console/frontend/app/modules/cluster/Node.js @@ -0,0 +1,54 @@ +/* + * 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. + */ + +export default class Node { + constructor(node) { + this.nid = node.nodeId.toUpperCase(); + + this.jvmPid = node.attributes['org.apache.ignite.jvm.pid']; + this.macs = node.attributes['org.apache.ignite.macs']; + + this.ip = node.attributes['org.apache.ignite.ips'].split(',')[0]; + this.igniteVersion = node.attributes['org.apache.ignite.build.ver']; + this.version = node.attributes['plugins.gg.build.ver'] || this.igniteVersion; + // this.hostName = data.attributes[]; + this.clientMode = node.attributes['org.apache.ignite.cache.client'] ? 'CLIENT' : 'SERVER'; + this.gridName = node.attributes['org.apache.ignite.ignite.name']; + + this.startTime = node.metrics.startTime; + this.upTime = node.metrics.upTime; + + this.cpus = node.metrics.totalCpus; + + this.heapMemoryMaximum = parseInt(node.metrics.heapMemoryMaximum, 10); + this.heapMemoryUsed = parseInt(node.metrics.heapMemoryUsed, 10); + this.heapMemoryCommitted = parseInt(node.metrics.heapMemoryCommitted, 10); + + this.busy = parseFloat(node.metrics.busyTimePercentage); + + this.cpuLoad = parseFloat(node.metrics.currentCpuLoad); + this.gcLoad = parseFloat(node.metrics.currentGcCpuLoad); + + this.heapMemoryFreePercent = (this.heapMemoryMaximum - this.heapMemoryUsed) / this.heapMemoryMaximum; + + this.os = `${node.attributes['os.name']} ${node.attributes['os.arch']} ${node.attributes['os.version']}`; + } + + static from(node) { + return new Node(node); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/323e3870/modules/web-console/frontend/app/modules/cluster/NodeMetrics.js ---------------------------------------------------------------------- diff --git a/modules/web-console/frontend/app/modules/cluster/NodeMetrics.js b/modules/web-console/frontend/app/modules/cluster/NodeMetrics.js new file mode 100644 index 0000000..400d480 --- /dev/null +++ b/modules/web-console/frontend/app/modules/cluster/NodeMetrics.js @@ -0,0 +1,19 @@ +/* + * 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. + */ + +export default class NodeMetrics { +} http://git-wip-us.apache.org/repos/asf/ignite/blob/323e3870/modules/web-console/frontend/app/modules/demo/Demo.module.js ---------------------------------------------------------------------- diff --git a/modules/web-console/frontend/app/modules/demo/Demo.module.js b/modules/web-console/frontend/app/modules/demo/Demo.module.js index 740ab30..dc763b3 100644 --- a/modules/web-console/frontend/app/modules/demo/Demo.module.js +++ b/modules/web-console/frontend/app/modules/demo/Demo.module.js @@ -117,7 +117,7 @@ angular return items; }]; }]) -.service('DemoInfo', ['$rootScope', '$modal', '$state', '$q', 'igniteDemoInfo', 'IgniteAgentMonitor', ($rootScope, $modal, $state, $q, igniteDemoInfo, agentMonitor) => { +.service('DemoInfo', ['$rootScope', '$modal', '$state', '$q', 'igniteDemoInfo', 'AgentManager', ($rootScope, $modal, $state, $q, igniteDemoInfo, agentMonitor) => { const scope = $rootScope.$new(); let closePromise = null; @@ -132,7 +132,6 @@ angular const dialog = $modal({ templateUrl, scope, - placement: 'center', show: false, backdrop: 'static' }); @@ -146,7 +145,7 @@ angular scope.downloadAgent = () => { const lnk = document.createElement('a'); - lnk.setAttribute('href', '/api/v1/agent/download/zip'); + lnk.setAttribute('href', '/api/v1/agent/downloads/agent'); lnk.setAttribute('target', '_self'); lnk.setAttribute('download', null); lnk.style.display = 'none'; http://git-wip-us.apache.org/repos/asf/ignite/blob/323e3870/modules/web-console/frontend/app/modules/dialog/dialog.factory.js ---------------------------------------------------------------------- diff --git a/modules/web-console/frontend/app/modules/dialog/dialog.factory.js b/modules/web-console/frontend/app/modules/dialog/dialog.factory.js index 2ac8917..599433a 100644 --- a/modules/web-console/frontend/app/modules/dialog/dialog.factory.js +++ b/modules/web-console/frontend/app/modules/dialog/dialog.factory.js @@ -20,7 +20,6 @@ import templateUrl from './dialog.tpl.pug'; export default ['IgniteDialog', ['$modal', ($modal) => { const defaults = { templateUrl, - placement: 'center', show: false }; http://git-wip-us.apache.org/repos/asf/ignite/blob/323e3870/modules/web-console/frontend/app/modules/getting-started/GettingStarted.provider.js ---------------------------------------------------------------------- diff --git a/modules/web-console/frontend/app/modules/getting-started/GettingStarted.provider.js b/modules/web-console/frontend/app/modules/getting-started/GettingStarted.provider.js index f4c834c..2608bd2 100644 --- a/modules/web-console/frontend/app/modules/getting-started/GettingStarted.provider.js +++ b/modules/web-console/frontend/app/modules/getting-started/GettingStarted.provider.js @@ -78,7 +78,7 @@ angular _fillPage(); }; - const dialog = $modal({ templateUrl, scope, placement: 'center', show: false, backdrop: 'static'}); + const dialog = $modal({ templateUrl, scope, show: false, backdrop: 'static'}); scope.close = () => { try { http://git-wip-us.apache.org/repos/asf/ignite/blob/323e3870/modules/web-console/frontend/app/modules/navbar/userbar.directive.js ---------------------------------------------------------------------- diff --git a/modules/web-console/frontend/app/modules/navbar/userbar.directive.js b/modules/web-console/frontend/app/modules/navbar/userbar.directive.js index af70eb1..279314f 100644 --- a/modules/web-console/frontend/app/modules/navbar/userbar.directive.js +++ b/modules/web-console/frontend/app/modules/navbar/userbar.directive.js @@ -22,7 +22,7 @@ export default ['igniteUserbar', [function() { const ctrl = this; ctrl.items = [ - {text: 'Profile', sref: 'settings.profile'}, + {text: 'Profile', sref: 'base.settings.profile'}, {text: 'Getting started', click: 'gettingStarted.tryShow(true)'} ]; @@ -30,7 +30,7 @@ export default ['igniteUserbar', [function() { ctrl.items.splice(2); if (AclService.can('admin_page')) - ctrl.items.push({text: 'Admin panel', sref: 'settings.admin'}); + ctrl.items.push({text: 'Admin panel', sref: 'base.settings.admin'}); ctrl.items.push(...IgniteUserbar); http://git-wip-us.apache.org/repos/asf/ignite/blob/323e3870/modules/web-console/frontend/app/modules/nodes/Nodes.service.js ---------------------------------------------------------------------- diff --git a/modules/web-console/frontend/app/modules/nodes/Nodes.service.js b/modules/web-console/frontend/app/modules/nodes/Nodes.service.js index 4ca1d45..e231753 100644 --- a/modules/web-console/frontend/app/modules/nodes/Nodes.service.js +++ b/modules/web-console/frontend/app/modules/nodes/Nodes.service.js @@ -47,7 +47,6 @@ class Nodes { nodes: () => nodes || [], options: () => options }, - placement: 'center', controller: 'nodesDialogController', controllerAs: '$ctrl' }); http://git-wip-us.apache.org/repos/asf/ignite/blob/323e3870/modules/web-console/frontend/app/modules/sql/notebook.controller.js ---------------------------------------------------------------------- diff --git a/modules/web-console/frontend/app/modules/sql/notebook.controller.js b/modules/web-console/frontend/app/modules/sql/notebook.controller.js index 252dee6..68d318a 100644 --- a/modules/web-console/frontend/app/modules/sql/notebook.controller.js +++ b/modules/web-console/frontend/app/modules/sql/notebook.controller.js @@ -38,7 +38,7 @@ export default ['$scope', '$modal', '$state', 'IgniteMessages', 'IgniteNotebook' Notebook.read() .then((notebooks) => { scope.$watchCollection(() => notebooks, (changed) => { - if (!changed.length) + if (_.isEmpty(changed)) return scope.notebooks = []; scope.notebooks = [ http://git-wip-us.apache.org/repos/asf/ignite/blob/323e3870/modules/web-console/frontend/app/modules/sql/sql.controller.js ---------------------------------------------------------------------- diff --git a/modules/web-console/frontend/app/modules/sql/sql.controller.js b/modules/web-console/frontend/app/modules/sql/sql.controller.js index 11700dd..bb94b0c 100644 --- a/modules/web-console/frontend/app/modules/sql/sql.controller.js +++ b/modules/web-console/frontend/app/modules/sql/sql.controller.js @@ -210,8 +210,8 @@ class Paragraph { } // Controller for SQL notebook screen. -export default ['$rootScope', '$scope', '$http', '$q', '$timeout', '$interval', '$animate', '$location', '$anchorScroll', '$state', '$filter', '$modal', '$popover', 'IgniteLoading', 'IgniteLegacyUtils', 'IgniteMessages', 'IgniteConfirm', 'IgniteAgentMonitor', 'IgniteChartColors', 'IgniteNotebook', 'IgniteNodes', 'uiGridExporterConstants', 'IgniteVersion', 'IgniteActivitiesData', 'JavaTypes', - function($root, $scope, $http, $q, $timeout, $interval, $animate, $location, $anchorScroll, $state, $filter, $modal, $popover, Loading, LegacyUtils, Messages, Confirm, agentMonitor, IgniteChartColors, Notebook, Nodes, uiGridExporterConstants, Version, ActivitiesData, JavaTypes) { +export default ['$rootScope', '$scope', '$http', '$q', '$timeout', '$interval', '$animate', '$location', '$anchorScroll', '$state', '$filter', '$modal', '$popover', 'IgniteLoading', 'IgniteLegacyUtils', 'IgniteMessages', 'IgniteConfirm', 'AgentManager', 'IgniteChartColors', 'IgniteNotebook', 'IgniteNodes', 'uiGridExporterConstants', 'IgniteVersion', 'IgniteActivitiesData', 'JavaTypes', + function($root, $scope, $http, $q, $timeout, $interval, $animate, $location, $anchorScroll, $state, $filter, $modal, $popover, Loading, LegacyUtils, Messages, Confirm, agentMgr, IgniteChartColors, Notebook, Nodes, uiGridExporterConstants, Version, ActivitiesData, JavaTypes) { const $ctrl = this; // Define template urls. @@ -846,7 +846,7 @@ export default ['$rootScope', '$scope', '$http', '$q', '$timeout', '$interval', * @private */ const _refreshFn = () => - agentMonitor.topology(true) + agentMgr.topology(true) .then((nodes) => { $scope.caches = _.sortBy(_.reduce(nodes, (cachesAcc, node) => { _.forEach(node.caches, (cache) => { @@ -884,20 +884,10 @@ export default ['$rootScope', '$scope', '$http', '$q', '$timeout', '$interval', paragraph.cacheName = _.head(cacheNames); }); }) - .then(() => agentMonitor.checkModal()) - .catch((err) => agentMonitor.showNodeError(err)); + .catch((err) => Messages.showError(err)); const _startWatch = () => - agentMonitor.startWatch({ - state: 'base.configuration.clusters', - text: 'Back to Configuration', - goal: 'execute sql statements', - onDisconnect: () => { - _stopTopologyRefresh(); - - _startWatch(); - } - }) + agentMgr.startWatch('Back to Configuration', 'base.configuration.clusters') .then(() => Loading.start('sqlLoading')) .then(_refreshFn) .then(() => Loading.finish('sqlLoading')) @@ -1314,7 +1304,7 @@ export default ['$rootScope', '$scope', '$http', '$q', '$timeout', '$interval', const nid = paragraph.resNodeId; if (paragraph.queryId && _.find($scope.caches, ({nodes}) => _.includes(nodes, nid))) - return agentMonitor.queryClose(nid, paragraph.queryId); + return agentMgr.queryClose(nid, paragraph.queryId); return $q.when(); }; @@ -1346,11 +1336,11 @@ export default ['$rootScope', '$scope', '$http', '$q', '$timeout', '$interval', const _executeRefresh = (paragraph) => { const args = paragraph.queryArgs; - agentMonitor.awaitAgent() + agentMgr.awaitAgent() .then(() => _closeOldQuery(paragraph)) .then(() => args.localNid || _chooseNode(args.cacheName, false)) - .then((nid) => agentMonitor.query(nid, args.cacheName, args.query, args.nonCollocatedJoins, - args.enforceJoinOrder, !!args.localNid, args.pageSize)) + .then((nid) => agentMgr.querySql(nid, args.cacheName, args.query, args.nonCollocatedJoins, + args.enforceJoinOrder, false, !!args.localNid, args.pageSize)) .then(_processQueryResult.bind(this, paragraph, false)) .catch((err) => paragraph.setError(err)); }; @@ -1422,7 +1412,7 @@ export default ['$rootScope', '$scope', '$http', '$q', '$timeout', '$interval', ActivitiesData.post({ action: '/queries/execute' }); - return agentMonitor.query(nid, args.cacheName, qry, nonCollocatedJoins, enforceJoinOrder, local, args.pageSize); + return agentMgr.querySql(nid, args.cacheName, qry, nonCollocatedJoins, enforceJoinOrder, false, local, args.pageSize); }) .then((res) => { _processQueryResult(paragraph, true, res); @@ -1475,7 +1465,7 @@ export default ['$rootScope', '$scope', '$http', '$q', '$timeout', '$interval', ActivitiesData.post({ action: '/queries/explain' }); - return agentMonitor.query(nid, args.cacheName, args.query, false, !!paragraph.enforceJoinOrder, false, args.pageSize); + return agentMgr.querySql(nid, args.cacheName, args.query, false, !!paragraph.enforceJoinOrder, false, false, args.pageSize); }) .then(_processQueryResult.bind(this, paragraph, true)) .catch((err) => { @@ -1516,7 +1506,7 @@ export default ['$rootScope', '$scope', '$http', '$q', '$timeout', '$interval', ActivitiesData.post({ action: '/queries/scan' }); - return agentMonitor.scan(nid, cacheName, filter, false, caseSensitive, false, local, pageSize); + return agentMgr.queryScan(nid, cacheName, filter, false, caseSensitive, false, local, pageSize); }) .then((res) => _processQueryResult(paragraph, true, res)) .catch((err) => { @@ -1549,7 +1539,7 @@ export default ['$rootScope', '$scope', '$http', '$q', '$timeout', '$interval', paragraph.queryArgs.pageSize = paragraph.pageSize; - agentMonitor.next(paragraph.resNodeId, paragraph.queryId, paragraph.pageSize) + agentMgr.queryNextPage(paragraph.resNodeId, paragraph.queryId, paragraph.pageSize) .then((res) => { paragraph.page++; @@ -1637,10 +1627,9 @@ export default ['$rootScope', '$scope', '$http', '$q', '$timeout', '$interval', const args = paragraph.queryArgs; return Promise.resolve(args.localNid || _chooseNode(args.cacheName, false)) - .then((nid) => - args.type === 'SCAN' - ? agentMonitor.scanGetAll(nid, args.cacheName, args.filter, !!args.regEx, !!args.caseSensitive, !!args.near, !!args.localNid) - : agentMonitor.queryGetAll(nid, args.cacheName, args.query, !!args.nonCollocatedJoins, !!args.enforceJoinOrder, !!args.localNid)) + .then((nid) => args.type === 'SCAN' + ? agentMgr.queryScanGetAll(nid, args.cacheName, args.filter, !!args.regEx, !!args.caseSensitive, !!args.near, !!args.localNid) + : agentMgr.querySqlGetAll(nid, args.cacheName, args.query, !!args.nonCollocatedJoins, !!args.enforceJoinOrder, false, !!args.localNid)) .then((res) => _export(paragraph.name + '-all.csv', paragraph.gridOptions.columnDefs, res.columns, res.rows)) .catch(Messages.showError) .then(() => paragraph.ace && paragraph.ace.focus()); @@ -1728,7 +1717,7 @@ export default ['$rootScope', '$scope', '$http', '$q', '$timeout', '$interval', $scope.metadata = []; - agentMonitor.metadata() + agentMgr.metadata() .then((metadata) => { $scope.metadata = _.sortBy(_.filter(metadata, (meta) => { const cache = _.find($scope.caches, { name: meta.cacheName }); @@ -1774,7 +1763,7 @@ export default ['$rootScope', '$scope', '$http', '$q', '$timeout', '$interval', } // Show a basic modal from a controller - $modal({scope, templateUrl: messageTemplateUrl, placement: 'center', show: true}); + $modal({scope, templateUrl: messageTemplateUrl, show: true}); } }; @@ -1798,7 +1787,7 @@ export default ['$rootScope', '$scope', '$http', '$q', '$timeout', '$interval', } // Show a basic modal from a controller - $modal({scope, templateUrl: messageTemplateUrl, placement: 'center', show: true}); + $modal({scope, templateUrl: messageTemplateUrl, show: true}); } }; } http://git-wip-us.apache.org/repos/asf/ignite/blob/323e3870/modules/web-console/frontend/app/modules/states/admin.state.js ---------------------------------------------------------------------- diff --git a/modules/web-console/frontend/app/modules/states/admin.state.js b/modules/web-console/frontend/app/modules/states/admin.state.js index ea9ba49..cbd43f5 100644 --- a/modules/web-console/frontend/app/modules/states/admin.state.js +++ b/modules/web-console/frontend/app/modules/states/admin.state.js @@ -27,13 +27,13 @@ angular .config(['$stateProvider', 'AclRouteProvider', function($stateProvider, AclRoute) { // set up the states $stateProvider - .state('settings.admin', { + .state('base.settings.admin', { url: '/admin', views: { '@': { template }, - '@settings.admin': { + '@base.settings.admin': { templateUrl } }, http://git-wip-us.apache.org/repos/asf/ignite/blob/323e3870/modules/web-console/frontend/app/modules/states/configuration.state.js ---------------------------------------------------------------------- diff --git a/modules/web-console/frontend/app/modules/states/configuration.state.js b/modules/web-console/frontend/app/modules/states/configuration.state.js index a609d3a..624cf5f 100644 --- a/modules/web-console/frontend/app/modules/states/configuration.state.js +++ b/modules/web-console/frontend/app/modules/states/configuration.state.js @@ -51,15 +51,15 @@ angular.module('ignite-console.states.configuration', ['ui.router']) .state('base.configuration', { url: '/configuration', templateUrl: sidebarTpl, - abstract: true + abstract: true, + params: { + linkId: null + } }) .state('base.configuration.clusters', { url: '/clusters', templateUrl: clustersTpl, onEnter: AclRoute.checkAccess('configuration'), - params: { - linkId: null - }, metaTags: { title: 'Configure Clusters' } @@ -68,9 +68,6 @@ angular.module('ignite-console.states.configuration', ['ui.router']) url: '/caches', templateUrl: cachesTpl, onEnter: AclRoute.checkAccess('configuration'), - params: { - linkId: null - }, metaTags: { title: 'Configure Caches' } @@ -79,9 +76,6 @@ angular.module('ignite-console.states.configuration', ['ui.router']) url: '/domains', templateUrl: domainsTpl, onEnter: AclRoute.checkAccess('configuration'), - params: { - linkId: null - }, metaTags: { title: 'Configure Domain Model' } @@ -90,9 +84,6 @@ angular.module('ignite-console.states.configuration', ['ui.router']) url: '/igfs', templateUrl: igfsTpl, onEnter: AclRoute.checkAccess('configuration'), - params: { - linkId: null - }, metaTags: { title: 'Configure IGFS' } http://git-wip-us.apache.org/repos/asf/ignite/blob/323e3870/modules/web-console/frontend/app/modules/states/profile.state.js ---------------------------------------------------------------------- diff --git a/modules/web-console/frontend/app/modules/states/profile.state.js b/modules/web-console/frontend/app/modules/states/profile.state.js index 7c270ad..3298bdc 100644 --- a/modules/web-console/frontend/app/modules/states/profile.state.js +++ b/modules/web-console/frontend/app/modules/states/profile.state.js @@ -26,7 +26,7 @@ angular .config(['$stateProvider', 'AclRouteProvider', function($stateProvider, AclRoute) { // set up the states $stateProvider - .state('settings.profile', { + .state('base.settings.profile', { url: '/profile', templateUrl, onEnter: AclRoute.checkAccess('profile'), http://git-wip-us.apache.org/repos/asf/ignite/blob/323e3870/modules/web-console/frontend/app/modules/user/Auth.service.js ---------------------------------------------------------------------- diff --git a/modules/web-console/frontend/app/modules/user/Auth.service.js b/modules/web-console/frontend/app/modules/user/Auth.service.js index 95ff4c3..a2f4763 100644 --- a/modules/web-console/frontend/app/modules/user/Auth.service.js +++ b/modules/web-console/frontend/app/modules/user/Auth.service.js @@ -15,8 +15,8 @@ * limitations under the License. */ -export default ['Auth', ['$http', '$rootScope', '$state', '$window', 'IgniteErrorPopover', 'IgniteMessages', 'gettingStarted', 'User', 'IgniteAgentMonitor', - ($http, $root, $state, $window, ErrorPopover, Messages, gettingStarted, User, agentMonitor) => { +export default ['Auth', ['$http', '$rootScope', '$state', '$window', 'IgniteErrorPopover', 'IgniteMessages', 'gettingStarted', 'User', + ($http, $root, $state, $window, ErrorPopover, Messages, gettingStarted, User) => { return { forgotPassword(userInfo) { $http.post('/api/v1/password/forgot', userInfo) @@ -35,8 +35,6 @@ export default ['Auth', ['$http', '$rootScope', '$state', '$window', 'IgniteErro $state.go('base.configuration.clusters'); - agentMonitor.init(); - $root.gettingStarted.tryShow(); }); }) http://git-wip-us.apache.org/repos/asf/ignite/blob/323e3870/modules/web-console/frontend/app/services/Confirm.service.js ---------------------------------------------------------------------- diff --git a/modules/web-console/frontend/app/services/Confirm.service.js b/modules/web-console/frontend/app/services/Confirm.service.js index 0b5b9be..1638d7e 100644 --- a/modules/web-console/frontend/app/services/Confirm.service.js +++ b/modules/web-console/frontend/app/services/Confirm.service.js @@ -21,7 +21,7 @@ import templateUrl from 'views/templates/confirm.tpl.pug'; export default ['IgniteConfirm', ['$rootScope', '$q', '$modal', '$animate', ($root, $q, $modal, $animate) => { const scope = $root.$new(); - const modal = $modal({templateUrl, scope, placement: 'center', show: false, backdrop: true}); + const modal = $modal({templateUrl, scope, show: false, backdrop: true}); const _hide = () => { $animate.enabled(modal.$element, false); http://git-wip-us.apache.org/repos/asf/ignite/blob/323e3870/modules/web-console/frontend/app/services/ConfirmBatch.service.js ---------------------------------------------------------------------- diff --git a/modules/web-console/frontend/app/services/ConfirmBatch.service.js b/modules/web-console/frontend/app/services/ConfirmBatch.service.js index 2fd55b7..8b473d8 100644 --- a/modules/web-console/frontend/app/services/ConfirmBatch.service.js +++ b/modules/web-console/frontend/app/services/ConfirmBatch.service.js @@ -24,7 +24,6 @@ export default ['IgniteConfirmBatch', ['$rootScope', '$q', '$modal', ($root, $q, scope.confirmModal = $modal({ templateUrl, scope, - placement: 'center', show: false, backdrop: 'static', keyboard: false http://git-wip-us.apache.org/repos/asf/ignite/blob/323e3870/modules/web-console/frontend/controllers/caches-controller.js ---------------------------------------------------------------------- diff --git a/modules/web-console/frontend/controllers/caches-controller.js b/modules/web-console/frontend/controllers/caches-controller.js index 176a634..bf97692 100644 --- a/modules/web-console/frontend/controllers/caches-controller.js +++ b/modules/web-console/frontend/controllers/caches-controller.js @@ -513,7 +513,7 @@ export default ['cachesController', [ ]; // Show a basic modal from a controller - $modal({scope, templateUrl: infoMessageTemplateUrl, placement: 'center', show: true}); + $modal({scope, templateUrl: infoMessageTemplateUrl, show: true}); } save(item); http://git-wip-us.apache.org/repos/asf/ignite/blob/323e3870/modules/web-console/frontend/controllers/domains-controller.js ---------------------------------------------------------------------- diff --git a/modules/web-console/frontend/controllers/domains-controller.js b/modules/web-console/frontend/controllers/domains-controller.js index 806dd45..57050a0 100644 --- a/modules/web-console/frontend/controllers/domains-controller.js +++ b/modules/web-console/frontend/controllers/domains-controller.js @@ -19,8 +19,8 @@ import templateUrl from 'views/configuration/domains-import.tpl.pug'; // Controller for Domain model screen. export default ['domainsController', [ - '$rootScope', '$scope', '$http', '$state', '$filter', '$timeout', '$modal', 'IgniteLegacyUtils', 'IgniteMessages', 'IgniteFocus', 'IgniteConfirm', 'IgniteConfirmBatch', 'IgniteInput', 'IgniteLoading', 'IgniteModelNormalizer', 'IgniteUnsavedChangesGuard', 'IgniteAgentMonitor', 'IgniteLegacyTable', 'IgniteConfigurationResource', 'IgniteErrorPopover', 'IgniteFormUtils', 'JavaTypes', 'SqlTypes', 'IgniteActivitiesData', - function($root, $scope, $http, $state, $filter, $timeout, $modal, LegacyUtils, Messages, Focus, Confirm, ConfirmBatch, Input, Loading, ModelNormalizer, UnsavedChangesGuard, IgniteAgentMonitor, LegacyTable, Resource, ErrorPopover, FormUtils, JavaTypes, SqlTypes, ActivitiesData) { + '$rootScope', '$scope', '$http', '$state', '$filter', '$timeout', '$modal', 'IgniteLegacyUtils', 'IgniteMessages', 'IgniteFocus', 'IgniteConfirm', 'IgniteConfirmBatch', 'IgniteInput', 'IgniteLoading', 'IgniteModelNormalizer', 'IgniteUnsavedChangesGuard', 'AgentManager', 'IgniteLegacyTable', 'IgniteConfigurationResource', 'IgniteErrorPopover', 'IgniteFormUtils', 'JavaTypes', 'SqlTypes', 'IgniteActivitiesData', + function($root, $scope, $http, $state, $filter, $timeout, $modal, LegacyUtils, Messages, Focus, Confirm, ConfirmBatch, Input, Loading, ModelNormalizer, UnsavedChangesGuard, agentMgr, LegacyTable, Resource, ErrorPopover, FormUtils, JavaTypes, SqlTypes, ActivitiesData) { UnsavedChangesGuard.install($scope); const emptyDomain = {empty: true}; @@ -416,7 +416,7 @@ export default ['domainsController', [ const hideImportDomain = importDomainModal.hide; importDomainModal.hide = function() { - IgniteAgentMonitor.stopWatch(); + agentMgr.stopWatch(); hideImportDomain(); }; @@ -461,7 +461,7 @@ export default ['domainsController', [ $scope.importDomain.loadingOptions = LOADING_JDBC_DRIVERS; - IgniteAgentMonitor.startWatch({text: 'Back to Domain models', goal: 'import domain model from database'}) + agentMgr.startWatch('Back to Domain models', 'import domain model from database') .then(() => { ActivitiesData.post({ group: 'configuration', @@ -486,7 +486,7 @@ export default ['domainsController', [ $scope.jdbcDriverJars = []; $scope.ui.selectedJdbcDriverJar = {}; - return IgniteAgentMonitor.drivers() + return agentMgr.drivers() .then((drivers) => { $scope.ui.packageName = $scope.ui.packageNameUserInput; @@ -530,19 +530,19 @@ export default ['domainsController', [ * Load list of database schemas. */ function _loadSchemas() { - IgniteAgentMonitor.awaitAgent() + agentMgr.awaitAgent() .then(function() { $scope.importDomain.loadingOptions = LOADING_SCHEMAS; Loading.start('importDomainFromDb'); if ($root.IgniteDemoMode) - return IgniteAgentMonitor.schemas($scope.demoConnection); + return agentMgr.schemas($scope.demoConnection); const preset = $scope.selectedPreset; _savePreset(preset); - return IgniteAgentMonitor.schemas(preset); + return agentMgr.schemas(preset); }) .then(function(schemas) { $scope.importDomain.schemas = _.map(schemas, function(schema) { @@ -674,7 +674,7 @@ export default ['domainsController', [ * Load list of database tables. */ function _loadTables() { - IgniteAgentMonitor.awaitAgent() + agentMgr.awaitAgent() .then(function() { $scope.importDomain.loadingOptions = LOADING_TABLES; Loading.start('importDomainFromDb'); @@ -690,7 +690,7 @@ export default ['domainsController', [ preset.schemas.push(schema.name); }); - return IgniteAgentMonitor.tables(preset); + return agentMgr.tables(preset); }) .then(function(tables) { _importCachesOrTemplates = [DFLT_PARTITIONED_CACHE, DFLT_REPLICATED_CACHE].concat($scope.caches); http://git-wip-us.apache.org/repos/asf/ignite/blob/323e3870/modules/web-console/frontend/package.json ---------------------------------------------------------------------- diff --git a/modules/web-console/frontend/package.json b/modules/web-console/frontend/package.json index b11f690..fccc944 100644 --- a/modules/web-console/frontend/package.json +++ b/modules/web-console/frontend/package.json @@ -30,7 +30,7 @@ ], "dependencies": { "angular": "1.5.11", - "angular-acl": "0.1.7", + "angular-acl": "0.1.8", "angular-animate": "1.5.11", "angular-aria": "1.5.11", "angular-cookies": "1.5.11", @@ -44,17 +44,17 @@ "angular-socket-io": "0.7.0", "angular-strap": "2.3.12", "angular-touch": "1.5.11", - "angular-translate": "2.14.0", + "angular-translate": "2.15.1", "angular-tree-control": "0.2.28", - "angular-ui-grid": "4.0.2", + "angular-ui-grid": "4.0.4", "angular-ui-router": "0.4.2", "bootstrap-sass": "3.3.7", - "brace": "0.8.0", - "es6-promise": "4.0.5", + "brace": "0.10.0", + "es6-promise": "4.1.0", "file-saver": "1.3.3", "font-awesome": "4.7.0", "glob": "7.1.1", - "jquery": "3.1.1", + "jquery": "3.2.1", "jszip": "3.1.3", "lodash": "4.17.4", "nvd3": "1.8.4", @@ -65,26 +65,26 @@ }, "devDependencies": { "assets-webpack-plugin": "3.5.1", - "autoprefixer": "6.7.5", - "babel-core": "6.20.0", - "babel-eslint": "7.0.0", - "babel-loader": "6.2.10", + "autoprefixer": "6.7.7", + "babel-core": "6.24.1", + "babel-eslint": "7.2.1", + "babel-loader": "6.4.1", "babel-plugin-add-module-exports": "0.2.1", "babel-plugin-transform-builtin-extend": "1.1.2", - "babel-plugin-transform-runtime": "6.15.0", - "babel-polyfill": "6.20.0", + "babel-plugin-transform-runtime": "6.23.0", + "babel-polyfill": "6.23.0", "babel-preset-angular": "6.0.15", - "babel-preset-es2015": "6.18.0", - "babel-runtime": "6.20.0", + "babel-preset-es2015": "6.24.1", + "babel-runtime": "6.23.0", "chai": "3.5.0", - "cross-env": "3.1.4", - "css-loader": "0.26.2", - "eslint": "3.16.1", + "cross-env": "4.0.0", + "css-loader": "0.28.0", + "eslint": "3.19.0", "eslint-friendly-formatter": "2.0.7", - "eslint-loader": "1.6.3", + "eslint-loader": "1.7.1", "expose-loader": "0.7.3", - "extract-text-webpack-plugin": "2.0.0", - "file-loader": "0.10.1", + "extract-text-webpack-plugin": "2.1.0", + "file-loader": "0.11.1", "gulp": "3.9.1", "gulp-eslint": "3.0.1", "gulp-inject": "4.2.0", @@ -95,31 +95,31 @@ "html-webpack-plugin": "2.28.0", "jasmine-core": "2.5.2", "json-loader": "0.5.4", - "karma": "1.5.0", + "karma": "1.6.0", "karma-babel-preprocessor": "6.0.1", "karma-jasmine": "1.1.0", "karma-mocha": "1.3.0", - "karma-mocha-reporter": "2.2.2", - "karma-phantomjs-launcher": "1.0.2", + "karma-mocha-reporter": "2.2.3", + "karma-phantomjs-launcher": "1.0.4", "karma-teamcity-reporter": "1.0.0", - "karma-webpack": "2.0.2", + "karma-webpack": "2.0.3", "mocha": "3.2.0", "mocha-teamcity-reporter": "1.1.1", "ngtemplate-loader": "1.3.1", - "node-sass": "4.5.0", + "node-sass": "4.5.2", "phantomjs-prebuilt": "2.1.14", - "postcss-loader": "1.3.2", + "postcss-loader": "1.3.3", "progress-bar-webpack-plugin": "1.9.3", "pug-html-loader": "1.1.0", "pug-loader": "2.3.0", "require-dir": "0.3.1", - "resolve-url-loader": "2.0.0", - "sass-loader": "6.0.2", - "style-loader": "0.13.2", + "resolve-url-loader": "2.0.2", + "sass-loader": "6.0.3", + "style-loader": "0.16.1", "url": "0.11.0", "url-loader": "0.5.8", - "webpack": "2.2.1", - "webpack-dev-server": "2.4.1", + "webpack": "2.3.3", + "webpack-dev-server": "2.4.2", "webpack-stream": "3.2.0", "worker-loader": "0.8.0" } http://git-wip-us.apache.org/repos/asf/ignite/blob/323e3870/modules/web-console/frontend/public/stylesheets/_bootstrap-variables.scss ---------------------------------------------------------------------- diff --git a/modules/web-console/frontend/public/stylesheets/_bootstrap-variables.scss b/modules/web-console/frontend/public/stylesheets/_bootstrap-variables.scss index 07e8c51..e308de3 100644 --- a/modules/web-console/frontend/public/stylesheets/_bootstrap-variables.scss +++ b/modules/web-console/frontend/public/stylesheets/_bootstrap-variables.scss @@ -441,7 +441,7 @@ $navbar-inverse-toggle-border-color: #333 !default; //## //=== Shared nav styles -$nav-link-padding: 10px 15px !default; +$nav-link-padding: 0 0 0 15px !default; $nav-link-hover-bg: transparent !default; $nav-disabled-link-color: $gray-light !default; http://git-wip-us.apache.org/repos/asf/ignite/blob/323e3870/modules/web-console/frontend/public/stylesheets/_font-awesome-custom.scss ---------------------------------------------------------------------- diff --git a/modules/web-console/frontend/public/stylesheets/_font-awesome-custom.scss b/modules/web-console/frontend/public/stylesheets/_font-awesome-custom.scss index 47555a7..16670a5 100644 --- a/modules/web-console/frontend/public/stylesheets/_font-awesome-custom.scss +++ b/modules/web-console/frontend/public/stylesheets/_font-awesome-custom.scss @@ -97,3 +97,8 @@ $fa-font-path: '~font-awesome/fonts'; margin: 0; } + +.icon-cluster { + @extend .fa; + @extend .fa-sitemap; +} http://git-wip-us.apache.org/repos/asf/ignite/blob/323e3870/modules/web-console/frontend/public/stylesheets/style.scss ---------------------------------------------------------------------- diff --git a/modules/web-console/frontend/public/stylesheets/style.scss b/modules/web-console/frontend/public/stylesheets/style.scss index 882a363..f3dd3c9 100644 --- a/modules/web-console/frontend/public/stylesheets/style.scss +++ b/modules/web-console/frontend/public/stylesheets/style.scss @@ -274,10 +274,6 @@ ul.navbar-nav, .sidebar-nav { } } -.header .nav.navbar-nav.pull-right > li > a { - padding-right: 0; -} - .header .title { margin: 20px 0 5px 0; padding: 0 15px; @@ -285,26 +281,36 @@ ul.navbar-nav, .sidebar-nav { font-size: 1.4em; } -.header .nav.navbar-nav .not-link { - padding: 15px; - display: inline-block; -} - .nav > li { > a { - color: $navbar-default-link-color - } - > a:hover { - color: $link-hover-color + color: $navbar-default-link-color; + + &:hover, + &:focus { + color: $link-hover-color; + } + + &.active { + color: $link-color; + } } - > a.active { - color: $link-color + + &.disabled > a { + label:hover, label:focus, i:hover, i:focus { + cursor: default; + } } } -.theme-line header .navbar-nav a { - line-height: 25px; - font-size: 18px; +.theme-line header .navbar-nav { + a { + line-height: 25px; + font-size: 18px; + } + + > li > a { + padding-right: 0; + } } .theme-line .section-right { @@ -1621,6 +1627,19 @@ th[st-sort] { padding: 10px 10px 10px 20px; } +// Hack to solve an issue where scrollbars aren't visible in Safari. +// Safari seems to clip part of the scrollbar element. By giving the +// element a background, we're telling Safari that it *really* needs to +// paint the whole area. See https://github.com/ajaxorg/ace/issues/2872 +.ace_scrollbar-inner { + background-color: #FFF; + opacity: 0.01; + + .ace_dark & { + background-color: #000; + } +} + .ace_content { padding-left: 5px; } @@ -2357,4 +2376,4 @@ html,body,.splash-screen { height: 65px; } } -} \ No newline at end of file +} http://git-wip-us.apache.org/repos/asf/ignite/blob/323e3870/modules/web-console/frontend/views/includes/header.pug ---------------------------------------------------------------------- diff --git a/modules/web-console/frontend/views/includes/header.pug b/modules/web-console/frontend/views/includes/header.pug index 99bcea9..ff8692e 100644 --- a/modules/web-console/frontend/views/includes/header.pug +++ b/modules/web-console/frontend/views/includes/header.pug @@ -27,26 +27,31 @@ header#header.header a.dropdown-toggle Configure span.caret - ul.nav.navbar-nav(ng-controller='notebookController') - li.sql-notebooks(ng-if='IgniteDemoMode' ng-class='{active: $state.includes("base.sql")}') + ul.nav.navbar-nav(ng-if='IgniteDemoMode' ng-controller='notebookController') + li.sql-notebooks( ng-class='{active: $state.includes("base.sql")}') a(ui-sref='base.sql.demo') Queries - li.sql-notebooks(ng-if='!IgniteDemoMode && !notebooks.length' ng-class='{active: $state.includes("base.sql")}') + ul.nav.navbar-nav(ng-if='!IgniteDemoMode' ng-controller='notebookController') + li.sql-notebooks(ng-if='!notebooks.length' ng-class='{active: $state.includes("base.sql")}') a(ng-click='createNotebook()') Queries - li.sql-notebooks(ng-if='!IgniteDemoMode && notebooks.length' ng-class='{active: $state.includes("base.sql")}' bs-dropdown='notebooks' data-placement='bottom-left' data-trigger='hover focus' data-container='self' data-animation='' ng-click='$event.stopPropagation()' aria-haspopup='true' aria-expanded='false') + li.sql-notebooks(ng-if='notebooks.length' ng-class='{active: $state.includes("base.sql")}' bs-dropdown='notebooks' data-placement='bottom-left' data-trigger='hover focus' data-container='self' data-animation='' ng-click='$event.stopPropagation()' aria-haspopup='true' aria-expanded='false') a.dropdown-toggle Queries span.caret + ul.nav.navbar-nav li(ui-sref-active='active' ng-repeat='item in navbar.items' ng-class='{active: $state.includes("base.monitoring")}' bs-dropdown='item.children' data-placement='bottom-left' data-trigger='hover focus' data-container='self' data-animation='' ng-click='$event.stopPropagation()' aria-haspopup='true' aria-expanded='false') a.dropdown-toggle {{::item.text}} span.caret - a(ng-controller='demoController') + a.padding-left-dflt(ng-controller='demoController') button.btn.btn-info(ng-if='IgniteDemoMode' ng-click='closeDemo()') Close demo button.btn.btn-info(ng-if='!IgniteDemoMode' ng-click='startDemo()') Start demo - ul.nav.navbar-nav.pull-right(ignite-userbar) - li(bs-dropdown='userbar.items' data-placement='bottom-right' data-trigger='hover focus' data-container='self' data-animation='' ng-class='{active: $state.includes("settings")}' ng-click='$event.stopPropagation()') - a.dropdown-toggle {{user.firstName}} {{user.lastName}} - span.caret + .pull-right + ignite-cluster-select + + ul.nav.navbar-nav.pull-right(ignite-userbar) + li(bs-dropdown='userbar.items' data-placement='bottom-right' data-trigger='hover focus' data-container='self' data-animation='' ng-class='{active: $state.includes("settings")}' ng-click='$event.stopPropagation()') + a.dropdown-toggle {{user.firstName}} {{user.lastName}} + span.caret http://git-wip-us.apache.org/repos/asf/ignite/blob/323e3870/modules/web-console/frontend/views/templates/agent-download.tpl.pug ---------------------------------------------------------------------- diff --git a/modules/web-console/frontend/views/templates/agent-download.tpl.pug b/modules/web-console/frontend/views/templates/agent-download.tpl.pug index b913636..615abbc 100644 --- a/modules/web-console/frontend/views/templates/agent-download.tpl.pug +++ b/modules/web-console/frontend/views/templates/agent-download.tpl.pug @@ -15,29 +15,38 @@ limitations under the License. .modal.center(tabindex='-1' role='dialog') - .modal-dialog - .modal-content - #errors-container.modal-header.header + .modal-dialog(ng-switch='ctrl.status') + .modal-content(ng-switch-when='agentMissing') + .modal-header.header h4.modal-title i.fa.fa-download - span(ng-if='!hasAgents') Connection to Ignite Web Agent is not established - span(ng-if='hasAgents') Connection to Ignite Node is not established - .agent-download(ng-if='!hasAgents') - p Please download and run #[a(href='/api/v1/agent/download/zip' target='_self') ignite-web-agent] in order to {{::agentGoal}} + span Connection to Ignite Web Agent is not established + .modal-body.agent-download + p Please download and run #[a(href='/api/v1/downloads/agent' target='_self') ignite-web-agent] to use this functionality p For run: ul - li Download and unzip #[a(href='/api/v1/agent/download/zip' target='_self') ignite-web-agent] archive + li Download and unzip #[a(href='/api/v1/downloads/agent' target='_self') ignite-web-agent] archive li Run shell file #[b ignite-web-agent.{sh|bat}] p Refer to #[b README.txt] in agent folder for more information .modal-advanced-options - i.fa.fa-chevron-circle-down(ng-show='agentLoad.showToken' ng-click='agentLoad.showToken = ! agentLoad.showToken') - i.fa.fa-chevron-circle-right(ng-show='!agentLoad.showToken' ng-click='agentLoad.showToken = ! agentLoad.showToken') - a(ng-click='agentLoad.showToken = ! agentLoad.showToken') {{agentLoad.showToken ? 'Hide security token...' : 'Show security token...'}} - .details-row(ng-show='agentLoad.showToken') + i.fa(ng-class='showToken ? "fa-chevron-circle-down" : "fa-chevron-circle-right"' ng-click='showToken = !showToken') + a(ng-click='showToken = !showToken') {{showToken ? 'Hide security token...' : 'Show security token...'}} + .details-row(ng-show='showToken') label.labelField Security token: {{user.becameToken || user.token}} i.tipLabel.fa.fa-clipboard(ignite-copy-to-clipboard='{{user.becameToken || user.token}}' bs-tooltip='' data-title='Copy security token to clipboard') i.tipLabel.icon-help(ng-if=lines bs-tooltip='' data-title='The security token is used for authorization of web agent') - .agent-download(ng-if='hasAgents') + + .modal-footer + button.btn.btn-default(ng-click='ctrl.back()') {{::ctrl.backText}} + a.btn.btn-primary(href='/api/v1/downloads/agent' target='_self') Download agent + + .modal-content(ng-switch-when='nodeMissing') + .modal-header.header + h4.modal-title + i.fa.fa-download + span Connection to Ignite Node is not established + + .modal-body.agent-download p Connection to Ignite Web Agent is established, but agent failed to connect to Ignite Node p Please check the following: ul @@ -45,6 +54,6 @@ li In agent settings check URI for connect to Ignite REST server li Check agent logs for errors li Refer to #[b README.txt] in agent folder for more information + .modal-footer - button.btn.btn-default(ng-click='back()') {{::backText}} - a.btn.btn-primary(ng-if='!hasAgents' href='/api/v1/agent/download/zip' target='_self') Download agent + button.btn.btn-default(ng-click='ctrl.back()') {{::ctrl.backText}} http://git-wip-us.apache.org/repos/asf/ignite/blob/323e3870/modules/web-console/frontend/views/templates/demo-info.tpl.pug ---------------------------------------------------------------------- diff --git a/modules/web-console/frontend/views/templates/demo-info.tpl.pug b/modules/web-console/frontend/views/templates/demo-info.tpl.pug index 44c091c..62642b3 100644 --- a/modules/web-console/frontend/views/templates/demo-info.tpl.pug +++ b/modules/web-console/frontend/views/templates/demo-info.tpl.pug @@ -44,4 +44,4 @@ li Close dialog and try Web Console .modal-footer button.btn.btn-default(ng-class='hasAgents ? "btn-primary" : "btn-default"' ng-click='close()') Close - button.btn.btn-primary(ng-hide='hasAgents' ng-click='downloadAgent()') Download agent + a.btn.btn-primary(ng-hide='hasAgents' href='/api/v1/downloads/agent' target='_self') Download agent http://git-wip-us.apache.org/repos/asf/ignite/blob/323e3870/modules/web-console/web-agent/pom.xml ---------------------------------------------------------------------- diff --git a/modules/web-console/web-agent/pom.xml b/modules/web-console/web-agent/pom.xml index 530aef6..697e58f 100644 --- a/modules/web-console/web-agent/pom.xml +++ b/modules/web-console/web-agent/pom.xml @@ -43,7 +43,7 @@ <dependency> <groupId>io.socket</groupId> <artifactId>socket.io-client</artifactId> - <version>0.7.0</version> + <version>0.8.3</version> </dependency> <dependency> @@ -59,9 +59,9 @@ </dependency> <dependency> - <groupId>org.apache.httpcomponents</groupId> - <artifactId>httpclient</artifactId> - <version>${httpclient.version}</version> + <groupId>com.squareup.okhttp3</groupId> + <artifactId>okhttp</artifactId> + <version>3.6.0</version> </dependency> <dependency> @@ -98,9 +98,15 @@ <dependency> <groupId>org.apache.ignite</groupId> - <artifactId>ignite-log4j</artifactId> + <artifactId>ignite-slf4j</artifactId> <version>${project.version}</version> </dependency> + + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>jul-to-slf4j</artifactId> + <version>${slf4j.version}</version> + </dependency> </dependencies> <build>
