diff --git a/ignite-extensions/modules/elasticsearch-relay/src/main/java/org/elasticsearch/relay/permissions/PermissionCrawler.java b/ignite-extensions/modules/elasticsearch-relay/src/main/java/org/elasticsearch/relay/permissions/PermissionCrawler.java index 928702c56a9cc..2b4f8f038afa8 100644 --- a/ignite-extensions/modules/elasticsearch-relay/src/main/java/org/elasticsearch/relay/permissions/PermissionCrawler.java +++ b/ignite-extensions/modules/elasticsearch-relay/src/main/java/org/elasticsearch/relay/permissions/PermissionCrawler.java @@ -34,7 +34,6 @@ public class PermissionCrawler implements IPermCrawler, Runnable { private static PermissionCrawler fPermCrawler = null; - private final Object fTrigger = new Object(); @@ -122,17 +121,13 @@ public void run() { fActive = false; } - try { - fLogger.log(Level.INFO, "starting permission crawl"); - long time = System.currentTimeMillis(); + fLogger.log(Level.INFO, "starting permission crawl"); + long time = System.currentTimeMillis(); - crawl(); + crawl(); - time = System.currentTimeMillis() - time; - fLogger.log(Level.INFO, "finished crawl in " + time + "ms"); - } catch (Exception e) { - fLogger.log(Level.WARNING,e.getMessage()); - } + time = System.currentTimeMillis() - time; + fLogger.log(Level.INFO, "finished crawl in " + time + "ms"); } } @@ -143,7 +138,7 @@ public void run() { * @throws Exception * if crawling fails */ - public void crawl() throws Exception { + public void crawl() { // clear users fUsers.clear(); @@ -177,7 +172,7 @@ public void crawl() throws Exception { } } } catch(Exception e) { - fLogger.log(Level.WARNING,e.getMessage()); + fLogger.log(Level.INFO,e.getMessage()); } // crawl all permissions for all users diff --git a/ignite-extensions/modules/ignite-graph/works-ignite-gremlin-server/src/main/java/de/kp/works/ignite/gremlin/plugin/GremlinPlugin.java b/ignite-extensions/modules/ignite-graph/works-ignite-gremlin-server/src/main/java/de/kp/works/ignite/gremlin/plugin/GremlinPlugin.java index a6f0592565acc..2fefa280b1fb5 100644 --- a/ignite-extensions/modules/ignite-graph/works-ignite-gremlin-server/src/main/java/de/kp/works/ignite/gremlin/plugin/GremlinPlugin.java +++ b/ignite-extensions/modules/ignite-graph/works-ignite-gremlin-server/src/main/java/de/kp/works/ignite/gremlin/plugin/GremlinPlugin.java @@ -4,6 +4,8 @@ import org.apache.tinkerpop.gremlin.server.GraphManager; import org.apache.tinkerpop.gremlin.structure.Graph; +import de.kp.works.ignite.gremlin.sql.IgniteGraphTraversalSource; + public class GremlinPlugin implements IgnitePlugin{ String databaseName; @@ -21,4 +23,8 @@ public Graph getGraph() { return graphManager.getGraph(databaseName); } + public IgniteGraphTraversalSource traversal() { + return graphManager.getGraph(databaseName).traversal(IgniteGraphTraversalSource.class); + } + } diff --git a/ignite-extensions/modules/ignite-graph/works-ignite-gremlin-server/src/main/java/de/kp/works/ignite/gremlin/plugin/GremlinServerPluginProvider.java b/ignite-extensions/modules/ignite-graph/works-ignite-gremlin-server/src/main/java/de/kp/works/ignite/gremlin/plugin/GremlinServerPluginProvider.java index fe26a01455bc0..2ded604a11e9e 100644 --- a/ignite-extensions/modules/ignite-graph/works-ignite-gremlin-server/src/main/java/de/kp/works/ignite/gremlin/plugin/GremlinServerPluginProvider.java +++ b/ignite-extensions/modules/ignite-graph/works-ignite-gremlin-server/src/main/java/de/kp/works/ignite/gremlin/plugin/GremlinServerPluginProvider.java @@ -17,10 +17,7 @@ package de.kp.works.ignite.gremlin.plugin; import java.io.File; -import java.io.IOException; import java.io.Serializable; -import java.net.BindException; -import java.net.Socket; import java.util.UUID; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutorService; @@ -33,19 +30,15 @@ import org.apache.ignite.plugin.CachePluginContext; import org.apache.ignite.plugin.CachePluginProvider; import org.apache.ignite.plugin.ExtensionRegistry; -import org.apache.ignite.plugin.IgnitePlugin; import org.apache.ignite.plugin.PluginConfiguration; import org.apache.ignite.plugin.PluginContext; import org.apache.ignite.plugin.PluginProvider; import org.apache.ignite.plugin.PluginValidationException; -import org.apache.tinkerpop.gremlin.server.GraphManager; import org.apache.tinkerpop.gremlin.server.GremlinServer; import org.apache.tinkerpop.gremlin.server.Settings; import org.apache.tinkerpop.gremlin.server.util.ServerGremlinExecutor; -import org.apache.tinkerpop.gremlin.structure.Graph; -import org.apache.tinkerpop.gremlin.structure.util.GraphFactory; - import org.jetbrains.annotations.Nullable; + import de.kp.works.ignite.IgniteConnect; @@ -198,7 +191,8 @@ public void onIgniteStart() { } catch (Exception e) { log.error("GremlinServer bind fail.", e); - throw new RuntimeException(e); + //-throw new RuntimeException(e); + gremlinServer = null; } } @@ -228,7 +222,7 @@ public void onIgniteStop(boolean cancel) { if (counter<=0 && gremlinServer!= null) { try { log.info("GremlinServer", "shutting down " + gremlinServer.toString()); - gremlinServer.stop(); + gremlinServer.stop(); gremlinServer = null; } catch (Exception e) { log.error("GremlinServer close fail.", e); diff --git a/ignite-extensions/modules/ignite-janus/src/main/java/de/kp/works/janus/gremlin/plugin/GremlinPlugin.java b/ignite-extensions/modules/ignite-janus/src/main/java/de/kp/works/janus/gremlin/plugin/GremlinPlugin.java index 7ac50edcf4748..8d9370dd2258b 100644 --- a/ignite-extensions/modules/ignite-janus/src/main/java/de/kp/works/janus/gremlin/plugin/GremlinPlugin.java +++ b/ignite-extensions/modules/ignite-janus/src/main/java/de/kp/works/janus/gremlin/plugin/GremlinPlugin.java @@ -1,6 +1,7 @@ package de.kp.works.janus.gremlin.plugin; import org.apache.ignite.plugin.IgnitePlugin; +import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource; import org.apache.tinkerpop.gremlin.server.GraphManager; import org.apache.tinkerpop.gremlin.structure.Graph; @@ -19,4 +20,8 @@ public Graph getGraph() { return graphManager.getGraph(databaseName); } + public GraphTraversalSource traversal() { + return graphManager.getGraph(databaseName).traversal(); + } + } diff --git a/ignite-extensions/modules/ignite-janus/src/main/java/de/kp/works/janus/gremlin/plugin/GremlinServerPluginProvider.java b/ignite-extensions/modules/ignite-janus/src/main/java/de/kp/works/janus/gremlin/plugin/GremlinServerPluginProvider.java index 03d427ecbf32e..fc26020b509db 100644 --- a/ignite-extensions/modules/ignite-janus/src/main/java/de/kp/works/janus/gremlin/plugin/GremlinServerPluginProvider.java +++ b/ignite-extensions/modules/ignite-janus/src/main/java/de/kp/works/janus/gremlin/plugin/GremlinServerPluginProvider.java @@ -200,8 +200,9 @@ public void onIgniteStart() { log.info("JanaGremlinServer", "listern on " + settings.host + ":" + settings.port); } catch (Exception e) { - log.error("GremlinServer bind fail.", e); - throw new RuntimeException(e); + log.error("JanaGremlinServer bind fail.", e); + // throw new RuntimeException(e); + janusGraphServer = null; } } } diff --git a/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/CacheJdbcPojoStoreFactory.java b/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/CacheJdbcPojoStoreFactory.java index 4fecc335345fc..a1c76a19b7afa 100644 --- a/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/CacheJdbcPojoStoreFactory.java +++ b/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/CacheJdbcPojoStoreFactory.java @@ -144,7 +144,7 @@ public class CacheJdbcPojoStoreFactory implements Factory dataSrcFactory; /** Flag indicating that table and field names should be escaped in all SQL queries created by JDBC POJO store. */ - private boolean sqlEscapeAll; + private boolean sqlEscapeAll = true; /** Application context. */ @SpringApplicationContextResource diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/checkpoint/Checkpointer.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/checkpoint/Checkpointer.java index e09d91451a027..69ee86efa5dd0 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/checkpoint/Checkpointer.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/checkpoint/Checkpointer.java @@ -428,7 +428,7 @@ private void doCheckpoint() { return; } else { - if (log.isInfoEnabled()) + if (log.isDebugEnabled()) LT.info(log, String.format( "Skipping checkpoint (no pages were modified) [" + "checkpointBeforeLockTime=%dms, checkpointLockWait=%dms, " + diff --git a/web-console/frontend/app/components/page-queries/components/queries-notebook/controller.ts b/web-console/frontend/app/components/page-queries/components/queries-notebook/controller.ts index 88f58e1bd5548..94309b28140b0 100644 --- a/web-console/frontend/app/components/page-queries/components/queries-notebook/controller.ts +++ b/web-console/frontend/app/components/page-queries/components/queries-notebook/controller.ts @@ -338,7 +338,7 @@ export class NotebookCtrl { $scope.aggregateFxs = ['FIRST', 'LAST', 'MIN', 'MAX', 'SUM', 'AVG', 'COUNT']; - $scope.modes = LegacyUtils.mkOptions(['PARTITIONED', 'REPLICATED', 'LOCAL']); + $scope.modes = LegacyUtils.mkOptions(['PARTITIONED', 'REPLICATED']); $scope.loadingText = this.Demo.enabled ? $translate.instant('queries.notebook.loadingMessageWithDemoEnabled') @@ -1473,7 +1473,7 @@ export class NotebookCtrl { rows.push([row.key, row.value]) } paragraph.rows = rows; - } + } else paragraph.rows = res.rows; diff --git a/web-console/frontend/app/components/web-console-header/components/help-menu/controller.ts b/web-console/frontend/app/components/web-console-header/components/help-menu/controller.ts index fdb2211199a0f..19441019f799b 100644 --- a/web-console/frontend/app/components/web-console-header/components/help-menu/controller.ts +++ b/web-console/frontend/app/components/web-console-header/components/help-menu/controller.ts @@ -9,9 +9,9 @@ export default class HelpMenu { items = [ {text: 'Getting Started', click: '$ctrl.gettingStarted.tryShow(true)'}, - {text: 'Documentation', href: 'https://docs.gridgain.com/docs/web-console', target: '_blank'}, - {text: 'Forums', href: 'https://forums.gridgain.com/home', target: '_blank'}, - {text: 'Support', href: 'https://gridgain.freshdesk.com/support/login', target: '_blank'}, - {text: 'Whitepapers', href: 'https://www.gridgain.com/resources/literature/white-papers?combine=web+console&field_personas_target_id=All', target: '_blank'} + {text: 'Documentation', href: '/docs/web-console', target: '_blank'}, + {text: 'Forums', href: '/forum#ignite', target: '_blank'}, + {text: 'Support', href: '/support/login', target: '_blank'}, + {text: 'Whitepapers', href: '/white-papers?combine=web+console&field_personas_target_id=All', target: '_blank'} ]; } diff --git a/web-console/frontend/app/configuration/components/button-import-models/component.ts b/web-console/frontend/app/configuration/components/button-import-models/component.ts index b3bf15892e5d1..d0f2d2b47bbe1 100644 --- a/web-console/frontend/app/configuration/components/button-import-models/component.ts +++ b/web-console/frontend/app/configuration/components/button-import-models/component.ts @@ -1,5 +1,3 @@ - - import template from './template.pug'; import './style.scss'; import ModalImportModels from '../modal-import-models/service'; diff --git a/web-console/frontend/app/configuration/components/page-configure-advanced/components/cache-edit-form/templates/rebalance.pug b/web-console/frontend/app/configuration/components/page-configure-advanced/components/cache-edit-form/templates/rebalance.pug index 7cf259c905390..ff95b99eeaa31 100644 --- a/web-console/frontend/app/configuration/components/page-configure-advanced/components/cache-edit-form/templates/rebalance.pug +++ b/web-console/frontend/app/configuration/components/page-configure-advanced/components/cache-edit-form/templates/rebalance.pug @@ -8,8 +8,7 @@ include /app/configuration/mixins panel-collapsible( ng-form=form - on-open=`ui.loadPanel('${form}')` - ng-hide=`${model}.cacheMode === "LOCAL"` + on-open=`ui.loadPanel('${form}')` ) panel-title Rebalance panel-description diff --git a/web-console/frontend/app/configuration/components/page-configure-advanced/components/cluster-edit-form/controller.ts b/web-console/frontend/app/configuration/components/page-configure-advanced/components/cluster-edit-form/controller.ts index 62f77a7254454..b5b6a4caee4da 100644 --- a/web-console/frontend/app/configuration/components/page-configure-advanced/components/cluster-edit-form/controller.ts +++ b/web-console/frontend/app/configuration/components/page-configure-advanced/components/cluster-edit-form/controller.ts @@ -110,7 +110,7 @@ export default class ClusterEditFormController { this.$scope.ui.loadedPanels = ['checkpoint', 'serviceConfiguration', 'odbcConfiguration']; this.formActions = [ - {text: 'Save', icon: 'checkmark', click: () => this.save()}, + {text: 'Save', icon: 'checkmark', click: () => this.save(false)}, {text: 'Save and Download', icon: 'download', click: () => this.save(true)} ]; } diff --git a/web-console/frontend/app/configuration/components/page-configure-advanced/components/cluster-edit-form/templates/atomic.pug b/web-console/frontend/app/configuration/components/page-configure-advanced/components/cluster-edit-form/templates/atomic.pug index a7069a12bff1e..00aec5e9ea2b5 100644 --- a/web-console/frontend/app/configuration/components/page-configure-advanced/components/cluster-edit-form/templates/atomic.pug +++ b/web-console/frontend/app/configuration/components/page-configure-advanced/components/cluster-edit-form/templates/atomic.pug @@ -24,7 +24,6 @@ panel-collapsible(ng-form=form on-open=`ui.loadPanel('${form}')`) name: '"cacheMode"', placeholder: 'PARTITIONED', options: '[\ - {value: "LOCAL", label: "LOCAL"},\ {value: "REPLICATED", label: "REPLICATED"},\ {value: "PARTITIONED", label: "PARTITIONED"}\ ]', @@ -32,7 +31,6 @@ panel-collapsible(ng-form=form on-open=`ui.loadPanel('${form}')`) ' }) .pc-form-grid-col-30 diff --git a/web-console/frontend/app/configuration/components/page-configure-advanced/components/cluster-edit-form/templates/discovery.pug b/web-console/frontend/app/configuration/components/page-configure-advanced/components/cluster-edit-form/templates/discovery.pug index 96337c699cd2b..81c6543fe79c3 100644 --- a/web-console/frontend/app/configuration/components/page-configure-advanced/components/cluster-edit-form/templates/discovery.pug +++ b/web-console/frontend/app/configuration/components/page-configure-advanced/components/cluster-edit-form/templates/discovery.pug @@ -6,7 +6,7 @@ include /app/configuration/mixins -var form = 'discovery' -var model = '$ctrl.clonedCluster.discovery' -panel-collapsible(ng-form=form on-open=`ui.loadPanel('${form}')`) +panel-collapsible(ng-form=form on-open=`ui.loadPanel('${form}')` ng-if=`${model}.kind !== 'ZooKeeper'`) panel-title Discovery panel-description | TCP/IP discovery configuration. diff --git a/web-console/frontend/app/configuration/components/page-configure-basic/controller.ts b/web-console/frontend/app/configuration/components/page-configure-basic/controller.ts index 557e410ea40f3..ab982d40c8504 100644 --- a/web-console/frontend/app/configuration/components/page-configure-basic/controller.ts +++ b/web-console/frontend/app/configuration/components/page-configure-basic/controller.ts @@ -156,12 +156,12 @@ export default class PageConfigureBasicController { { text: 'Deploy and ReStart', click: () => this.deploy(true), - icon: 'download' + icon: 'refresh' }, { text: 'Deploy Only', click: () => this.deploy(false), - icon: 'plus' + icon: 'expand' } ]; diff --git a/web-console/frontend/app/configuration/generator/generator/ConfigurationGenerator.js b/web-console/frontend/app/configuration/generator/generator/ConfigurationGenerator.js index 9ba2212e52d84..8c9773f1cbd2c 100644 --- a/web-console/frontend/app/configuration/generator/generator/ConfigurationGenerator.js +++ b/web-console/frontend/app/configuration/generator/generator/ConfigurationGenerator.js @@ -2344,15 +2344,13 @@ export default class IgniteConfigurationGenerator { // Generate cache rebalance group. static cacheRebalance(cache, ccfg = this.cacheConfigurationBean(cache)) { - if (ccfg.valueOf('cacheMode') !== 'LOCAL') { - ccfg.enumProperty('rebalanceMode') - .intProperty('rebalanceBatchSize') - .longProperty('rebalanceBatchesPrefetchCount') - .intProperty('rebalanceOrder') - .longProperty('rebalanceDelay') - .longProperty('rebalanceTimeout') - .longProperty('rebalanceThrottle'); - } + ccfg.enumProperty('rebalanceMode') + .intProperty('rebalanceBatchSize') + .longProperty('rebalanceBatchesPrefetchCount') + .intProperty('rebalanceOrder') + .longProperty('rebalanceDelay') + .longProperty('rebalanceTimeout') + .longProperty('rebalanceThrottle'); return ccfg; } diff --git a/web-console/frontend/app/configuration/generator/generator/Maven.service.js b/web-console/frontend/app/configuration/generator/generator/Maven.service.js index 818528f51ff8a..75e4f0a359f74 100644 --- a/web-console/frontend/app/configuration/generator/generator/Maven.service.js +++ b/web-console/frontend/app/configuration/generator/generator/Maven.service.js @@ -137,10 +137,10 @@ export default class IgniteMavenGenerator { sb.startBlock(''); this.addProperty(sb, 'artifactId', 'maven-compiler-plugin'); - this.addProperty(sb, 'version', '3.1'); + this.addProperty(sb, 'version', '3.6'); sb.startBlock(''); - this.addProperty(sb, 'source', '1.7'); - this.addProperty(sb, 'target', '1.7'); + this.addProperty(sb, 'source', '11'); + this.addProperty(sb, 'target', '11'); sb.endBlock(''); sb.endBlock(''); @@ -169,7 +169,7 @@ export default class IgniteMavenGenerator { const storeDeps = []; this.addDependency(deps, artifactGrp, 'ignite-core', igniteVer); - + this.addDependency(deps, artifactGrp, 'ignite-igfs', igniteVer); this.addDependency(deps, artifactGrp, 'ignite-spring', igniteVer); this.addDependency(deps, artifactGrp, 'ignite-indexing', igniteVer); this.addDependency(deps, artifactGrp, 'ignite-rest-http', igniteVer); diff --git a/web-console/frontend/app/configuration/mixins.pug b/web-console/frontend/app/configuration/mixins.pug index c49311c10ed6f..953460733b019 100644 --- a/web-console/frontend/app/configuration/mixins.pug +++ b/web-console/frontend/app/configuration/mixins.pug @@ -269,7 +269,6 @@ mixin form-field__cache-modes({ label, model, name, placeholder }) +form-field__dropdown({ label, model, name, placeholder, options: '[\ - {value: "LOCAL", label: "LOCAL"},\ {value: "REPLICATED", label: "REPLICATED"},\ {value: "PARTITIONED", label: "PARTITIONED"}\ ]', @@ -277,7 +276,6 @@ mixin form-field__cache-modes({ label, model, name, placeholder }) ' })&attributes(attributes) if block diff --git a/web-console/frontend/app/configuration/services/Caches.ts b/web-console/frontend/app/configuration/services/Caches.ts index 88815923e32ed..3e2345a4c7af3 100644 --- a/web-console/frontend/app/configuration/services/Caches.ts +++ b/web-console/frontend/app/configuration/services/Caches.ts @@ -7,6 +7,10 @@ import uuidv4 from 'uuid/v4'; import {CacheModes, AtomicityModes, ShortCache} from '../types'; import {Menu} from 'app/types'; +const JDBC_LINKS = { + Oracle: 'https://docs.oracle.com/javase/tutorial/jdbc/basics/connecting.html' +} + export default class Caches { static $inject = ['$http']; @@ -208,9 +212,8 @@ export default class Caches { return cache && cache.cacheMode === 'PARTITIONED'; } - jdbcDriverURL(storeFactory) { - this.JDBC_LINKS = {} - return this.JDBC_LINKS[get(storeFactory, 'dialect')]; + jdbcDriverURL(storeFactory) { + return JDBC_LINKS[get(storeFactory, 'dialect')]; } requiresProprietaryDrivers(storeFactory) { diff --git a/web-console/frontend/app/configuration/services/ConfigureState.ts b/web-console/frontend/app/configuration/services/ConfigureState.ts index 3d848f3af2445..f7339a43a787e 100644 --- a/web-console/frontend/app/configuration/services/ConfigureState.ts +++ b/web-console/frontend/app/configuration/services/ConfigureState.ts @@ -5,7 +5,8 @@ import {tap, scan} from 'rxjs/operators'; export default class ConfigureState { actions$: Subject<{type: string}>; - + state$: BehaviorSubject; + _combinedReducer: (state, action) => any; constructor() { this.actions$ = new Subject(); this.state$ = new BehaviorSubject({}); diff --git a/web-console/frontend/app/configuration/services/Models.ts b/web-console/frontend/app/configuration/services/Models.ts index b23bf0706ead3..b5cd2ee71c871 100644 --- a/web-console/frontend/app/configuration/services/Models.ts +++ b/web-console/frontend/app/configuration/services/Models.ts @@ -1,5 +1,3 @@ - - import omit from 'lodash/fp/omit'; import uuidv4 from 'uuid/v4'; @@ -109,7 +107,9 @@ ${scale && entity.precision && entity.scale ? ',' + entity.scale : ''}${precisio id: uuidv4(), name: '', indexType: 'SORTED', - fields: [] + fields: [], + inlineSize: null, + inlineSizeType: -1 }); return model.indexes[model.indexes.length - 1]; diff --git a/web-console/frontend/app/configuration/states.ts b/web-console/frontend/app/configuration/states.ts index 3c40d69cc7a7f..f7b0f69a5d451 100644 --- a/web-console/frontend/app/configuration/states.ts +++ b/web-console/frontend/app/configuration/states.ts @@ -23,6 +23,21 @@ const shortCachesResolve = ['ConfigSelectors', 'ConfigureState', 'ConfigEffects' .toPromise(); }]; +const shortCachesAndModels = ['ConfigSelectors', 'ConfigureState', 'ConfigEffects', '$transition$', (ConfigSelectors, ConfigureState, {etp}, $transition$) => { + if ($transition$.params().clusterID === 'new') + return Promise.resolve(); + + return from($transition$.injector().getAsync('_cluster')).pipe( + switchMap(() => ConfigureState.state$.pipe(ConfigSelectors.selectCluster($transition$.params().clusterID), take(1))), + map((cluster) => { + return Promise.all([ + etp('LOAD_SHORT_CACHES', {ids: cluster.caches, clusterID: cluster.id}), + etp('LOAD_SHORT_MODELS', {ids: cluster.models, clusterID: cluster.id}) + ]); + }) + ).toPromise(); +}] + function registerStates($stateProvider) { // Setup the states. $stateProvider @@ -124,21 +139,7 @@ function registerStates($stateProvider) { permission: 'configuration', component: pageConfigureAdvancedCachesComponent.name, resolve: { - _shortCachesAndModels: ['ConfigSelectors', 'ConfigureState', 'ConfigEffects', '$transition$', (ConfigSelectors, ConfigureState, {etp}, $transition$) => { - if ($transition$.params().clusterID === 'new') - return Promise.resolve(); - - return from($transition$.injector().getAsync('_cluster')).pipe( - switchMap(() => ConfigureState.state$.pipe(ConfigSelectors.selectCluster($transition$.params().clusterID), take(1))), - map((cluster) => { - return Promise.all([ - etp('LOAD_SHORT_CACHES', {ids: cluster.caches, clusterID: cluster.id}), - etp('LOAD_SHORT_MODELS', {ids: cluster.models, clusterID: cluster.id}) - ]); - }) - ) - .toPromise(); - }] + _shortCachesAndModels: shortCachesAndModels }, resolvePolicy: { async: 'NOWAIT' @@ -175,20 +176,7 @@ function registerStates($stateProvider) { component: pageConfigureAdvancedModelsComponent.name, permission: 'configuration', resolve: { - _shortCachesAndModels: ['ConfigSelectors', 'ConfigureState', 'ConfigEffects', '$transition$', (ConfigSelectors, ConfigureState, {etp}, $transition$) => { - if ($transition$.params().clusterID === 'new') - return Promise.resolve(); - - return from($transition$.injector().getAsync('_cluster')).pipe( - switchMap(() => ConfigureState.state$.pipe(ConfigSelectors.selectCluster($transition$.params().clusterID), take(1))), - map((cluster) => { - return Promise.all([ - etp('LOAD_SHORT_CACHES', {ids: cluster.caches, clusterID: cluster.id}), - etp('LOAD_SHORT_MODELS', {ids: cluster.models, clusterID: cluster.id}) - ]); - }) - ).toPromise(); - }] + _shortCachesAndModels: shortCachesAndModels }, resolvePolicy: { async: 'NOWAIT' diff --git a/web-console/frontend/app/console/components/page-configure-advanced/components/cache-meric-form/templates/schedule.pug b/web-console/frontend/app/console/components/page-configure-advanced/components/cache-meric-form/templates/schedule.pug index d0a0e6b42c5c9..e152087973588 100644 --- a/web-console/frontend/app/console/components/page-configure-advanced/components/cache-meric-form/templates/schedule.pug +++ b/web-console/frontend/app/console/components/page-configure-advanced/components/cache-meric-form/templates/schedule.pug @@ -1,5 +1,3 @@ - - include /app/helpers/jade/mixins include /app/configuration/mixins @@ -8,8 +6,7 @@ include /app/configuration/mixins panel-collapsible( ng-form=form - on-open=`ui.loadPanel('${form}')` - ng-hide=`${model}.cacheMode === "LOCAL"` + on-open=`ui.loadPanel('${form}')` ) panel-title 调度配置 panel-description diff --git a/web-console/frontend/app/console/components/page-configure-advanced/components/cluster-control-overview/controller.ts b/web-console/frontend/app/console/components/page-configure-advanced/components/cluster-control-overview/controller.ts index 222e60fa7421a..9729c05c3839b 100644 --- a/web-console/frontend/app/console/components/page-configure-advanced/components/cluster-control-overview/controller.ts +++ b/web-console/frontend/app/console/components/page-configure-advanced/components/cluster-control-overview/controller.ts @@ -168,18 +168,13 @@ export default class ClusterControlController { callCommand(cmdName: string, args) { let clusterID = this.clusterID; return new Promise((resolve,reject) => { - this.AgentManager.callClusterCommand({id:clusterID},cmdName,args).then((data) => { - - if(data.result){ - resolve(data); - } - else if(data.message){ - this.message = data.message; - resolve(data) - } + this.AgentManager.callClusterCommand({id:clusterID},cmdName,args).then((data) => { + if(data.message){ + this.message = data.message; + } + resolve(data) }) - .catch((e) => { - //this.$scope.message = ('Failed to callClusterService : '+serviceName+' Caused : '+e); + .catch((e) => { reject(e) }); }); @@ -206,8 +201,7 @@ export default class ClusterControlController { this.message = data.message; } }) - .catch((e) => { - //this.$scope.message = ('Failed to callClusterService : '+serviceName+' Caused : '+e); + .catch((e) => { reject(e) }); }); diff --git a/web-console/frontend/app/console/components/page-configure-advanced/components/cluster-taskflow-overview/components/taskflow-edit-form/controller.ts b/web-console/frontend/app/console/components/page-configure-advanced/components/cluster-taskflow-overview/components/taskflow-edit-form/controller.ts index 7a56bb93856c9..6c984a38d4503 100644 --- a/web-console/frontend/app/console/components/page-configure-advanced/components/cluster-taskflow-overview/components/taskflow-edit-form/controller.ts +++ b/web-console/frontend/app/console/components/page-configure-advanced/components/cluster-taskflow-overview/components/taskflow-edit-form/controller.ts @@ -81,7 +81,7 @@ export default class TaskFlowFormController { this.formActions = [ {text: 'Save TaskFlow', icon: 'checkmark', click: () => this.confirmAndSave()}, - {text: 'Start TaskFlow', icon: 'checkmark', click: () => this.confirmAndStart()} + {text: 'Start TaskFlow', icon: 'copy', click: () => this.confirmAndStart()} ]; } @@ -102,7 +102,7 @@ export default class TaskFlowFormController { this.taskFlow = Object.assign({},tplFlow); this.taskFlow.target = cache.name; this.taskFlow.source = cache.name; - this.taskFlow.name = 'Data from '+this.targetCluster.name+'.'+this.taskFlow.source+' to '+cache.name; + this.taskFlow.name = tplFlow.name +' to '+cache.name; taskList.push(this.taskFlow); } return taskList; @@ -170,15 +170,15 @@ export default class TaskFlowFormController { result.push(stat); } if(result){ - this.AgentManager.callClusterService({id: tplFlow.sourceCluster},serviceName,{tasks,task,models:this.models}).then((data) => { - this.$scope.status = data.status; - if(data.result){ - return data.result; - } - else if(data.message){ - this.$scope.message = data.message; - } - return {} + this.AgentManager.callClusterService({id: tplFlow.targetCluster},serviceName,{tasks,task,models:this.models}).then((data) => { + this.$scope.status = data.status; + if(data.message){ + this.$scope.message = data.message; + } + if(data.result){ + return data.result; + } + return {} }) .catch((e) => { this.$scope.message = ('Failed to callClusterService : '+serviceName+' Caused : '+e); diff --git a/web-console/frontend/app/console/components/page-configure-advanced/components/model-meric-form/controller.ts b/web-console/frontend/app/console/components/page-configure-advanced/components/model-meric-form/controller.ts index 6b2723ccf1c09..2375f9051faf4 100644 --- a/web-console/frontend/app/console/components/page-configure-advanced/components/model-meric-form/controller.ts +++ b/web-console/frontend/app/console/components/page-configure-advanced/components/model-meric-form/controller.ts @@ -42,7 +42,7 @@ export default class ModelEditFormController { this.$scope.supportedJavaTypes = this.LegacyUtils.mkOptions(this.LegacyUtils.javaBuiltInTypes); this.formActions = [ - {text: 'Save', icon: 'checkmark', click: () => this.save()}, + {text: 'Save', icon: 'checkmark', click: () => this.save(false)}, {text: 'Save and Download', icon: 'download', click: () => this.save(true)} ]; } diff --git a/web-console/frontend/app/console/components/page-configure-advanced/components/page-configure-advanced-caches/controller.ts b/web-console/frontend/app/console/components/page-configure-advanced/components/page-configure-advanced-caches/controller.ts index 3b99f7ff842b7..6bcd8a952ad93 100644 --- a/web-console/frontend/app/console/components/page-configure-advanced/components/page-configure-advanced-caches/controller.ts +++ b/web-console/frontend/app/console/components/page-configure-advanced/components/page-configure-advanced-caches/controller.ts @@ -185,6 +185,6 @@ export default class Controller { } save({cache, download}) { - //this.ConfigureState.dispatchAction(advancedSaveCache(cache, download)); + // this.ConfigureState.dispatchAction(advancedSaveCache(cache, download)); } } diff --git a/web-console/frontend/app/console/components/page-configure-basic/controller.ts b/web-console/frontend/app/console/components/page-configure-basic/controller.ts index 1f77a81380156..6cd73c10a7b7a 100644 --- a/web-console/frontend/app/console/components/page-configure-basic/controller.ts +++ b/web-console/frontend/app/console/components/page-configure-basic/controller.ts @@ -153,35 +153,39 @@ export default class PageConfigureBasicController { } buildFormActionsMenu(){ - let formActionsMenu = [];//this.$scope.formActionsMenu; - //this.$scope.formActionsMenu.length = 0; + let formActionsMenu = []; - if(this.$scope.status && this.$scope.status!="started"){ - formActionsMenu.push({ - text: 'Start Cluster', - click: () => this.confirmAndRestart(), - icon: 'checkmark' - }) - } - else { - formActionsMenu.push({ - text: 'Stop Cluster', - click: () => this.confirmAndStop(), - icon: 'download' - }); - formActionsMenu.push({ - text: 'Restart Cluster', - click: () => this.confirmAndRestart(), - icon: 'checkmark' - }) - } - this.$scope.formActionsMenu = formActionsMenu; - return formActionsMenu; + if(this.$scope.status && this.$scope.status!="started"){ + formActionsMenu.push({ + text: 'Start Cluster', + click: () => this.confirmAndStart(), + icon: 'checkmark' + }) + } + else { + formActionsMenu.push({ + text: 'Start Cluster', + click: () => this.confirmAndStart(), + icon: 'checkmark' + }); + formActionsMenu.push({ + text: 'Stop Cluster', + click: () => this.confirmAndStop(), + icon: 'exit' + }); + formActionsMenu.push({ + text: 'Restart Cluster', + click: () => this.confirmAndRestart(), + icon: 'refresh' + }) + } + this.$scope.formActionsMenu = formActionsMenu; + return formActionsMenu; } - restart() { - this.clonedCluster['restart'] = true; + start(restart:boolean) { + this.clonedCluster['restart'] = restart; this.AgentManager.startCluster(this.clonedCluster).then((msg) => { if(!msg.message){ this.$scope.status = msg.status; @@ -212,12 +216,12 @@ export default class PageConfigureBasicController { this.$scope.status = data.status; this.buildFormActionsMenu(); this.clonedCluster.status = data.status; + if(data.message){ + this.$scope.message = data.message; + } if(data.result){ return data.result; - } - else if(data.message){ - this.$scope.message = data.message; - } + } return {} }) .catch((e) => { @@ -236,9 +240,14 @@ export default class PageConfigureBasicController { .then(() => this.reset()) .catch(() => {}); } + confirmAndStart() { + return this.Confirm.confirm('Are you sure you want to start current cluster? Current status:' + this.clonedCluster.status) + .then(() => this.start(false)) + .catch(() => {}); + } confirmAndRestart() { return this.Confirm.confirm('Are you sure you want to restart current cluster? Current status:' + this.clonedCluster.status) - .then(() => this.restart()) + .then(() => this.start(true)) .catch(() => {}); } confirmAndStop() { diff --git a/web-console/frontend/app/console/components/page-console-cache-service/components/cache-service-call-form/component.js b/web-console/frontend/app/console/components/page-console-cache-service/components/cache-service-call-form/component.js index ca9e1f97cec10..9a3cc1681dfd3 100644 --- a/web-console/frontend/app/console/components/page-console-cache-service/components/cache-service-call-form/component.js +++ b/web-console/frontend/app/console/components/page-console-cache-service/components/cache-service-call-form/component.js @@ -9,7 +9,8 @@ export default { bindings: { cache: '<', caches: '<', - services: '=', + models: '<', + services: '<', onCall: '&' } }; \ No newline at end of file diff --git a/web-console/frontend/app/console/components/page-console-cache-service/components/cache-service-call-form/controller.ts b/web-console/frontend/app/console/components/page-console-cache-service/components/cache-service-call-form/controller.ts index fe5fe45e204ed..0ad4ef8b38f39 100644 --- a/web-console/frontend/app/console/components/page-console-cache-service/components/cache-service-call-form/controller.ts +++ b/web-console/frontend/app/console/components/page-console-cache-service/components/cache-service-call-form/controller.ts @@ -36,29 +36,9 @@ export default class CacheServiceCallFormController { this.$scope.ui = this.IgniteFormUtils.formUI(); this.$scope.formActions = [ - {text: 'Choose Service:', icon: 'plus', click: () => this.updateServices({})}, - ]; - - this.formActions$ = this.services.pipe( - filter((v) => v.length>0), - map((services) => { - let formActions = [ {text: 'Choose Service:', icon: 'plus', click: () => this.updateServices({})}]; - for(let service of services){ - let action = { - text: service.description, - icon: 'checkmark', - click: () => this.confirmAndCall(service) - }; - formActions.push(action); - } - return formActions; - }) - ); - - this.formActions$.subscribe((formActions)=>{ - this.$scope.formActions = formActions; - }); - + {text: 'Choose Service:', icon: 'plus', click: () => this.updateServices()}, + ]; + setTimeout(() => this.updateServices(), 2000); } $onDestroy() { @@ -89,25 +69,39 @@ export default class CacheServiceCallFormController { let args = this.onCall({$event: {cache: this.clonedCache}}); let clusterId = args['id']; params = Object.assign(args,params); - this.AgentManager.callClusterService({id: clusterId},serviceName,params).then((data) => { - this.$scope.status = data.status; + this.AgentManager.callCacheService({id: clusterId},serviceName,params).then((data) => { + this.$scope.status = data.status; + if(data.message){ + this.$scope.message = data.message; + } if(data.result){ return data.result; - } - else if(data.message){ - this.$scope.message = data.message; - } + } return {} }) .catch((e) => { - this.$scope.message = ('Failed to callClusterService : '+serviceName+' Caused : '+e); + this.$scope.message = ('Failed to callClusterService : '+serviceName+' Caused : '+e); }); } reset = (forReal) => forReal ? this.clonedCache = cloneDeep(this.cache) : void 0; - updateServices(){ - + updateServices(){ + if(this.services){ + let formActions = [] + for(let service of this.services){ + let action = { + text: service.description, + icon: 'checkmark', + click: () => this.confirmAndCall(service) + }; + formActions.push(action); + } + this.$scope.formActions = formActions; + } + else{ + setTimeout(() => this.updateServices(), 2000); + } } confirmAndCall(service) { diff --git a/web-console/frontend/app/console/components/page-console-cache-service/controller.ts b/web-console/frontend/app/console/components/page-console-cache-service/controller.ts index 3eef50162a25f..353dc9faa4f95 100644 --- a/web-console/frontend/app/console/components/page-console-cache-service/controller.ts +++ b/web-console/frontend/app/console/components/page-console-cache-service/controller.ts @@ -7,6 +7,7 @@ import naturalCompare from 'natural-compare-lite'; import {removeClusterItems, advancedSaveCache} from '../../../configuration/store/actionCreators'; import ConfigureState from '../../../configuration/services/ConfigureState'; import ConfigSelectors from '../../../configuration/store/selectors'; +import {default as MessagesFactory} from '../../../services/Messages.service'; import Caches from '../../../configuration/services/Caches'; import Services from '../../services/Services'; import Version from 'app/services/Version.service'; @@ -18,6 +19,7 @@ export default class CacheServiceController { static $inject = [ 'ConfigSelectors', 'configSelectionManager', + 'IgniteMessages', '$uiRouter', '$transitions', 'ConfigureState', @@ -31,6 +33,7 @@ export default class CacheServiceController { constructor( private ConfigSelectors, private configSelectionManager, + private messages: ReturnType, private $uiRouter: UIRouter, private $transitions: TransitionService, private ConfigureState: ConfigureState, @@ -103,7 +106,7 @@ export default class CacheServiceController { clusterID$.subscribe((v)=>{ this.clusterID = v; - this.callService('serviceList',{}).then((data) => { + this.callService('serviceList',{type:'CacheAgentService'}).then((data) => { if(data.message){ this.message = data.message; return; @@ -117,7 +120,7 @@ export default class CacheServiceController { }); this.shortCaches$ = this.ConfigureState.state$.pipe(this.ConfigSelectors.selectCurrentShortCaches); - + this.shortModels$ = this.ConfigureState.state$.pipe(this.ConfigSelectors.selectCurrentShortModels); this.originalCache$ = cacheID$.pipe( distinctUntilChanged(), switchMap((id) => { @@ -201,18 +204,14 @@ export default class CacheServiceController { callService(serviceName: string, args) { let clusterID = this.clusterID; return new Promise((resolve,reject) => { - this.AgentManager.callClusterService({id:clusterID,type:'CacheAgentService'},serviceName,args).then((data) => { - - if(data.result){ - resolve(data); - } - else if(data.message){ - this.message = data.message; - resolve(data) - } + this.AgentManager.callCacheService({id:clusterID},serviceName,args).then((data) => { + if(data.message){ + this.messages.showInfo(data.message); + } + resolve(data); }) .catch((e) => { - //this.$scope.message = ('Failed to callClusterService : '+serviceName+' Caused : '+e); + this.messages.showError('Failed to callClusterService : '+serviceName+' Caused : '+e); reject(e) }); }); diff --git a/web-console/frontend/app/console/components/page-console-cache-service/template.pug b/web-console/frontend/app/console/components/page-console-cache-service/template.pug index a3b33317442ae..ea3538f938299 100644 --- a/web-console/frontend/app/console/components/page-console-cache-service/template.pug +++ b/web-console/frontend/app/console/components/page-console-cache-service/template.pug @@ -21,7 +21,8 @@ h2.pc-page-header.ng-animate-disabled(ng-if='$ctrl.isBlocked$|async:this') cache-service-call-form( cache='$ctrl.originalCache$|async:this' caches='$ctrl.selectedRows$|async:this' - services='$ctrl.serviceList$' + models='$ctrl.shortModels$|async:this' + services='$ctrl.serviceList' on-call='$ctrl.onCall($event)' ng-class='{"pca-form-blocked": !($ctrl.isBlocked$|async:this)}' diff --git a/web-console/frontend/app/console/components/page-console-service/components/service-call-form/controller.ts b/web-console/frontend/app/console/components/page-console-service/components/service-call-form/controller.ts index 8607303fe0982..ba062faef961f 100644 --- a/web-console/frontend/app/console/components/page-console-service/components/service-call-form/controller.ts +++ b/web-console/frontend/app/console/components/page-console-service/components/service-call-form/controller.ts @@ -65,7 +65,7 @@ export default class ServiceCallFormController { redeployService(force:boolean) { let serviceName = 'redeployService'; - return this.callServiceForCache(serviceName,{force}); + return this.callServiceForGrid(serviceName,{force}); } @@ -75,12 +75,12 @@ export default class ServiceCallFormController { params = Object.assign(args,params); this.AgentManager.callClusterService({id: clusterId},serviceName,params).then((data) => { this.$scope.status = data.status; + if(data.message){ + this.$scope.message = data.message; + } if(data.result){ return data.result; - } - else if(data.message){ - this.$scope.message = data.message; - } + } return {} }) .catch((e) => { diff --git a/web-console/frontend/app/console/components/page-console-service/controller.ts b/web-console/frontend/app/console/components/page-console-service/controller.ts index 180d179fb0773..8c2f8fa09a695 100644 --- a/web-console/frontend/app/console/components/page-console-service/controller.ts +++ b/web-console/frontend/app/console/components/page-console-service/controller.ts @@ -7,6 +7,7 @@ import naturalCompare from 'natural-compare-lite'; import {removeClusterItems, advancedSaveCache} from '../../../configuration/store/actionCreators'; import ConfigureState from '../../../configuration/services/ConfigureState'; import ConfigSelectors from '../../../configuration/store/selectors'; +import {default as MessagesFactory} from '../../../services/Messages.service'; import Caches from '../../../configuration/services/Caches'; import Services from '../../services/Services'; import Version from 'app/services/Version.service'; @@ -18,6 +19,7 @@ export default class ServiceController { static $inject = [ 'ConfigSelectors', 'configSelectionManager', + 'IgniteMessages', '$uiRouter', '$transitions', 'ConfigureState', @@ -31,6 +33,7 @@ export default class ServiceController { constructor( private ConfigSelectors, private configSelectionManager, + private messages: ReturnType, private $uiRouter: UIRouter, private $transitions: TransitionService, private ConfigureState: ConfigureState, @@ -132,7 +135,7 @@ export default class ServiceController { //this.serviceListSubject$.next(this.serviceList); this.clusterID = await clusterID$.toPromise(); - this.serviceList$ = from(this.callServiceList()); + this.serviceList$ = from(this.callServiceList('ClusterAgentService')); this.originalService$ = serviceID$.pipe( @@ -164,8 +167,7 @@ export default class ServiceController { this.isBlocked$ = serviceID$; - this.tableActions$ = this.selectionManager.selectedItemIDs$.pipe(map((selectedItems) => [ - + this.tableActions$ = this.selectionManager.selectedItemIDs$.pipe(map((selectedItems) => [ { action: 'Redeploy', click: () => { @@ -181,15 +183,9 @@ export default class ServiceController { available: true }, { - action: 'Simple Call', + action: 'Cancel', click: () => { - for(let serviceName of selectedItems){ - this.callService(serviceName,{}).then((data) => { - if(data.message){ - this.message = data.message; - } - }); - } + this.call(selectedItems,'cancelService'); }, available: true } @@ -214,27 +210,27 @@ export default class ServiceController { let clusterID = this.clusterID; return new Promise((resolve,reject) => { this.AgentManager.callClusterService({id:clusterID},serviceName,args).then((data) => { - - if(data.result){ - resolve(data); - } - else if(data.message){ + if(data.message){ this.message = data.message; - resolve(data) - } + this.messages.showInfo(data.message); + } + reject(data); }) .catch((e) => { - //this.$scope.message = ('Failed to callClusterService : '+serviceName+' Caused : '+e); - reject(e) + this.messages.showError('Failed to callClusterService : '+serviceName+' Caused : '+e); + reject(e); }); }); } - callServiceList() { + callServiceList(type) { let clusterID = this.clusterID; return new Promise((resolve,reject) => { - this.AgentManager.callClusterService({id:clusterID},'serviceList').then((data) => { + this.AgentManager.callClusterService({id:clusterID},'serviceList',{type:type}).then((data) => { + if(data.message){ + this.message = data.message; + } if(data.result){ let serviceList = []; let serviceMap = Object.assign(data.result); @@ -244,13 +240,12 @@ export default class ServiceController { }); this.serviceMap = serviceMap; resolve(serviceList); - } - else if(data.message){ - this.message = data.message; - } + } + else{ + reject(data) + } }) - .catch((e) => { - //this.$scope.message = ('Failed to callClusterService : '+serviceName+' Caused : '+e); + .catch((e) => { reject(e) }); }); diff --git a/web-console/frontend/app/console/states.ts b/web-console/frontend/app/console/states.ts index 3e3c9ce849ded..d01e0239631ea 100644 --- a/web-console/frontend/app/console/states.ts +++ b/web-console/frontend/app/console/states.ts @@ -23,6 +23,21 @@ const shortCachesResolve = ['ConfigSelectors', 'ConfigureState', 'ConfigEffects' .toPromise(); }]; +const shortCachesAndModels = ['ConfigSelectors', 'ConfigureState', 'ConfigEffects', '$transition$', (ConfigSelectors, ConfigureState, {etp}, $transition$) => { + if ($transition$.params().clusterID === 'new') + return Promise.resolve(); + + return from($transition$.injector().getAsync('_cluster')).pipe( + switchMap(() => ConfigureState.state$.pipe(ConfigSelectors.selectCluster($transition$.params().clusterID), take(1))), + map((cluster) => { + return Promise.all([ + etp('LOAD_SHORT_CACHES', {ids: cluster.caches, clusterID: cluster.id}), + etp('LOAD_SHORT_MODELS', {ids: cluster.models, clusterID: cluster.id}) + ]); + }) + ).toPromise(); +}] + function registerStates($stateProvider) { // Setup the states. $stateProvider @@ -102,7 +117,7 @@ function registerStates($stateProvider) { component: 'pageConsoleService', permission: 'configuration', resolve: { - _shortCaches: shortCachesResolve + _shortCachesAndModels: shortCachesAndModels, }, resolvePolicy: { async: 'NOWAIT' @@ -116,7 +131,7 @@ function registerStates($stateProvider) { component: 'pageConsoleCacheService', permission: 'configuration', resolve: { - _shortCaches: shortCachesResolve + _shortCachesAndModels: shortCachesAndModels, }, resolvePolicy: { async: 'NOWAIT' @@ -128,7 +143,7 @@ function registerStates($stateProvider) { .state('base.console.edit.service.select', { url: `/{serviceID}`, permission: 'configuration', - resolve: { + resolve: { }, data: { errorState: 'base.console.edit.service' @@ -204,21 +219,7 @@ function registerStates($stateProvider) { permission: 'configuration', component: pageConsoleAdvancedCachesComponent.name, resolve: { - _shortCachesAndModels: ['ConfigSelectors', 'ConfigureState', 'ConfigEffects', '$transition$', (ConfigSelectors, ConfigureState, {etp}, $transition$) => { - if ($transition$.params().clusterID === 'new') - return Promise.resolve(); - - return from($transition$.injector().getAsync('_cluster')).pipe( - switchMap(() => ConfigureState.state$.pipe(ConfigSelectors.selectCluster($transition$.params().clusterID), take(1))), - map((cluster) => { - return Promise.all([ - etp('LOAD_SHORT_CACHES', {ids: cluster.caches, clusterID: cluster.id}), - etp('LOAD_SHORT_MODELS', {ids: cluster.models, clusterID: cluster.id}) - ]); - }) - ) - .toPromise(); - }] + _shortCachesAndModels: shortCachesAndModels }, resolvePolicy: { async: 'NOWAIT' @@ -255,20 +256,7 @@ function registerStates($stateProvider) { component: pageConsoleAdvancedModelsComponent.name, permission: 'configuration', resolve: { - _shortCachesAndModels: ['ConfigSelectors', 'ConfigureState', 'ConfigEffects', '$transition$', (ConfigSelectors, ConfigureState, {etp}, $transition$) => { - if ($transition$.params().clusterID === 'new') - return Promise.resolve(); - - return from($transition$.injector().getAsync('_cluster')).pipe( - switchMap(() => ConfigureState.state$.pipe(ConfigSelectors.selectCluster($transition$.params().clusterID), take(1))), - map((cluster) => { - return Promise.all([ - etp('LOAD_SHORT_CACHES', {ids: cluster.caches, clusterID: cluster.id}), - etp('LOAD_SHORT_MODELS', {ids: cluster.models, clusterID: cluster.id}) - ]); - }) - ).toPromise(); - }] + _shortCachesAndModels: shortCachesAndModels }, resolvePolicy: { async: 'NOWAIT' diff --git a/web-console/frontend/app/datasource/components/page-datasource-basic/controller.ts b/web-console/frontend/app/datasource/components/page-datasource-basic/controller.ts index 2621f5f6599c2..109deb814a86b 100644 --- a/web-console/frontend/app/datasource/components/page-datasource-basic/controller.ts +++ b/web-console/frontend/app/datasource/components/page-datasource-basic/controller.ts @@ -191,7 +191,7 @@ export default class PageDatasourceBasicController { datasource.db = foundPreset.db this.AgentManager.callClusterService(datasource,'datasourceTest',datasource).then((msg) => { if(msg.status){ - datasource.status = msg.status; + datasource.status = msg.status; this.$scope.status = msg.status; this.$scope.message = msg.message; } @@ -202,7 +202,7 @@ export default class PageDatasourceBasicController { let datasource = this.clonedCluster; this.AgentManager.callClusterService(datasource,'datasourceDisconnect').then((msg) => { if(msg.status){ - datasource.status = msg.status; + datasource.status = msg.status; this.$scope.status = msg.status; this.$scope.message = msg.message; } diff --git a/web-console/frontend/app/datasource/components/page-datasource-overview/controller.ts b/web-console/frontend/app/datasource/components/page-datasource-overview/controller.ts index b86bb3825493b..55f3713bd3abb 100644 --- a/web-console/frontend/app/datasource/components/page-datasource-overview/controller.ts +++ b/web-console/frontend/app/datasource/components/page-datasource-overview/controller.ts @@ -127,8 +127,7 @@ export default class PageDatasourceOverviewController { } } - $onInit() { - + $onInit() { this.dataSourceList$ = from(this.Datasource.getDatasourceList()).pipe( switchMap(({data}) => of( data diff --git a/web-console/frontend/app/modules/agent/AgentManager.service.ts b/web-console/frontend/app/modules/agent/AgentManager.service.ts index d48ef2355c3e0..a08604c3ec1e0 100644 --- a/web-console/frontend/app/modules/agent/AgentManager.service.ts +++ b/web-console/frontend/app/modules/agent/AgentManager.service.ts @@ -179,7 +179,7 @@ export default class AgentManager { pool = new SimpleWorkerPool('decompressor', Worker, 4); - promises = new Set>(); + promises = new Set>(); /** Websocket */ ws = null; @@ -499,6 +499,10 @@ export default class AgentManager { callClusterService(cluster,serviceName,payload) { return this._sendToAgent('agent:callClusterService',{id:cluster.id,name:cluster.name,serviceName:serviceName,args:payload}); } + + callCacheService(cluster,serviceName,payload) { + return this._sendToAgent('agent:callClusterService',{id:cluster.id,name:cluster.name,serviceName:serviceName,serviceType:'CacheAgentService',args:payload}); + } callClusterCommand(cluster,cmdName,payload) { return this._sendToAgent('agent:callClusterCommand',{id:cluster.id,name:cluster.name,cmdName:cmdName,args:payload}); @@ -559,6 +563,10 @@ export default class AgentManager { const now = Date.now() return this._restOnCluster(event, params) .then((res) => { + if (typeof res === 'boolean') { + return res + } + // add@byron if('result' in res){ return res.result } diff --git a/web-console/frontend/app/services/Version.service.ts b/web-console/frontend/app/services/Version.service.ts index 03eba614f8ad5..1a6092f6e6d04 100644 --- a/web-console/frontend/app/services/Version.service.ts +++ b/web-console/frontend/app/services/Version.service.ts @@ -32,7 +32,7 @@ export default class IgniteVersion { this.supportedVersions = [ { label: 'Ignite 2.15+', - ignite: '2.15.0' + ignite: '2.16.999' }, { label: 'Ignite 2.9+', diff --git a/web-console/frontend/app/vendor.js b/web-console/frontend/app/vendor.js index 333959ce874da..3c8a46fc2a68d 100644 --- a/web-console/frontend/app/vendor.js +++ b/web-console/frontend/app/vendor.js @@ -28,6 +28,7 @@ import 'brace'; import 'brace/mode/xml'; import 'brace/mode/sql'; import 'brace/mode/java'; +import 'brace/mode/groovy'; import 'brace/mode/csharp'; import 'brace/mode/dockerfile'; import 'brace/mode/snippets'; diff --git a/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/AgentConfiguration.java b/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/AgentConfiguration.java index 3e28adc15a2cc..860cd6eae6a40 100644 --- a/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/AgentConfiguration.java +++ b/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/AgentConfiguration.java @@ -27,6 +27,8 @@ import java.util.List; import java.util.Properties; import com.beust.jcommander.Parameter; + +import org.apache.ignite.console.utils.BeanMerger; import org.apache.ignite.internal.util.typedef.F; import org.apache.ignite.plugin.PluginConfiguration; @@ -45,9 +47,8 @@ public class AgentConfiguration implements PluginConfiguration { private static final String DFLT_SERVER_URI = "http://localhost:3000"; /** Default Ignite node HTTP URI. */ - private static final String DFLT_NODE_URI = "http://localhost:8080"; - - private static final String DFLT_ZOOKEEPER_URI = "127.0.0.1:2181"; + private static final String DFLT_NODE_URI = "http://localhost:8080"; + /** */ @Parameter(names = {"-t", "--tokens"}, @@ -78,10 +79,10 @@ public class AgentConfiguration implements PluginConfiguration { description = "Password that will be used to connect to secured cluster") private String nodePwd; - /** zookeeper connect string */ - @Parameter(names = {"-zk", "--zookeeper-uri"}, - description = "Password that will be used to connect to secured cluster") - private String zookeeper = DFLT_ZOOKEEPER_URI; + /** agent ident no */ + @Parameter(names = {"-id", "--server-id"}, + description = "Server Ident that will be used to ident node for cluster") + private int serverId = 0; /** URI for connect to Ignite demo node REST server */ @@ -508,12 +509,12 @@ public List cipherSuites() { return cipherSuites; } - public String zookeeper() { - return zookeeper; + public int serverId() { + return serverId; } - public void zookeeper(String zookeeper) { - this.zookeeper = zookeeper; + public void serverId(int serverId) { + this.serverId = serverId; } /** @@ -577,9 +578,9 @@ public void load(URL cfgUrl) throws IOException { if (val != null) nodePassword(val); - val = props.getProperty("zookeeper-uri"); + val = props.getProperty("server-id"); if (val != null) - zookeeper(val); + serverId(Integer.parseInt(val)); val = props.getProperty("driver-folder"); @@ -655,71 +656,8 @@ public void load(URL cfgUrl) throws IOException { /** * @param cfg Config to merge with. */ - public void merge(AgentConfiguration cfg) { - if (tokens == null) - tokens(cfg.tokens()); - - if (srvUri == null) - serverUri(cfg.serverUri()); - - if (srvUri == null) - serverUri(DFLT_SERVER_URI); - - if (nodeURIs == null) - nodeURIs(cfg.nodeURIs()); - - if (nodeURIs == null) - nodeURIs(Collections.singletonList(DFLT_NODE_URI)); - - if (nodeLogin == null) - nodeLogin(cfg.nodeLogin()); - - if (nodePwd == null) - nodePassword(cfg.nodePassword()); - - if (driversFolder == null) - driversFolder(cfg.driversFolder()); - - disableDemo(disableDemo || cfg.disableDemo()); - - disableVertx(disableVertx || cfg.disableVertx()); - - if (nodeKeyStore == null) - nodeKeyStore(cfg.nodeKeyStore()); - - if (nodeKeyStorePass == null) - nodeKeyStorePassword(cfg.nodeKeyStorePassword()); - - if (nodeTrustStore == null) - nodeTrustStore(cfg.nodeTrustStore()); - - if (nodeTrustStorePass == null) - nodeTrustStorePassword(cfg.nodeTrustStorePassword()); - - if (srvKeyStore == null) - serverKeyStore(cfg.serverKeyStore()); - - if (srvKeyStorePass == null) - serverKeyStorePassword(cfg.serverKeyStorePassword()); - - if (srvTrustStore == null) - serverTrustStore(cfg.serverTrustStore()); - - if (srvTrustStorePass == null) - serverTrustStorePassword(cfg.serverTrustStorePassword()); - - if (passwordsStore == null) - passwordsStore(cfg.passwordsStore()); - - if (passwordsStorePass == null) - passwordsStorePassword(cfg.passwordsStorePassword()); - - if (cipherSuites == null) - cipherSuites(cfg.cipherSuites()); - - tokens = trim(tokens); - nodeURIs = trim(nodeURIs); - cipherSuites = trim(cipherSuites); + public void merge(AgentConfiguration cfg) { + BeanMerger.mergeBeans(cfg,this); } diff --git a/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/AgentLauncher.java b/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/AgentLauncher.java index 11f29ebe59243..8da2f989982ee 100644 --- a/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/AgentLauncher.java +++ b/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/AgentLauncher.java @@ -211,6 +211,8 @@ public static void main(String[] args) { websocket.awaitClose(); + websocket.close(); + Thread.sleep(1000); } catch (Throwable ignored) { @@ -219,8 +221,5 @@ public static void main(String[] args) { break; } } - - // Force exit because of known issue with Jetty: HTTP client does not shutdown its threads. - //-System.exit(0); } } diff --git a/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/IgniteClusterLauncher.java b/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/IgniteClusterLauncher.java index 81218bdb49403..6c51374ba5574 100644 --- a/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/IgniteClusterLauncher.java +++ b/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/IgniteClusterLauncher.java @@ -55,7 +55,7 @@ import org.apache.ignite.console.agent.service.CacheClearDataService; import org.apache.ignite.console.agent.service.CacheCopyDataService; import org.apache.ignite.console.agent.service.CacheLoadDataService; -import org.apache.ignite.console.agent.service.ClusterAgentServiceList; +import org.apache.ignite.console.agent.service.ClusterAgentServiceManager; import org.apache.ignite.console.agent.service.ComputeTaskLoadService; import org.apache.ignite.console.json.JsonBinarySerializer; import org.apache.ignite.console.utils.BeanMerger; @@ -192,9 +192,8 @@ static public IgniteConfiguration singleIgniteConfiguration(IgniteConfiguration * * @param services Distributed services on the grid. */ - public static void deployServices(IgniteServices services) { - - services.deployNodeSingleton("serviceList", new ClusterAgentServiceList()); + public static void deployServices(IgniteServices services) { + services.deployNodeSingleton("loadDataService", new CacheLoadDataService()); services.deployNodeSingleton("clearDataService", new CacheClearDataService()); services.deployClusterSingleton("copyDataService", new CacheCopyDataService()); @@ -237,14 +236,14 @@ public static String registerNodeUrl(Ignite ignite,String clusterId) { /** */ - public static void stopIgnite(String clusterName,String nodeId) { - if(nodeId!=null) { - try { - Ignite ignite = Ignition.ignite(UUID.fromString(nodeId)); - String gridName = ignite.configuration().getIgniteInstanceName(); - Ignition.stop(gridName,true); - clusterName = null; - + public static void stopIgnite(String clusterName,String clusterId) { + if(clusterId!=null) { + try { + String gridName = RestClusterHandler.clusterNameMap.get(clusterId); + if(gridName!=null) { + Ignition.stop(gridName,true); + clusterName = null; + } } catch(IgniteIllegalStateException | IllegalArgumentException e) { //-log.error("Failed to stop cluster node: "+nodeId,e); @@ -272,19 +271,6 @@ public static Ignite trySingleStart(String clusterId,String clusterName,int node public static Ignite trySingleStart(String clusterId,String clusterName,int nodeIndex,boolean isLastNode,String cfgFile,String preCfgFile) throws IgniteCheckedException { Ignite ignite = null; - // 最后一个节点: clusterID和nodeID相同 - UUID nodeID = null; - if(isLastNode) { - try { - nodeID = UUID.fromString(clusterId); - ignite = Ignition.ignite(UUID.fromString(clusterId)); - return ignite; - } - catch(IgniteIllegalStateException | IllegalArgumentException e) { - - } - } - // 基于Instance Name 查找ignite try { ignite = Ignition.ignite(clusterName); @@ -303,7 +289,7 @@ public static Ignite trySingleStart(String clusterId,String clusterName,int node Collection cfgList = cfgMap.get1(); for(IgniteConfiguration cfg: cfgList) { - if(clusterName.equals(cfg.getIgniteInstanceName())){ + if(clusterName.equals(cfg.getIgniteInstanceName()) || cfgList.size()==1){ preCfg = cfg; } } @@ -320,10 +306,9 @@ public static Ignite trySingleStart(String clusterId,String clusterName,int node IgniteConfiguration cfg = cfgWorkMap.get1().iterator().next(); // 最后一个节点: clusterID和nodeID相同 - if(isLastNode) { - cfg.setNodeId(nodeID); + if(isLastNode) { if(cfg.getConsistentId()==null) - cfg.setConsistentId(clusterId); + cfg.setConsistentId(clusterId+"_"+nodeIndex); } else { cfg.setClusterStateOnStart(ClusterState.INACTIVE); @@ -340,7 +325,7 @@ public static Ignite trySingleStart(String clusterId,String clusterName,int node } - if(cfgMap!=null) { + if(cfgMap!=null && cfgMap.get1().size()>1) { // other ignite instance Collection cfgList = cfgMap.get1(); for(IgniteConfiguration cfg: cfgList) { @@ -363,10 +348,15 @@ public static Ignite trySingleStart(String clusterId,String clusterName,int node if(isLastNode && ignite!=null) { try { Thread.sleep(1000*nodeIndex); + while(ignite.cluster().nodes().size() argsList = new ArrayList<>(); if(ignite!=null) { @@ -510,12 +463,12 @@ public static JsonObject callClusterCommand(String cmdName,JsonObject json) { IgniteCommandRegistry cmdReg = null; if(ignite==null) { try { - Field registry = hnd.getClass().getField("registry"); + Field registry = hnd.getClass().getDeclaredField("registry"); registry.setAccessible(true); cmdReg = (IgniteCommandRegistry)registry.get(hnd); } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) { - + e.printStackTrace(); } } @@ -535,8 +488,8 @@ public static JsonObject callClusterCommand(String cmdName,JsonObject json) { String usage = outHandder.getOutput(); String desc = c.description(); int pos = 0; - if((pos=usage.indexOf("
"))>0) { - usage = usage.substring(pos+5).strip(); + if((pos=usage.indexOf(desc))>0) { + usage = usage.substring(pos+desc.length()+26).strip(); } JsonObject cmd = new JsonObject(); cmd.put("name", pair.getKey()); diff --git a/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/handlers/DatabaseHandler.java b/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/handlers/DatabaseHandler.java index 227769ca872a6..cac7223e59686 100644 --- a/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/handlers/DatabaseHandler.java +++ b/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/handlers/DatabaseHandler.java @@ -380,7 +380,12 @@ public List topologySnapshot() { catch(Exception e) { e.printStackTrace(); } - } + } + + for(String nodeId: databaseListener.deactivedCluster.keySet()) { + databaseListener.clusters.remove(nodeId); + } + databaseListener.deactivedCluster.clear(); return tops; } diff --git a/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/handlers/DatabaseListener.java b/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/handlers/DatabaseListener.java index 99235bf663989..a50327dca6a10 100644 --- a/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/handlers/DatabaseListener.java +++ b/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/handlers/DatabaseListener.java @@ -51,8 +51,7 @@ public class DatabaseListener { public boolean deactivedCluster(String id) { Integer count = deactivedCluster.compute(id,(k,v)->{ return v==null? 1: ++v;}); - if(count>1) { - clusters.remove(id); + if(count>1) { return true; } return false; diff --git a/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/handlers/DemoClusterHandler.java b/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/handlers/DemoClusterHandler.java index 56cb2b77bf160..bb50bbc1bab5a 100644 --- a/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/handlers/DemoClusterHandler.java +++ b/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/handlers/DemoClusterHandler.java @@ -46,7 +46,7 @@ */ public class DemoClusterHandler extends AbstractClusterHandler{ /** Demo cluster ID. */ - public static String DEMO_CLUSTER_ID; + public static String DEMO_CLUSTER_ID = null; /** Demo cluster name. */ public static final String DEMO_CLUSTER_NAME = "demo-cluster"; @@ -55,8 +55,7 @@ public class DemoClusterHandler extends AbstractClusterHandler{ * @param cfg Config. */ DemoClusterHandler(AgentConfiguration cfg) { - super(cfg, null); - DEMO_CLUSTER_ID = F.first(cfg.tokens()); + super(cfg, null); } /** {@inheritDoc} */ @@ -83,13 +82,15 @@ public List topologySnapshot() { if (AgentClusterDemo.getDemoUrl() != null) { try { IgniteEx ignite = (IgniteEx)Ignition.ignite(AgentClusterDemo.SRV_NODE_NAME); - + if(DEMO_CLUSTER_ID == null) { + DEMO_CLUSTER_ID = ignite.cluster().id().toString(); + } Collection nodes = collectNodes(ignite.context()); top = new TopologySnapshot(nodes); top.setClusterVersion(VER_STR); top.setActive(ignite.cluster().active()); - top.setId(DEMO_CLUSTER_ID.toString()); + top.setId(DEMO_CLUSTER_ID); top.setName(DEMO_CLUSTER_NAME); top.setDemo(true); @@ -99,14 +100,16 @@ public List topologySnapshot() { return null; } } - else { + else if(DEMO_CLUSTER_ID!=null) { top = new TopologySnapshot(); top.setClusterVersion(VER_STR); - top.setId(DEMO_CLUSTER_ID.toString()); + top.setId(DEMO_CLUSTER_ID); top.setName(DEMO_CLUSTER_NAME); top.setDemo(true); + DEMO_CLUSTER_ID = null; return List.of(top); - } + } + return null; } /** diff --git a/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/handlers/RestClusterHandler.java b/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/handlers/RestClusterHandler.java index 91194b6f8af66..c6437ac8d3f11 100644 --- a/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/handlers/RestClusterHandler.java +++ b/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/handlers/RestClusterHandler.java @@ -62,9 +62,9 @@ public class RestClusterHandler extends AbstractClusterHandler { /** Index of alive node URI. */ private final Map, Integer> startIdxs = U.newHashMap(2); - /** Map of clusterId-> node URI. */ + /** Map of clusterId -> node URI. */ public static final Map> clusterUrlMap = U.newHashMap(2); - + /** Map of cluster id -> cluster name */ public static final Map clusterNameMap = U.newHashMap(2); public static final Map deactivedCluster = new ConcurrentHashMap<>(); @@ -98,16 +98,6 @@ else if(!urls.contains(url)){ urls.add(url); } } - - public static boolean deactivedCluster(String id) { - Integer count = deactivedCluster.compute(id,(k,v)->{ return v==null? 1: ++v;}); - if(count>1) { - - return true; - } - return false; - } - /** {@inheritDoc} */ @Override public RestResult restCommand(String clusterId,JsonObject params) throws Throwable { @@ -290,10 +280,11 @@ else if (!Objects.equals(latestTop.nids(), newTop.nids())) { log.info("Cluster topology changed, new topology: " + nid8(newTop.nids())); } - if(cluster.isEmpty()) { - cluster = F.first(nodes).getConsistentId().toString(); - if(clusterNameMap.containsValue(cluster)) { - continue; + if(cluster.isEmpty()) { // external node + cluster = F.first(nodes).getNodeId().toString(); + String clusterName = F.first(nodes).getConsistentId().toString(); + if(!clusterNameMap.containsKey(cluster)) { + clusterNameMap.put(cluster, clusterName); } } @@ -302,7 +293,7 @@ else if (!Objects.equals(latestTop.nids(), newTop.nids())) { newTop.setDemo(false); newTop.setActive(active); newTop.setSecured(!F.isEmpty(res.getSessionToken())); - newTop.setName(RestClusterHandler.clusterNameMap.getOrDefault(cluster, cluster)); + newTop.setName(clusterNameMap.getOrDefault(cluster, cluster)); latestTop = newTop; @@ -318,14 +309,14 @@ else if (!Objects.equals(latestTop.nids(), newTop.nids())) { dieTop.setName(RestClusterHandler.clusterNameMap.getOrDefault(cluster, cluster)); tops.add(dieTop); - RestClusterHandler.deactivedCluster(cluster); + deactivedCluster.put(cluster,1); latestTop = null; } } - for(String nodeId: deactivedCluster.keySet()) { - RestClusterHandler.clusterUrlMap.remove(nodeId); - RestClusterHandler.clusterNameMap.remove(nodeId); + for(String clusterId: deactivedCluster.keySet()) { + clusterUrlMap.remove(clusterId); + clusterNameMap.remove(clusterId); } deactivedCluster.clear(); return tops; diff --git a/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/handlers/VertxClusterHandler.java b/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/handlers/VertxClusterHandler.java index fede1ff968efb..d45e1d3b64463 100644 --- a/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/handlers/VertxClusterHandler.java +++ b/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/handlers/VertxClusterHandler.java @@ -18,15 +18,18 @@ import java.util.Collection; import java.util.Collections; +import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.UUID; import java.util.Map.Entry; +import java.util.concurrent.ConcurrentHashMap; import java.util.Optional; import org.apache.ignite.Ignite; import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.IgniteIllegalStateException; import org.apache.ignite.IgniteLogger; import org.apache.ignite.Ignition; import org.apache.ignite.configuration.IgniteConfiguration; @@ -74,6 +77,8 @@ public class VertxClusterHandler implements ClusterHandler{ public static final Map lastErrors = U.newLinkedHashMap(4); /** ignite cluster id -> ignite name */ public static final Map clusterNameMap = U.newHashMap(4); + + public static final Map deactivedCluster = new ConcurrentHashMap<>(); private GremlinExecutor gremlinExecutor; @@ -82,14 +87,12 @@ public class VertxClusterHandler implements ClusterHandler{ /** Agent configuration. */ protected final AgentConfiguration cfg; - private String lastClusterId = ""; - /** * @param cfg Config. */ public VertxClusterHandler(AgentConfiguration cfg) { this.cfg = cfg; - gremlinExecutor = new GremlinExecutor(cfg.gremlinPort()); + gremlinExecutor = new GremlinExecutor(F.first(cfg.nodeURIs()),cfg.gremlinPort()); gridTaskExecutor = new GridTaskExecutor(); } @@ -105,17 +108,20 @@ public VertxClusterHandler(AgentConfiguration cfg) { if(code.indexOf("vertx.")<0) { // Gremlin Query - Ignite ignite = Ignition.ignite(clusterName); - return gremlinExecutor.sendRequest(ignite, clusterId, params); + Map context = new HashMap<>(); + context.put("graphName", clusterName); + return gremlinExecutor.sendRequest(context, clusterId, params); } if (cfg.disableVertx()) return RestResult.fail(404, "Vertx disabled by administrator."); + lastErrors.clear(); if (!clusterVertxMap.containsKey(clusterName)) { startVertxCluster(clusterName,cfg); - if(!lastErrors.containsKey(clusterName) && !clusterVertxMap.containsKey(clusterName)) { + + while(!lastErrors.containsKey(clusterName) && !clusterVertxMap.containsKey(clusterName)) { Thread.sleep(200); } } @@ -133,7 +139,7 @@ public VertxClusterHandler(AgentConfiguration cfg) { } if (lastErrors.containsKey(clusterName)) { - return RestResult.fail(500, lastErrors.get(clusterName).getMessage()); + return RestResult.fail(GridRestResponse.STATUS_FAILED, lastErrors.get(clusterName).getMessage()); } } else { @@ -198,32 +204,41 @@ public List topologySnapshot() { List tops = new LinkedList<>(); - for (Entry ent: clusterVertxMap.entrySet()) { + for (Entry ent: clusterNameMap.entrySet()) { TopologySnapshot top; - String clusterName = ent.getKey(); + String clusterId = ent.getKey(); + String clusterName = ent.getValue(); try { IgniteEx ignite = (IgniteEx)Ignition.ignite(clusterName); Collection nodes = collectNodes(ignite.context()); - top = new TopologySnapshot(nodes); - lastClusterId = ignite.cluster().id().toString(); - top.setId(lastClusterId); + top = new TopologySnapshot(nodes); + top.setId(clusterId); top.setName(VERTX_CLUSTER_NAME_PREFIX+clusterName); top.setDemo(false); top.setClusterVersion(VER_STR); top.setActive(ignite.active()); } - catch(Exception e) { + catch(IgniteIllegalStateException e) { top = new TopologySnapshot(); - top.setId(lastClusterId); + top.setId(clusterId); top.setName(VERTX_CLUSTER_NAME_PREFIX+clusterName); top.setDemo(false); top.setClusterVersion(VER_STR); top.setActive(false); + deactivedCluster.put(clusterId, 1); + clusterVertxMap.remove(clusterName); + } tops.add(top); } + + for(String nodeId: deactivedCluster.keySet()) { + clusterNameMap.remove(nodeId); + } + deactivedCluster.clear(); + return tops; } diff --git a/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/handlers/WebSocketRouter.java b/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/handlers/WebSocketRouter.java index 2b36bd8aec7d1..ef7ce28e29539 100644 --- a/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/handlers/WebSocketRouter.java +++ b/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/handlers/WebSocketRouter.java @@ -54,6 +54,7 @@ import java.util.UUID; import java.util.concurrent.CancellationException; import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; @@ -70,11 +71,14 @@ import org.apache.ignite.console.agent.AgentUtils; import org.apache.ignite.console.agent.IgniteClusterLauncher; import org.apache.ignite.console.agent.db.DataSourceManager; +import org.apache.ignite.console.agent.rest.GremlinExecutor; import org.apache.ignite.console.agent.rest.RestExecutor; import org.apache.ignite.console.agent.rest.RestRequest; import org.apache.ignite.console.agent.rest.RestResult; import org.apache.ignite.console.agent.service.CacheAgentService; import org.apache.ignite.console.agent.service.ClusterAgentService; +import org.apache.ignite.console.agent.service.ClusterAgentServiceManager; +import org.apache.ignite.console.agent.service.ServiceResult; import org.apache.ignite.console.demo.AgentClusterDemo; import org.apache.ignite.console.utils.Utils; import org.apache.ignite.console.websocket.AgentHandshakeRequest; @@ -160,6 +164,8 @@ public class WebSocketRouter implements AutoCloseable { private HttpClient httpClient; + private static Map runningServices = new ConcurrentHashMap<>(); + /** * @param cfg Configuration. */ @@ -178,7 +184,7 @@ public WebSocketRouter(AgentConfiguration cfg) { httpClient.setConnectBlocking(false); httpClient.setConnectTimeout(1000); httpClient.setFollowRedirects(false); - httpClient.setExecutor(RestExecutor.executor); + httpClient.setExecutor(RestExecutor.executor); // TODO GG-18379 Investigate how to establish native websocket connection with proxy. @@ -255,6 +261,8 @@ private void stopClient() { clusterHnd.close(); stopClient(); + + httpClient.destroy(); watcher.close(); } @@ -280,15 +288,15 @@ private void connect0() { return; - client = new WebSocketClient(httpClient); + client = new WebSocketClient(httpClient); + client.getPolicy().setMaxTextMessageSize(1024*1024); + client.getPolicy().setMaxBinaryMessageSize(1024*1024); + client.getPolicy().setMaxTextMessageBufferSize(1024*1024); + client.getPolicy().setMaxBinaryMessageBufferSize(1024*1024); client.start(); Session session = client.connect(this, URI.create(cfg.serverUri()).resolve(AGENTS_PATH)).get(5L, TimeUnit.SECONDS); - session.getPolicy().setMaxTextMessageSize(1024*1024); - session.getPolicy().setMaxBinaryMessageSize(1024*1024); - session.getPolicy().setMaxTextMessageBufferSize(1024*1024); - session.getPolicy().setMaxBinaryMessageBufferSize(1024*1024); - session.setIdleTimeout(60*60000); + session.setIdleTimeout(60*60000); reconnectCnt.set(0); @@ -398,6 +406,48 @@ private void processRevokeToken(String tok) { } + /** + * @param tok Token to revoke. + */ + private Ignite getIgnite(JsonObject json,JsonObject stat) { + String clusterId = json.getString("id"); + String clusterName = json.getString("name"); + Ignite ignite = null; + stat.put("status", "stoped"); + if(clusterName!=null) { + clusterName = Utils.escapeFileName(clusterName); + } + else { + String gridName = RestClusterHandler.clusterNameMap.get(clusterId); + if(gridName!=null) { + try { + ignite = Ignition.ignite(gridName); + stat.put("status", "started"); + clusterName = null; + } + catch(IgniteIllegalStateException e) { + stat.put("message", e.getMessage()); + stat.put("status", "stoped"); + } + } + } + + if(ignite==null && clusterName!=null) { + try { + ignite = Ignition.ignite(clusterName); + stat.put("status", "started"); + } + catch(IgniteIllegalStateException e) { + stat.put("message", e.getMessage()); + stat.put("status", "stoped"); + } + } + else { + stat.put("message", "ignite cluster not found!"); + } + return ignite; + } + /** * @param tok Token to revoke. */ @@ -408,12 +458,12 @@ private JsonObject processClusterStart(WebSocketRequest evt) { boolean isLastNode = evt.isLastNode(); String clusterId = json.getString("id"); - if(DEMO_CLUSTER_ID.equals(clusterId) || AgentClusterDemo.SRV_NODE_NAME.equals(clusterId)) { + if(clusterId.equals(DEMO_CLUSTER_ID) || AgentClusterDemo.SRV_NODE_NAME.equals(clusterId)) { json.put("demo", true); } String clusterName = Utils.escapeFileName(json.getString("name")); - try { - + try { + String unzipDest = IgniteClusterLauncher.saveBlobToFile(json); Boolean restart = json.getBoolean("restart",false); @@ -452,15 +502,15 @@ private JsonObject processClusterStart(WebSocketRequest evt) { if(configWorkFile.exists() && configFile.exists()) { // 合并并启动一个服务端已经配置好的node - ignite = IgniteClusterLauncher.trySingleStart(clusterId,clusterName,evt.getNodeSeq(),isLastNode,cfgFile,configFile.toString()); + ignite = IgniteClusterLauncher.trySingleStart(clusterId,clusterName,cfg.serverId(),isLastNode,cfgFile,configFile.toString()); } else if(configWorkFile.exists()) { // 启动一个独立的node,jvm内部的node之间相互隔离 - ignite = IgniteClusterLauncher.trySingleStart(clusterId,clusterName,evt.getNodeSeq(),isLastNode,cfgFile); + ignite = IgniteClusterLauncher.trySingleStart(clusterId,clusterName,cfg.serverId(),isLastNode,cfgFile); } else if(configFile.exists()) { // 启动一个服务端已经配置好的node - ignite = IgniteClusterLauncher.trySingleStart(clusterId,clusterName,evt.getNodeSeq(),isLastNode,null,configFile.toString()); + ignite = IgniteClusterLauncher.trySingleStart(clusterId,clusterName,cfg.serverId(),isLastNode,null,configFile.toString()); } else { stat.put("message", "not found cfg file, please deploy cfg first!"); @@ -468,9 +518,7 @@ else if(configFile.exists()) { if(ignite!=null) { IgniteClusterLauncher.registerNodeUrl(ignite,clusterId); - if(isLastNode) { - IgniteClusterLauncher.deployServices(ignite.services(ignite.cluster().forServers())); - } + stat.put("status", "started"); stat.put("message","Ignite started successfully."); } @@ -487,7 +535,7 @@ else if(configFile.exists()) { String cfgFile = String.format("%s/config/%s/src/main/resources/META-INF/%s-server.xml", work, clusterName,clusterName); File configWorkFile = new File(cfgFile); - IgniteConfiguration cfg = new IgniteConfiguration(); + IgniteConfiguration icfg = new IgniteConfiguration(); if(configWorkFile.exists()) { IgniteBiTuple, ? extends GridSpringResourceContext> cfgMap=null; if(ignite==null) { @@ -497,14 +545,14 @@ else if(configFile.exists()) { Collection cfgList = cfgMap.get1(); for(IgniteConfiguration cfg0: cfgList) { if(clusterName.equals(cfg0.getIgniteInstanceName())){ - cfg = cfg0; + icfg = cfg0; } } } } // 启动Demo节点,并且在最后一个节点部署服务 - ignite = AgentClusterDemo.tryStart(cfg,evt.getNodeSeq(),isLastNode); + ignite = AgentClusterDemo.tryStart(icfg,cfg.serverId(),isLastNode); if(ignite!=null) { stat.put("status", "started"); } @@ -567,13 +615,8 @@ private JsonObject processCallClusterService(String msg) { JsonObject stat = new JsonObject(); JsonObject json = fromJson(msg); String nodeId = json.getString("id"); - String serviceName = json.getString("serviceName",""); - String clusterName = null; - stat.put("status", "stoped"); - Ignite ignite = null; - if(json.getString("name",null)!=null) { - clusterName = Utils.escapeFileName(json.getString("name")); - } + String serviceName = json.getString("serviceName",""); + if(serviceName.equals("datasourceTest")) { JsonObject args = json.getJsonObject("args"); try (Connection conn = dbHnd.connect(args)) { @@ -591,8 +634,7 @@ private JsonObject processCallClusterService(String msg) { } } - if(serviceName.equals("datasourceDisconnect")) { - JsonObject args = json.getJsonObject("args"); + if(serviceName.equals("datasourceDisconnect")) { boolean rv = dbHnd.getDatabaseListener().deactivedCluster(nodeId); if(!rv) { stat.put("message", "Try again to remove from List."); @@ -603,53 +645,77 @@ private JsonObject processCallClusterService(String msg) { stat.put("status", rv); return stat; } - if(nodeId!=null) { - try { - ignite = Ignition.ignite(UUID.fromString(nodeId)); - stat.put("status", "started"); - clusterName = null; - } - catch(IgniteIllegalStateException e) { - stat.put("message", e.getMessage()); - stat.put("status", "stoped"); - } - } - if(clusterName!=null) { - try { - ignite = Ignition.ignite(clusterName); - stat.put("status", "started"); - } - catch(IgniteIllegalStateException e) { - stat.put("message", e.getMessage()); - stat.put("status", "stoped"); - } - } + Ignite ignite = getIgnite(json,stat); if(ignite!=null && !serviceName.isEmpty()) { - Service serviceObject = ignite.services().service(serviceName); - if(serviceObject==null) { - stat.put("message", "service not found"); - return stat; - } + JsonObject args = json.getJsonObject("args"); + if(args==null) { + args = new JsonObject(); + } + Service serviceObject = null; + String serviceType = json.getString("serviceType","ClusterAgentService"); + + if(serviceName.equals("serviceList")) { + ClusterAgentServiceManager serviceList = new ClusterAgentServiceManager(ignite); + ServiceResult result = serviceList.serviceList(args.getMap()); + return result.toJson(); + } + if(serviceName.equals("redeployService")) { + ClusterAgentServiceManager serviceList = new ClusterAgentServiceManager(ignite); + ServiceResult result = serviceList.redeployService(args.getMap()); + return result.toJson(); + } + if(serviceName.equals("undeployService")) { + ClusterAgentServiceManager serviceList = new ClusterAgentServiceManager(ignite); + ServiceResult result = serviceList.undeployService(args.getMap()); + return result.toJson(); + } + if(serviceName.equals("cancelService")) { + ClusterAgentServiceManager serviceList = new ClusterAgentServiceManager(ignite); + ServiceResult result = serviceList.cancelService(args.getMap()); + return result.toJson(); + } + try { - if(serviceObject instanceof ClusterAgentService){ - ClusterAgentService agentSeervice = (ClusterAgentService)(serviceObject); - Map result = agentSeervice.call(json.getMap()); - stat.put("result", result); - - } - else if(serviceObject instanceof CacheAgentService){ - CacheAgentService agentSeervice = (CacheAgentService)(serviceObject); - Map result = agentSeervice.call(json.getMap()); - stat.put("result", result); - } + + if(runningServices.containsKey(serviceName)) { + stat.put("message", String.format("%s already running!", serviceName)); + return stat; + } + if(serviceType.equals("CacheAgentService")) { + serviceObject = ignite.services().serviceProxy(serviceName,CacheAgentService.class,true); + if(serviceObject==null) { + stat.put("message", "service not found!"); + return stat; + } + + CacheAgentService agentSeervice = (CacheAgentService)(serviceObject); + runningServices.put(serviceName,agentSeervice); + ServiceResult result = agentSeervice.call(args.getMap()); + runningServices.remove(serviceName); + return result.toJson(); + + } + else { + serviceObject = ignite.services().serviceProxy(serviceName,ClusterAgentService.class,true); + if(serviceObject==null) { + stat.put("message", "service not found!"); + return stat; + } + + ClusterAgentService agentSeervice = (ClusterAgentService)(serviceObject); + runningServices.put(serviceName,agentSeervice); + ServiceResult result = agentSeervice.call(args.getMap()); + runningServices.remove(serviceName); + return result.toJson(); + } } catch(Exception e) { stat.put("message", e.getMessage()); stat.put("errorType", e.getClass().getSimpleName()); - } - - } + runningServices.remove(serviceName); + } + } return stat; } @@ -658,13 +724,15 @@ else if(serviceObject instanceof CacheAgentService){ * @param tok Token to revoke. */ private JsonObject processCallClusterCommand(String msg) { - log.info("Cluster cmd has been revoked: " + msg); - + log.info("Cluster cmd has been revoked: " + msg); JsonObject json = fromJson(msg); String nodeId = json.getString("id"); String cmdName = json.getString("cmdName",""); - JsonObject state = IgniteClusterLauncher.callClusterCommand(cmdName,json); - + JsonObject state = new JsonObject(); + Ignite ignite = getIgnite(json,state); + if(ignite!=null) { + state = IgniteClusterLauncher.callClusterCommand(ignite,cmdName,json); + } return state; } @@ -745,10 +813,12 @@ public void onMessage(Session ses, String msg) { // Gremlin Query or Execute groovy code res = vertxClusterHnd.restCommand(reqRest.getClusterId(),params); } - else if(DEMO_CLUSTER_ID.equals(reqRest.getClusterId())) { + else if(DEMO_CLUSTER_ID!=null && DEMO_CLUSTER_ID.equals(reqRest.getClusterId())) { + // demo grid cmd res = demoClusterHnd.restCommand(reqRest.getClusterId(),params); } else if(dbHnd.isDBCluster(reqRest.getClusterId())) { + // rdms cmd res = dbHnd.restCommand(reqRest.getClusterId(), params); } else if(vertxClusterHnd.isVertxCluster(reqRest.getClusterId())) { @@ -771,6 +841,14 @@ else if(vertxClusterHnd.isVertxCluster(reqRest.getClusterId())) { } res = RestResult.success(nodes.toString(), res.getSessionToken()); } + else if(cmd.equals("qryscanexe") && res.getData()!=null) { + JsonObject queryResult = new JsonObject(res.getData()); + queryResult = GremlinExecutor.parseKeyValueResponse(queryResult, reqRest.getClusterId()); + if(queryResult.containsKey("rows")) { + res = RestResult.success(queryResult.toString(), res.getSessionToken()); + } + + } } catch (Throwable e) { res = RestResult.fail(HTTP_INTERNAL_ERROR, e.getMessage()); diff --git a/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/rest/GremlinExecutor.java b/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/rest/GremlinExecutor.java index ee4dd170a71c4..4aca2a3cdc97d 100644 --- a/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/rest/GremlinExecutor.java +++ b/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/rest/GremlinExecutor.java @@ -19,6 +19,8 @@ import static org.apache.ignite.internal.processors.rest.GridRestResponse.STATUS_FAILED; import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; import java.util.Collection; import java.util.HashMap; import java.util.Map; @@ -56,13 +58,22 @@ public class GremlinExecutor implements AutoCloseable { /** */ private final GremlinGroovyScriptEngine engine; + String gremlinAddr = "localhost"; int gremlinPort = 8182; /** * @param sslCtxFactory Ssl context factory. */ - public GremlinExecutor(int gremlinPort) { + public GremlinExecutor(String addr, int gremlinPort) { engine = new GremlinGroovyScriptEngine(); + if(addr!=null) { + try { + URL url = new URL(addr); + this.gremlinAddr = url.getHost(); + } catch (MalformedURLException e) { + this.gremlinAddr = addr; + } + } this.gremlinPort = gremlinPort; } @@ -76,24 +87,23 @@ public GremlinExecutor(int gremlinPort) { } } - private void addFieldMetadata(JsonArray metaDataArray, String name,String type) { + private static void addFieldMetadata(JsonArray metaDataArray, String name,String type) { JsonObject object = new JsonObject(); + object.put("schemaName", "default"); object.put("fieldName", name); - object.put("typeName", type); - object.put("schemaName", "default"); object.put("fieldTypeName", type); metaDataArray.add(object); } - private void addFieldMetadata(JsonArray metaDataArray, Set keys) { + private static void addFieldMetadata(JsonArray metaDataArray, Set keys) { for(String key: keys) { addFieldMetadata(metaDataArray, key, "String"); } } - private void addFieldMetadata(JsonArray metaDataArray, Map dict) { + private static void addFieldMetadata(JsonArray metaDataArray, Map dict) { for(Map.Entry ent: dict.entrySet()) { - Class vCls = ent.getValue().getClass(); + Class vCls = ent.getValue()==null? Object.class: ent.getValue().getClass(); if(vCls.isArray()) { vCls = vCls.getComponentType(); } @@ -101,7 +111,7 @@ private void addFieldMetadata(JsonArray metaDataArray, Map dict) } } - private JsonObject parseResponse(Object object, String nodeId, JsonObject params) throws IOException { + public static JsonObject parseResponse(Object object, String nodeId, JsonObject params) throws IOException { JsonObject queryResult = new JsonObject(); String err = null; try { @@ -150,11 +160,67 @@ else if (object!=null) { } return queryResult; - } - + } + public static JsonObject parseKeyValueResponse(JsonObject dataObject, String nodeId) throws IOException { + JsonObject queryResult = new JsonObject(); + String err = null; + try { + + int rowCount = 0; //To count the number of rows + + queryResult.put("hasMore", false); + queryResult.put("queryId", 0); + queryResult.put("responseNodeId", nodeId); + queryResult.put("protocolVersion", 1); + + JsonArray metaDataArray = new JsonArray(); + + JsonArray dataArray = new JsonArray(); + + JsonArray items = dataObject.getJsonArray("items"); + + for(int i=0;i ent: jsonValue.getMap().entrySet()) { + Object v = ent.getValue(); + if(rowCount==0) { + JsonObject object = new JsonObject(); + object.put("schemaName", "default"); + object.put("fieldName", ent.getKey()); + object.put("fieldTypeName",v==null? "Object": v.getClass().getSimpleName()); + metaDataArray.add(object); + } + row.add(v); + } + rowCount++; + dataArray.add(row); + } + } + if(items.size()>0) { + queryResult.put("rows", dataArray); + queryResult.put("columns", metaDataArray); + + return queryResult; + } + + } catch (Exception ex) { + err = ex.getMessage(); + queryResult.put("error",err); + } + + return queryResult; + } - private JsonObject parseResponse(ResultSet resultSet,String nodeId,JsonObject params) throws IOException { + public static JsonObject parseResponse(ResultSet resultSet,String nodeId,JsonObject params) throws IOException { JsonObject queryResult = new JsonObject(); String err = null; @@ -191,7 +257,7 @@ private JsonObject parseResponse(ResultSet resultSet,String nodeId,JsonObject pa return queryResult; } - private JsonArray parseObject(Object object, JsonArray metaDataArray,int rowCount) { + private static JsonArray parseObject(Object object, JsonArray metaDataArray,int rowCount) { JsonArray row = new JsonArray(); if(object instanceof Vertex) { Vertex v = (Vertex) object; @@ -265,6 +331,26 @@ else if(object instanceof Map) { } } } + else if(object instanceof JsonObject) { + Map dict = ((JsonObject)object).getMap(); + if(rowCount==0) { + addFieldMetadata(metaDataArray,dict); + } + for(Map.Entry ent: dict.entrySet()) { + if(ent.getValue() instanceof Object[]) { + Object[] list = (Object[])ent.getValue(); + if(list.length==1) { + row.add(list[0]); + } + else { + row.add(ent.getValue()); + } + } + else { + row.add(ent.getValue()); + } + } + } else { if(rowCount==0) { addFieldMetadata(metaDataArray,"value","Object"); @@ -281,23 +367,20 @@ else if(object instanceof Map) { * @throws IOException If failed to parse REST result. * @throws Throwable If failed to send request. */ - public RestResult sendRequest(Ignite ignite, String clusterId,JsonObject params) throws Throwable { + public RestResult sendRequest(Map context, String clusterId,JsonObject params) throws Throwable { String code = params.getString("qry"); try { - long start = System.currentTimeMillis(); - String addr = "localhost"; + long start = System.currentTimeMillis(); JsonObject res = new JsonObject(); res.put("error",(String)null); - Cluster cluster = Cluster.build(addr).port(gremlinPort).create(); - Client client = cluster.connect(); - Map context = new HashMap<>(); - context.put("ignite_name", ignite.name()); - ResultSet result = client.submit(code,context); + Cluster cluster = Cluster.build(gremlinAddr).port(gremlinPort).create(); + Client client = cluster.connect(); - String nodeId = ignite.cluster().localNode().id().toString(); - JsonObject data = parseResponse(result, nodeId, params); + ResultSet result = client.submit(code,context); + + JsonObject data = parseResponse(result, clusterId, params); long end = System.currentTimeMillis(); data.put("duration", end-start); res.put("result", data); diff --git a/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/service/CacheAgentService.java b/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/service/CacheAgentService.java index d2842d11b2bbf..aee880dd9af28 100644 --- a/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/service/CacheAgentService.java +++ b/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/service/CacheAgentService.java @@ -5,19 +5,14 @@ import java.util.List; import java.util.Map; -import org.apache.ignite.Ignite; -import org.apache.ignite.IgniteCache; - -import org.apache.ignite.resources.IgniteInstanceResource; import org.apache.ignite.services.Service; import org.apache.ignite.services.ServiceContext; -public interface CacheAgentService extends Service { - +public interface CacheAgentService extends Service { - public abstract Map call(Map payload); + public abstract ServiceResult call(Map payload); } diff --git a/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/service/CacheClearDataService.java b/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/service/CacheClearDataService.java index 73105b02e1aed..49d62a9d1cd42 100644 --- a/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/service/CacheClearDataService.java +++ b/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/service/CacheClearDataService.java @@ -24,11 +24,11 @@ public class CacheClearDataService implements CacheAgentService { private Ignite ignite; @Override - public Map call(Map payload) { - Map result = new HashMap<>(); + public ServiceResult call(Map payload) { + ServiceResult result = new ServiceResult(); int count = 0; - JsonObject args = new JsonObject((Map)payload.get("args")); - List message = new ArrayList<>(); + JsonObject args = new JsonObject(payload); + List message = result.messages; List caches = ClusterAgentServiceUtil.cacheSelectList(ignite,args); for(String cache: caches) { try { @@ -41,7 +41,10 @@ public class CacheClearDataService implements CacheAgentService { message.add(e.getMessage()); } } - result.put("message", message); + if(message.isEmpty()) { + message.add("Finish clear data successfull!"); + } + result.put("caches", ignite.cacheNames()); result.put("count", count); return result; diff --git a/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/service/CacheCopyDataService.java b/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/service/CacheCopyDataService.java index 12c807d8dfbf5..bda844e92f68b 100644 --- a/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/service/CacheCopyDataService.java +++ b/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/service/CacheCopyDataService.java @@ -16,7 +16,7 @@ import org.apache.ignite.Ignition; import org.apache.ignite.cache.query.QueryCursor; import org.apache.ignite.cache.query.ScanQuery; - +import org.apache.ignite.console.agent.handlers.RestClusterHandler; import org.apache.ignite.console.utils.Utils; import org.apache.ignite.internal.util.lang.IgnitePair; import org.apache.ignite.resources.IgniteInstanceResource; @@ -39,39 +39,39 @@ public class CacheCopyDataService implements CacheAgentService { @IgniteInstanceResource private Ignite ignite; - public Ignite getIgniteByName(String clusterName,Map stat) { - Ignite ignite = null; - String nodeId; - nodeId = Utils.escapeFileName(clusterName); - if(nodeId!=null) { - try { - ignite = Ignition.ignite(UUID.fromString(nodeId)); - stat.put("status", "started"); + public Ignite getIgniteByName(String clusterName,ServiceResult stat) { + Ignite ignite = null; + String clusterId = Utils.escapeFileName(clusterName); + String gridName = RestClusterHandler.clusterNameMap.get(clusterId); + if(gridName!=null) { + try { + ignite = Ignition.ignite(gridName); + stat.setStatus("started"); clusterName = null; } catch(IgniteIllegalStateException e) { - stat.put("message", e.getMessage()); - stat.put("status", "stoped"); + stat.addMessage(e.getMessage()); + stat.setStatus("stoped"); } - } - if(clusterName!=null) { + } + if(ignite!=null && clusterName!=null) { try { ignite = Ignition.ignite(clusterName); - stat.put("status", "started"); + stat.setStatus("started"); } catch(IgniteIllegalStateException e) { - stat.put("message", e.getMessage()); - stat.put("status", "stoped"); + stat.addMessage(e.getMessage()); + stat.setStatus("stoped"); } } return ignite; } @Override - public Map call(Map payload) { - Map result = new HashMap<>(); + public ServiceResult call(Map payload) { + ServiceResult result = new ServiceResult(); int count = 0; - JsonObject args = new JsonObject((Map)payload.get("args")); + JsonObject args = new JsonObject(payload); String targetCache = args.getString("target"); String sourceCache = args.getString("source"); @@ -84,7 +84,7 @@ public Ignite getIgniteByName(String clusterName,Map stat) { } JsonObject cacheInfo = new JsonObject(); - String message = null; + try { IgniteCache destCache = ignite.cache(targetCache); @@ -101,11 +101,10 @@ public Ignite getIgniteByName(String clusterName,Map stat) { count++; } catch(Exception e) { - message = e.getMessage(); + result.messages.add(e.getMessage()); } - result.put("metric", cacheInfo); - result.put("message", message); + result.put("metric", cacheInfo); result.put("count", count); return result; } diff --git a/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/service/CacheLoadDataService.java b/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/service/CacheLoadDataService.java index 40d5d3c1e0fd0..20ae0f85edc3d 100644 --- a/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/service/CacheLoadDataService.java +++ b/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/service/CacheLoadDataService.java @@ -23,11 +23,11 @@ public class CacheLoadDataService implements CacheAgentService { private Ignite ignite; @Override - public Map call(Map payload) { - Map result = new HashMap<>(); + public ServiceResult call(Map payload) { + ServiceResult result = new ServiceResult(); int count = 0; - JsonObject args = new JsonObject((Map)payload.get("args")); - List message = new ArrayList<>(); + JsonObject args = new JsonObject(payload); + List message = result.getMessages(); List caches = ClusterAgentServiceUtil.cacheSelectList(ignite,args); for(String cache: caches) { try { @@ -40,7 +40,10 @@ public class CacheLoadDataService implements CacheAgentService { message.add(e.getMessage()); } } - result.put("message", message); + if(message.isEmpty()) { + message.add("Finish load data successfull!"); + } + result.put("caches", ignite.cacheNames()); result.put("count", count); return result; diff --git a/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/service/CacheSaveDataService.java b/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/service/CacheSaveDataService.java new file mode 100644 index 0000000000000..c0229ea76471a --- /dev/null +++ b/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/service/CacheSaveDataService.java @@ -0,0 +1,52 @@ +package org.apache.ignite.console.agent.service; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.ignite.Ignite; +import org.apache.ignite.IgniteCache; + +import org.apache.ignite.resources.IgniteInstanceResource; +import org.apache.ignite.services.Service; +import org.apache.ignite.services.ServiceContext; + +import io.swagger.annotations.ApiOperation; +import io.vertx.core.json.JsonObject; + +@ApiOperation("save ignite cache data to dbstore") +public class CacheSaveDataService implements CacheAgentService { + + /** Ignite instance. */ + @IgniteInstanceResource + private Ignite ignite; + + @Override + public ServiceResult call(Map payload) { + ServiceResult result = new ServiceResult(); + int count = 0; + JsonObject args = new JsonObject(payload); + List message = result.getMessages(); + List caches = ClusterAgentServiceUtil.cacheSelectList(ignite,args); + for(String cache: caches) { + try { + IgniteCache igcache = ignite.cache(cache); + + + count++; + } + catch(Exception e) { + message.add(e.getMessage()); + } + } + if(message.isEmpty()) { + message.add("Finish load data successfull!"); + } + + result.put("caches", ignite.cacheNames()); + result.put("count", count); + return result; + } + +} diff --git a/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/service/ClusterAgentService.java b/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/service/ClusterAgentService.java index eeb51252fe4b1..8a062934a3ae6 100644 --- a/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/service/ClusterAgentService.java +++ b/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/service/ClusterAgentService.java @@ -17,7 +17,7 @@ public interface ClusterAgentService extends Service { - public abstract Map call(Map payload); + public abstract ServiceResult call(Map payload); } diff --git a/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/service/ClusterAgentServiceList.java b/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/service/ClusterAgentServiceList.java deleted file mode 100644 index 3f5f7e2260d8e..0000000000000 --- a/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/service/ClusterAgentServiceList.java +++ /dev/null @@ -1,70 +0,0 @@ -package org.apache.ignite.console.agent.service; - -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; - -import org.apache.ignite.Ignite; - -import org.apache.ignite.resources.IgniteInstanceResource; -import org.apache.ignite.services.Service; -import org.apache.ignite.services.ServiceContext; -import org.apache.ignite.services.ServiceDescriptor; - -import io.swagger.annotations.ApiOperation; -import io.vertx.core.json.JsonObject; - -@ApiOperation("get list of servcie of cluster") -public class ClusterAgentServiceList implements ClusterAgentService { - - @IgniteInstanceResource - private Ignite ignite; - - @Override - public Map call(Map payload) { - Map result = new HashMap<>(); - Collection descs = ignite.services().serviceDescriptors(); - - JsonObject args = new JsonObject(payload); - String type = args!=null?args.getString("type"):null; - - for(ServiceDescriptor ctx: descs) { - JsonObject info = new JsonObject(); - info.put("name", ctx.name()); - - info.put("cacheName", ctx.cacheName()); - info.put("affinityKey", ctx.affinityKey()); - info.put("totalCount", ctx.totalCount()); - info.put("maxPerNodeCount", ctx.maxPerNodeCount()); - ApiOperation api = ctx.serviceClass().getAnnotation(ApiOperation.class); - if(api!=null) { - info.put("description", api.value()); - info.put("notes", api.notes()); - } - else { - info.put("description", ctx.serviceClass().getSimpleName()); - info.put("notes",""); - } - - if(ClusterAgentService.class.isAssignableFrom(ctx.serviceClass())){ - info.put("type","ClusterAgentService"); - // KeyaffinitySingleton,Multiple,NodeSingleton,ClusterSingleton - info.put("mode", "ClusterSingleton"); - } - else if(CacheAgentService.class.isAssignableFrom(ctx.serviceClass())){ - info.put("type","CacheAgentService"); - // KeyaffinitySingleton,Multiple,NodeSingleton,ClusterSingleton - info.put("mode", "NodeSingleton"); - } - else { - info.put("mode", "ClusterSingleton"); - info.put("type","Unknown"); - } - if(type!=null && !info.getString("type").equals(type)) { - continue; - } - result.put(ctx.name(), info); - } - return result; - } -} diff --git a/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/service/ClusterAgentServiceManager.java b/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/service/ClusterAgentServiceManager.java new file mode 100644 index 0000000000000..8b41786587854 --- /dev/null +++ b/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/service/ClusterAgentServiceManager.java @@ -0,0 +1,151 @@ +package org.apache.ignite.console.agent.service; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.ignite.Ignite; + +import org.apache.ignite.resources.IgniteInstanceResource; +import org.apache.ignite.services.Service; +import org.apache.ignite.services.ServiceConfiguration; +import org.apache.ignite.services.ServiceContext; +import org.apache.ignite.services.ServiceDescriptor; + +import io.swagger.annotations.ApiOperation; +import io.vertx.core.json.JsonArray; +import io.vertx.core.json.JsonObject; + +@ApiOperation("get list of servcie of cluster") +public class ClusterAgentServiceManager { + + @IgniteInstanceResource + private Ignite ignite; + + public ClusterAgentServiceManager(Ignite ignite){ + this.ignite = ignite; + } + + public ServiceResult serviceList(Map payload) { + ServiceResult result = new ServiceResult(); + Collection descs = ignite.services().serviceDescriptors(); + + JsonObject args = new JsonObject(payload); + String type = args!=null? args.getString("type"):null; + + for(ServiceDescriptor ctx: descs) { + JsonObject info = new JsonObject(); + info.put("name", ctx.name()); + + info.put("cacheName", ctx.cacheName()); + info.put("affinityKey", ctx.affinityKey()); + info.put("totalCount", ctx.totalCount()); + info.put("maxPerNodeCount", ctx.maxPerNodeCount()); + ApiOperation api = ctx.serviceClass().getAnnotation(ApiOperation.class); + if(api!=null) { + info.put("description", api.value()); + info.put("notes", api.notes()); + } + else { + info.put("description", ctx.serviceClass().getSimpleName()); + info.put("notes",""); + } + + if(ClusterAgentService.class.isAssignableFrom(ctx.serviceClass())){ + info.put("type","ClusterAgentService"); + // KeyaffinitySingleton,Multiple,NodeSingleton,ClusterSingleton + info.put("mode", "ClusterSingleton"); + } + else if(CacheAgentService.class.isAssignableFrom(ctx.serviceClass())){ + info.put("type","CacheAgentService"); + // KeyaffinitySingleton,Multiple,NodeSingleton,ClusterSingleton + info.put("mode", "NodeSingleton"); + } + else { + info.put("mode", "ClusterSingleton"); + info.put("type","Unknown"); + } + if(type!=null && !info.getString("type").equals(type)) { + continue; + } + result.put(ctx.name(), info); + } + return result; + } + + public ServiceResult redeployService(Map payload) { + ServiceResult result = new ServiceResult(); + Collection descs = ignite.services().serviceDescriptors(); + JsonObject args = new JsonObject(payload); + JsonArray services = args.getJsonArray("services"); + List messages = new ArrayList<>(); + for(ServiceDescriptor desc: descs) { + for(Object service: services) { + if(desc.name().equals(service)) { + ServiceConfiguration cfg = new ServiceConfiguration(); + cfg.setName(desc.name()); + JsonObject info = new JsonObject(); + info.put("name", desc.name()); + info.put("cacheName", desc.cacheName()); + + try { + cfg.setService(desc.serviceClass().newInstance()); + ignite.services().deployNodeSingleton(cfg.getName(),cfg.getService()); + + } catch (InstantiationException | IllegalAccessException e) { + messages.add(e.getMessage()); + } + result.put(desc.name(), info); + } + } + } + return result; + } + + public ServiceResult undeployService(Map payload) { + ServiceResult result = new ServiceResult(); + JsonObject args = new JsonObject(payload); + JsonArray services = args.getJsonArray("services"); + List messages = result.messages; + for(Object service: services) { + if(service!=null) { + + JsonObject info = new JsonObject(); + info.put("name", service.toString()); + try { + ignite.services().cancel(service.toString()); + + } catch (Exception e) { + messages.add(e.getMessage()); + } + result.put(service.toString(), info); + } + } + return result; + } + + public ServiceResult cancelService(Map payload) { + ServiceResult result = new ServiceResult(); + JsonObject args = new JsonObject(payload); + JsonArray services = args.getJsonArray("services"); + List messages = result.messages; + for(Object service: services) { + if(service!=null) { + + JsonObject info = new JsonObject(); + info.put("name", service.toString()); + try { + Service svc = ignite.services().service(service.toString()); + svc.cancel(); + + } catch (Exception e) { + messages.add(e.getMessage()); + } + result.put(service.toString(), info); + } + } + return result; + } +} diff --git a/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/service/ClusterAgentServiceUtil.java b/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/service/ClusterAgentServiceUtil.java index 4eaa4811e2a9a..6b448a775101f 100644 --- a/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/service/ClusterAgentServiceUtil.java +++ b/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/service/ClusterAgentServiceUtil.java @@ -36,7 +36,7 @@ public static List cacheSelectList(Ignite ignite,JsonObject args) { } if(selectCaches!=null) { if(!selectCaches.contains(igcache.getName())) { - //-continue; + continue; } } list.add(cache); diff --git a/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/service/ClusterSnapshotDataService.java b/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/service/ClusterSnapshotDataService.java index cd039b9d49923..39b3ae52d97aa 100644 --- a/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/service/ClusterSnapshotDataService.java +++ b/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/service/ClusterSnapshotDataService.java @@ -33,10 +33,10 @@ public class ClusterSnapshotDataService implements ClusterAgentService { private Ignite ignite; @Override - public Map call(Map payload) { - Map result = new HashMap<>(); + public ServiceResult call(Map payload) { + ServiceResult result = new ServiceResult(); int count = 0; - JsonObject args = new JsonObject((Map)payload.get("args")); + JsonObject args = new JsonObject(payload); String destClusterName = args.getString("dest"); diff --git a/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/service/ComputeTaskLoadService.java b/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/service/ComputeTaskLoadService.java index 21fd5c80e76fb..6c86612edc1c7 100644 --- a/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/service/ComputeTaskLoadService.java +++ b/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/service/ComputeTaskLoadService.java @@ -38,11 +38,10 @@ public class ComputeTaskLoadService implements ClusterAgentService { private Ignite ignite; @Override - public Map call(Map payload) { - - Map result = new HashMap<>(); + public ServiceResult call(Map payload) { + ServiceResult result = new ServiceResult(); int count = 0; - JsonObject args = new JsonObject((Map)payload.get("args")); + JsonObject args = new JsonObject(payload); String task = args.getString("task"); if(task.indexOf('.')<0) { task = "org.apache.ignite.console.agent.task."+task; @@ -67,6 +66,7 @@ public void run() { } catch (Throwable e) { ignite.log().error("DemoCancellableTask execution error", e); + result.addMessage(e.getMessage()); } } @@ -77,7 +77,7 @@ public void run() { } catch (ClassNotFoundException e1) { e1.printStackTrace(); - result.put("errors", e1.getMessage()); + result.addMessage(e1.getMessage()); } return result; diff --git a/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/service/ServiceResult.java b/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/service/ServiceResult.java new file mode 100644 index 0000000000000..5909a16e963f7 --- /dev/null +++ b/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/service/ServiceResult.java @@ -0,0 +1,50 @@ +package org.apache.ignite.console.agent.service; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import io.vertx.core.json.JsonObject; + +public class ServiceResult { + String status; + List messages = new ArrayList<>(); + Map result = new HashMap<>(); + + public ServiceResult setStatus(String status) { + this.status = status; + return this; + } + + public ServiceResult put(String key,Object value) { + result.put(key, value); + return this; + } + + public ServiceResult addMessage(String msg) { + messages.add(msg); + return this; + } + + + public String getStatus() { + return status; + } + + public List getMessages() { + return messages; + } + + public Map getResult() { + return result; + } + + public JsonObject toJson() { + JsonObject stat = new JsonObject(); + stat.put("status", status); + stat.put("result", result); + stat.put("message", messages); + return stat; + } +} diff --git a/web-console/web-agent/src/main/java/org/apache/ignite/console/demo/AgentClusterDemo.java b/web-console/web-agent/src/main/java/org/apache/ignite/console/demo/AgentClusterDemo.java index 5b8106cd7274d..cee91857087ee 100644 --- a/web-console/web-agent/src/main/java/org/apache/ignite/console/demo/AgentClusterDemo.java +++ b/web-console/web-agent/src/main/java/org/apache/ignite/console/demo/AgentClusterDemo.java @@ -113,7 +113,7 @@ private static IgniteConfiguration igniteConfiguration(IgniteConfiguration cfg, cfg.setIgniteInstanceName((client ? CLN_NODE_NAME : SRV_NODE_NAME)); cfg.setLocalHost("127.0.0.1"); cfg.setEventStorageSpi(new MemoryEventStorageSpi()); - cfg.setConsistentId(cfg.getIgniteInstanceName()+"_"+ gridIdx); + File workDir = new File(U.workDirectory(null, null), "demo-work"); @@ -146,7 +146,6 @@ private static IgniteConfiguration igniteConfiguration(IgniteConfiguration cfg, TcpCommunicationSpi commSpi = new TcpCommunicationSpi(); - commSpi.setSharedMemoryPort(-1); commSpi.setMessageQueueLimit(10); int commPort = basePort + 30; @@ -235,12 +234,12 @@ public static Ignite tryStart(IgniteConfiguration cfg, int idx, boolean lastNode cfg.getWorkDirectory(), cfg.getDataStorageConfiguration().getStoragePath(), true - ); - cfg.setNodeId(UUID.fromString(DemoClusterHandler.DEMO_CLUSTER_ID)); + ); + cfg.setConsistentId(cfg.getIgniteInstanceName()+"_"+ idx); } - else { - cfg.setNodeId(null); + else { cfg.setClusterStateOnStart(ClusterState.INACTIVE); + cfg.setConsistentId(cfg.getIgniteInstanceName()+"_"+ idx); } ignite = Ignition.start(cfg); @@ -281,10 +280,12 @@ public static Ignite tryStart(IgniteConfiguration cfg, int idx, boolean lastNode } finally { if (lastNode && ignite != null) { - try { + try { Thread.sleep(1000*idx); - ignite.cluster().state(ClusterState.ACTIVE); - + while(ignite.cluster().nodes().size()