http://git-wip-us.apache.org/repos/asf/ignite/blob/7ee1683e/modules/web-console/frontend/app/vendor.js ---------------------------------------------------------------------- diff --git a/modules/web-console/frontend/app/vendor.js b/modules/web-console/frontend/app/vendor.js index eac47d4..58b1ede 100644 --- a/modules/web-console/frontend/app/vendor.js +++ b/modules/web-console/frontend/app/vendor.js @@ -15,6 +15,7 @@ * limitations under the License. */ +import 'babel-polyfill'; import 'jquery'; import 'angular'; import 'angular-acl';
http://git-wip-us.apache.org/repos/asf/ignite/blob/7ee1683e/modules/web-console/frontend/controllers/caches-controller.js ---------------------------------------------------------------------- diff --git a/modules/web-console/frontend/controllers/caches-controller.js b/modules/web-console/frontend/controllers/caches-controller.js deleted file mode 100644 index 5f8fc2f..0000000 --- a/modules/web-console/frontend/controllers/caches-controller.js +++ /dev/null @@ -1,653 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import infoMessageTemplateUrl from 'views/templates/message.tpl.pug'; - -// Controller for Caches screen. -export default ['$scope', '$http', '$state', '$filter', '$timeout', '$modal', 'IgniteLegacyUtils', 'IgniteMessages', 'IgniteConfirm', 'IgniteInput', 'IgniteLoading', 'IgniteModelNormalizer', 'IgniteUnsavedChangesGuard', 'IgniteConfigurationResource', 'IgniteErrorPopover', 'IgniteFormUtils', 'IgniteLegacyTable', 'IgniteVersion', - function($scope, $http, $state, $filter, $timeout, $modal, LegacyUtils, Messages, Confirm, Input, Loading, ModelNormalizer, UnsavedChangesGuard, Resource, ErrorPopover, FormUtils, LegacyTable, Version) { - this.available = Version.available.bind(Version); - - const rebuildDropdowns = () => { - $scope.affinityFunction = [ - {value: 'Rendezvous', label: 'Rendezvous'}, - {value: 'Custom', label: 'Custom'}, - {value: null, label: 'Default'} - ]; - - if (this.available(['1.0.0', '2.0.0'])) - $scope.affinityFunction.splice(1, 0, {value: 'Fair', label: 'Fair'}); - }; - - rebuildDropdowns(); - - const filterModel = () => { - if ($scope.backupItem) { - if (this.available('2.0.0')) { - if (_.get($scope.backupItem, 'affinity.kind') === 'Fair') - $scope.backupItem.affinity.kind = null; - } - } - }; - - Version.currentSbj.subscribe({ - next: () => { - rebuildDropdowns(); - - filterModel(); - } - }); - - UnsavedChangesGuard.install($scope); - - const emptyCache = {empty: true}; - - let __original_value; - - const blank = { - evictionPolicy: {}, - cacheStoreFactory: { - CacheHibernateBlobStoreFactory: { - hibernateProperties: [] - } - }, - writeBehindCoalescing: true, - nearConfiguration: {}, - sqlFunctionClasses: [] - }; - - // We need to initialize backupItem with empty object in order to properly used from angular directives. - $scope.backupItem = emptyCache; - - $scope.ui = FormUtils.formUI(); - $scope.ui.activePanels = [0]; - $scope.ui.topPanels = [0, 1, 2, 3]; - - $scope.saveBtnTipText = FormUtils.saveBtnTipText; - $scope.widthIsSufficient = FormUtils.widthIsSufficient; - $scope.offHeapMode = 'DISABLED'; - - $scope.contentVisible = function() { - const item = $scope.backupItem; - - return !item.empty && (!item._id || _.find($scope.displayedRows, {_id: item._id})); - }; - - $scope.toggleExpanded = function() { - $scope.ui.expanded = !$scope.ui.expanded; - - ErrorPopover.hide(); - }; - - $scope.caches = []; - $scope.domains = []; - - function _cacheLbl(cache) { - return cache.name + ', ' + cache.cacheMode + ', ' + cache.atomicityMode; - } - - function selectFirstItem() { - if ($scope.caches.length > 0) - $scope.selectItem($scope.caches[0]); - } - - function cacheDomains(item) { - return _.reduce($scope.domains, function(memo, domain) { - if (item && _.includes(item.domains, domain.value)) - memo.push(domain.meta); - - return memo; - }, []); - } - - const setOffHeapMode = (item) => { - if (_.isNil(item.offHeapMaxMemory)) - return; - - return item.offHeapMode = Math.sign(item.offHeapMaxMemory); - }; - - const setOffHeapMaxMemory = (value) => { - const item = $scope.backupItem; - - if (_.isNil(value) || value <= 0) - return item.offHeapMaxMemory = value; - - item.offHeapMaxMemory = item.offHeapMaxMemory > 0 ? item.offHeapMaxMemory : null; - }; - - $scope.tablePairSave = LegacyTable.tablePairSave; - $scope.tablePairSaveVisible = LegacyTable.tablePairSaveVisible; - $scope.tableNewItem = LegacyTable.tableNewItem; - $scope.tableNewItemActive = LegacyTable.tableNewItemActive; - - $scope.tableStartEdit = function(item, field, index) { - if ($scope.tableReset(true)) - LegacyTable.tableStartEdit(item, field, index, $scope.tableSave); - }; - - $scope.tableEditing = LegacyTable.tableEditing; - - $scope.tableSave = function(field, index, stopEdit) { - if (LegacyTable.tablePairSaveVisible(field, index)) - return LegacyTable.tablePairSave($scope.tablePairValid, $scope.backupItem, field, index, stopEdit); - - return true; - }; - - $scope.tableRemove = function(item, field, index) { - if ($scope.tableReset(true)) - LegacyTable.tableRemove(item, field, index); - }; - - $scope.tableReset = (trySave) => { - const field = LegacyTable.tableField(); - - if (trySave && LegacyUtils.isDefined(field) && !$scope.tableSave(field, LegacyTable.tableEditedRowIndex(), true)) - return false; - - LegacyTable.tableReset(); - - return true; - }; - - $scope.hibernatePropsTbl = { - type: 'hibernate', - model: 'cacheStoreFactory.CacheHibernateBlobStoreFactory.hibernateProperties', - focusId: 'Property', - ui: 'table-pair', - keyName: 'name', - valueName: 'value', - save: $scope.tableSave - }; - - $scope.tablePairValid = function(item, field, index, stopEdit) { - const pairValue = LegacyTable.tablePairValue(field, index); - - const model = _.get(item, field.model); - - if (!_.isNil(model)) { - const idx = _.findIndex(model, (pair) => { - return pair.name === pairValue.key; - }); - - // Found duplicate by key. - if (idx >= 0 && idx !== index) { - if (stopEdit) - return false; - - return ErrorPopover.show(LegacyTable.tableFieldId(index, 'KeyProperty'), 'Property with such name already exists!', $scope.ui, 'query'); - } - } - - return true; - }; - - Loading.start('loadingCachesScreen'); - - // When landing on the page, get caches and show them. - Resource.read() - .then(({spaces, clusters, caches, domains, igfss}) => { - const validFilter = $filter('domainsValidation'); - - $scope.spaces = spaces; - $scope.caches = caches; - $scope.igfss = _.map(igfss, (igfs) => ({ - label: igfs.name, - value: igfs._id, - igfs - })); - - _.forEach($scope.caches, (cache) => cache.label = _cacheLbl(cache)); - - $scope.clusters = _.map(clusters, (cluster) => ({ - value: cluster._id, - label: cluster.name, - discovery: cluster.discovery, - checkpointSpi: cluster.checkpointSpi, - caches: cluster.caches - })); - - $scope.domains = _.sortBy(_.map(validFilter(domains, true, false), (domain) => ({ - label: domain.valueType, - value: domain._id, - kind: domain.kind, - meta: domain - })), 'label'); - - if ($state.params.linkId) - $scope.createItem($state.params.linkId); - else { - const lastSelectedCache = angular.fromJson(sessionStorage.lastSelectedCache); - - if (lastSelectedCache) { - const idx = _.findIndex($scope.caches, function(cache) { - return cache._id === lastSelectedCache; - }); - - if (idx >= 0) - $scope.selectItem($scope.caches[idx]); - else { - sessionStorage.removeItem('lastSelectedCache'); - - selectFirstItem(); - } - } - else - selectFirstItem(); - } - - $scope.$watch('ui.inputForm.$valid', function(valid) { - if (valid && ModelNormalizer.isEqual(__original_value, $scope.backupItem)) - $scope.ui.inputForm.$dirty = false; - }); - - $scope.$watch('backupItem', function(val) { - if (!$scope.ui.inputForm) - return; - - const form = $scope.ui.inputForm; - - if (form.$valid && ModelNormalizer.isEqual(__original_value, val)) - form.$setPristine(); - else - form.$setDirty(); - }, true); - - $scope.$watch('backupItem.offHeapMode', setOffHeapMaxMemory); - - $scope.$watch('ui.activePanels.length', () => { - ErrorPopover.hide(); - }); - }) - .catch(Messages.showError) - .then(() => { - $scope.ui.ready = true; - $scope.ui.inputForm && $scope.ui.inputForm.$setPristine(); - - Loading.finish('loadingCachesScreen'); - }); - - $scope.selectItem = function(item, backup) { - function selectItem() { - $scope.selectedItem = item; - - if (item && !_.get(item.cacheStoreFactory.CacheJdbcBlobStoreFactory, 'connectVia')) - _.set(item.cacheStoreFactory, 'CacheJdbcBlobStoreFactory.connectVia', 'DataSource'); - - try { - if (item && item._id) - sessionStorage.lastSelectedCache = angular.toJson(item._id); - else - sessionStorage.removeItem('lastSelectedCache'); - } - catch (ignored) { - // No-op. - } - - if (backup) - $scope.backupItem = backup; - else if (item) - $scope.backupItem = angular.copy(item); - else - $scope.backupItem = emptyCache; - - $scope.backupItem = _.merge({}, blank, $scope.backupItem); - - if ($scope.ui.inputForm) { - $scope.ui.inputForm.$error = {}; - $scope.ui.inputForm.$setPristine(); - } - - setOffHeapMode($scope.backupItem); - - __original_value = ModelNormalizer.normalize($scope.backupItem); - - filterModel(); - - if (LegacyUtils.getQueryVariable('new')) - $state.go('base.configuration.tabs.advanced.caches'); - } - - FormUtils.confirmUnsavedChanges($scope.backupItem && $scope.ui.inputForm && $scope.ui.inputForm.$dirty, selectItem); - }; - - $scope.linkId = () => $scope.backupItem._id ? $scope.backupItem._id : 'create'; - - function prepareNewItem(linkId) { - return { - space: $scope.spaces[0]._id, - cacheMode: 'PARTITIONED', - atomicityMode: 'ATOMIC', - readFromBackup: true, - copyOnRead: true, - clusters: linkId && _.find($scope.clusters, {value: linkId}) - ? [linkId] : _.map($scope.clusters, function(cluster) { return cluster.value; }), - domains: linkId && _.find($scope.domains, { value: linkId }) ? [linkId] : [], - cacheStoreFactory: {CacheJdbcBlobStoreFactory: {connectVia: 'DataSource'}} - }; - } - - // Add new cache. - $scope.createItem = function(linkId) { - $timeout(() => FormUtils.ensureActivePanel($scope.ui, 'general', 'cacheNameInput')); - - $scope.selectItem(null, prepareNewItem(linkId)); - }; - - function cacheClusters() { - return _.filter($scope.clusters, (cluster) => _.includes($scope.backupItem.clusters, cluster.value)); - } - - function clusterCaches(cluster) { - const caches = _.filter($scope.caches, - (cache) => cache._id !== $scope.backupItem._id && _.includes(cluster.caches, cache._id)); - - caches.push($scope.backupItem); - - return caches; - } - - const _objToString = (type, name, prefix = '') => { - if (type === 'checkpoint') - return `${prefix} checkpoint configuration in cluster "${name}"`; - if (type === 'cluster') - return `${prefix} discovery IP finder in cluster "${name}"`; - - return `${prefix} ${type} "${name}"`; - }; - - function checkDataSources() { - const clusters = cacheClusters(); - - let checkRes = {checked: true}; - - const failCluster = _.find(clusters, (cluster) => { - const caches = clusterCaches(cluster); - - checkRes = LegacyUtils.checkDataSources(cluster, caches, $scope.backupItem); - - return !checkRes.checked; - }); - - if (!checkRes.checked) { - return ErrorPopover.show(checkRes.firstObj.cacheStoreFactory.kind === 'CacheJdbcPojoStoreFactory' ? 'pojoDialectInput' : 'blobDialectInput', - 'Found ' + _objToString(checkRes.secondType, checkRes.secondObj.name || failCluster.label) + ' with the same data source bean name "' + - checkRes.firstDs.dataSourceBean + '" and different database: "' + - LegacyUtils.cacheStoreJdbcDialectsLabel(checkRes.firstDs.dialect) + '" in ' + _objToString(checkRes.firstType, checkRes.firstObj.name, 'current') + ' and "' + - LegacyUtils.cacheStoreJdbcDialectsLabel(checkRes.secondDs.dialect) + '" in ' + _objToString(checkRes.secondType, checkRes.secondObj.name || failCluster.label), - $scope.ui, 'store', 10000); - } - - return true; - } - - function checkEvictionPolicy(evictionPlc) { - if (evictionPlc && evictionPlc.kind) { - const plc = evictionPlc[evictionPlc.kind]; - - if (plc && !plc.maxMemorySize && !plc.maxSize) - return ErrorPopover.show('evictionPolicymaxMemorySizeInput', 'Either maximum memory size or maximum size should be great than 0!', $scope.ui, 'memory'); - } - - return true; - } - - function checkSQLSchemas() { - const clusters = cacheClusters(); - - let checkRes = {checked: true}; - - const failCluster = _.find(clusters, (cluster) => { - const caches = clusterCaches(cluster); - - checkRes = LegacyUtils.checkCacheSQLSchemas(caches, $scope.backupItem); - - return !checkRes.checked; - }); - - if (!checkRes.checked) { - return ErrorPopover.show('sqlSchemaInput', - 'Found cache "' + checkRes.secondCache.name + '" in cluster "' + failCluster.label + '" ' + - 'with the same SQL schema name "' + checkRes.firstCache.sqlSchema + '"', - $scope.ui, 'query', 10000); - } - - return true; - } - - function checkStoreFactoryBean(storeFactory, beanFieldId) { - if (!LegacyUtils.isValidJavaIdentifier('Data source bean', storeFactory.dataSourceBean, beanFieldId, $scope.ui, 'store')) - return false; - - return checkDataSources(); - } - - function checkStoreFactory(item) { - const cacheStoreFactorySelected = item.cacheStoreFactory && item.cacheStoreFactory.kind; - - if (cacheStoreFactorySelected) { - const storeFactory = item.cacheStoreFactory[item.cacheStoreFactory.kind]; - - if (item.cacheStoreFactory.kind === 'CacheJdbcPojoStoreFactory' && !checkStoreFactoryBean(storeFactory, 'pojoDataSourceBean')) - return false; - - if (item.cacheStoreFactory.kind === 'CacheJdbcBlobStoreFactory' && storeFactory.connectVia !== 'URL' - && !checkStoreFactoryBean(storeFactory, 'blobDataSourceBean')) - return false; - } - - if ((item.readThrough || item.writeThrough) && !cacheStoreFactorySelected) - return ErrorPopover.show('cacheStoreFactoryInput', (item.readThrough ? 'Read' : 'Write') + ' through are enabled but store is not configured!', $scope.ui, 'store'); - - if (item.writeBehindEnabled && !cacheStoreFactorySelected) - return ErrorPopover.show('cacheStoreFactoryInput', 'Write behind enabled but store is not configured!', $scope.ui, 'store'); - - if (cacheStoreFactorySelected && !item.readThrough && !item.writeThrough) - return ErrorPopover.show('readThroughLabel', 'Store is configured but read/write through are not enabled!', $scope.ui, 'store'); - - return true; - } - - // Check cache logical consistency. - function validate(item) { - ErrorPopover.hide(); - - if (LegacyUtils.isEmptyString(item.name)) - return ErrorPopover.show('cacheNameInput', 'Cache name should not be empty!', $scope.ui, 'general'); - - if (item.memoryMode === 'ONHEAP_TIERED' && item.offHeapMaxMemory > 0 && !LegacyUtils.isDefined(item.evictionPolicy.kind)) - return ErrorPopover.show('evictionPolicyKindInput', 'Eviction policy should be configured!', $scope.ui, 'memory'); - - if (!LegacyUtils.checkFieldValidators($scope.ui)) - return false; - - if (item.memoryMode === 'OFFHEAP_VALUES' && !_.isEmpty(item.domains)) - return ErrorPopover.show('memoryModeInput', 'Query indexing could not be enabled while values are stored off-heap!', $scope.ui, 'memory'); - - if (item.memoryMode === 'OFFHEAP_TIERED' && item.offHeapMaxMemory === -1) - return ErrorPopover.show('offHeapModeInput', 'Invalid value!', $scope.ui, 'memory'); - - if (!checkEvictionPolicy(item.evictionPolicy)) - return false; - - if (!checkSQLSchemas()) - return false; - - if (!checkStoreFactory(item)) - return false; - - if (item.writeBehindFlushSize === 0 && item.writeBehindFlushFrequency === 0) - return ErrorPopover.show('writeBehindFlushSizeInput', 'Both "Flush frequency" and "Flush size" are not allowed as 0!', $scope.ui, 'store'); - - if (item.nodeFilter && item.nodeFilter.kind === 'OnNodes' && _.isEmpty(item.nodeFilter.OnNodes.nodeIds)) - return ErrorPopover.show('nodeFilter-title', 'At least one node ID should be specified!', $scope.ui, 'nodeFilter'); - - return true; - } - - // Save cache in database. - function save(item) { - $http.post('/api/v1/configuration/caches/save', item) - .then(({data}) => { - const _id = data; - - item.label = _cacheLbl(item); - - $scope.ui.inputForm.$setPristine(); - - const idx = _.findIndex($scope.caches, {_id}); - - if (idx >= 0) - _.assign($scope.caches[idx], item); - else { - item._id = _id; - $scope.caches.push(item); - } - - _.forEach($scope.clusters, (cluster) => { - if (_.includes(item.clusters, cluster.value)) - cluster.caches = _.union(cluster.caches, [_id]); - else - _.pull(cluster.caches, _id); - }); - - _.forEach($scope.domains, (domain) => { - if (_.includes(item.domains, domain.value)) - domain.meta.caches = _.union(domain.meta.caches, [_id]); - else - _.pull(domain.meta.caches, _id); - }); - - $scope.selectItem(item); - - Messages.showInfo('Cache "' + item.name + '" saved.'); - }) - .catch(Messages.showError); - } - - // Save cache. - $scope.saveItem = function() { - const item = $scope.backupItem; - - _.merge(item, LegacyUtils.autoCacheStoreConfiguration(item, cacheDomains(item))); - - if (validate(item)) - save(item); - }; - - function _cacheNames() { - return _.map($scope.caches, (cache) => cache.name); - } - - // Clone cache with new name. - $scope.cloneItem = function() { - if (validate($scope.backupItem)) { - Input.clone($scope.backupItem.name, _cacheNames()).then((newName) => { - const item = angular.copy($scope.backupItem); - - delete item._id; - - item.name = newName; - - if (!_.isEmpty(item.clusters) && !_.isNil(item.sqlSchema)) { - delete item.sqlSchema; - - const scope = $scope.$new(); - - scope.title = 'Info'; - scope.content = [ - 'Use the same SQL schema name in one cluster in not allowed', - 'SQL schema name will be reset' - ]; - - // Show a basic modal from a controller - $modal({scope, templateUrl: infoMessageTemplateUrl, show: true}); - } - - save(item); - }); - } - }; - - // Remove cache from db. - $scope.removeItem = function() { - const selectedItem = $scope.selectedItem; - - Confirm.confirm('Are you sure you want to remove cache: "' + selectedItem.name + '"?') - .then(function() { - const _id = selectedItem._id; - - $http.post('/api/v1/configuration/caches/remove', {_id}) - .then(() => { - Messages.showInfo('Cache has been removed: ' + selectedItem.name); - - const caches = $scope.caches; - - const idx = _.findIndex(caches, function(cache) { - return cache._id === _id; - }); - - if (idx >= 0) { - caches.splice(idx, 1); - - $scope.ui.inputForm.$setPristine(); - - if (caches.length > 0) - $scope.selectItem(caches[0]); - else - $scope.backupItem = emptyCache; - - _.forEach($scope.clusters, (cluster) => _.remove(cluster.caches, (id) => id === _id)); - _.forEach($scope.domains, (domain) => _.remove(domain.meta.caches, (id) => id === _id)); - } - }) - .catch(Messages.showError); - }); - }; - - // Remove all caches from db. - $scope.removeAllItems = function() { - Confirm.confirm('Are you sure you want to remove all caches?') - .then(function() { - $http.post('/api/v1/configuration/caches/remove/all') - .then(() => { - Messages.showInfo('All caches have been removed'); - - $scope.caches = []; - - _.forEach($scope.clusters, (cluster) => cluster.caches = []); - _.forEach($scope.domains, (domain) => domain.meta.caches = []); - - $scope.backupItem = emptyCache; - $scope.ui.inputForm.$error = {}; - $scope.ui.inputForm.$setPristine(); - }) - .catch(Messages.showError); - }); - }; - - $scope.resetAll = function() { - Confirm.confirm('Are you sure you want to undo all changes for current cache?') - .then(function() { - $scope.backupItem = $scope.selectedItem ? angular.copy($scope.selectedItem) : prepareNewItem(); - $scope.ui.inputForm.$error = {}; - $scope.ui.inputForm.$setPristine(); - }); - }; - } -]; http://git-wip-us.apache.org/repos/asf/ignite/blob/7ee1683e/modules/web-console/frontend/controllers/clusters-controller.js ---------------------------------------------------------------------- diff --git a/modules/web-console/frontend/controllers/clusters-controller.js b/modules/web-console/frontend/controllers/clusters-controller.js deleted file mode 100644 index 24d2c54..0000000 --- a/modules/web-console/frontend/controllers/clusters-controller.js +++ /dev/null @@ -1,1044 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -// Controller for Clusters screen. -export default ['$rootScope', '$scope', '$http', '$state', '$timeout', 'IgniteLegacyUtils', 'IgniteMessages', 'IgniteConfirm', 'IgniteInput', 'IgniteLoading', 'IgniteModelNormalizer', 'IgniteUnsavedChangesGuard', 'IgniteEventGroups', 'DemoInfo', 'IgniteLegacyTable', 'IgniteConfigurationResource', 'IgniteErrorPopover', 'IgniteFormUtils', 'IgniteVersion', 'Clusters', - function($root, $scope, $http, $state, $timeout, LegacyUtils, Messages, Confirm, Input, Loading, ModelNormalizer, UnsavedChangesGuard, igniteEventGroups, DemoInfo, LegacyTable, Resource, ErrorPopover, FormUtils, Version, Clusters) { - let __original_value; - - this.available = Version.available.bind(Version); - - const rebuildDropdowns = () => { - $scope.eventStorage = [ - {value: 'Memory', label: 'Memory'}, - {value: 'Custom', label: 'Custom'} - ]; - - $scope.marshallerVariant = [ - {value: 'JdkMarshaller', label: 'JdkMarshaller'}, - {value: null, label: 'Default'} - ]; - - if (this.available('2.0.0')) { - $scope.eventStorage.push({value: null, label: 'Disabled'}); - - $scope.eventGroups = _.filter(igniteEventGroups, ({value}) => value !== 'EVTS_SWAPSPACE'); - } - else { - $scope.eventGroups = igniteEventGroups; - - $scope.marshallerVariant.splice(0, 0, {value: 'OptimizedMarshaller', label: 'OptimizedMarshaller'}); - } - }; - - rebuildDropdowns(); - - const filterModel = () => { - if ($scope.backupItem) { - if (this.available('2.0.0')) { - const evtGrps = _.map($scope.eventGroups, 'value'); - - _.remove(__original_value, (evtGrp) => !_.includes(evtGrps, evtGrp)); - _.remove($scope.backupItem.includeEventTypes, (evtGrp) => !_.includes(evtGrps, evtGrp)); - - if (_.get($scope.backupItem, 'marshaller.kind') === 'OptimizedMarshaller') - $scope.backupItem.marshaller.kind = null; - } - else if ($scope.backupItem && !_.get($scope.backupItem, 'eventStorage.kind')) - _.set($scope.backupItem, 'eventStorage.kind', 'Memory'); - } - }; - - Version.currentSbj.subscribe({ - next: () => { - rebuildDropdowns(); - - filterModel(); - } - }); - - UnsavedChangesGuard.install($scope); - - const emptyCluster = {empty: true}; - - const blank = Clusters.getBlankCluster(); - - const pairFields = { - attributes: {id: 'Attribute', idPrefix: 'Key', searchCol: 'name', valueCol: 'key', dupObjName: 'name', group: 'attributes'}, - 'collision.JobStealing.stealingAttributes': {id: 'CAttribute', idPrefix: 'Key', searchCol: 'name', valueCol: 'key', dupObjName: 'name', group: 'collision'} - }; - - $scope.tablePairValid = function(item, field, index, stopEdit) { - const pairField = pairFields[field.model]; - - const pairValue = LegacyTable.tablePairValue(field, index); - - if (pairField) { - const model = _.get(item, field.model); - - if (LegacyUtils.isDefined(model)) { - const idx = _.findIndex(model, (pair) => { - return pair[pairField.searchCol] === pairValue[pairField.valueCol]; - }); - - // Found duplicate by key. - if (idx >= 0 && idx !== index) { - if (stopEdit) - return false; - - return ErrorPopover.show(LegacyTable.tableFieldId(index, pairField.idPrefix + pairField.id), 'Attribute with such ' + pairField.dupObjName + ' already exists!', $scope.ui, pairField.group); - } - } - } - - return true; - }; - - $scope.tableSave = function(field, index, stopEdit) { - if (LegacyTable.tablePairSaveVisible(field, index)) - return LegacyTable.tablePairSave($scope.tablePairValid, $scope.backupItem, field, index, stopEdit); - - return true; - }; - - $scope.tableReset = (trySave) => { - const field = LegacyTable.tableField(); - - if (trySave && LegacyUtils.isDefined(field) && !$scope.tableSave(field, LegacyTable.tableEditedRowIndex(), true)) - return false; - - LegacyTable.tableReset(); - - return true; - }; - - $scope.tableNewItem = function(field) { - if ($scope.tableReset(true)) { - if (field.type === 'failoverSpi') { - if (LegacyUtils.isDefined($scope.backupItem.failoverSpi)) - $scope.backupItem.failoverSpi.push({}); - else - $scope.backupItem.failoverSpi = {}; - } - else if (field.type === 'loadBalancingSpi') { - const newLoadBalancing = {Adaptive: { - loadProbe: { - Job: {useAverage: true}, - CPU: { - useAverage: true, - useProcessors: true - }, - ProcessingTime: {useAverage: true} - } - }}; - - if (LegacyUtils.isDefined($scope.backupItem.loadBalancingSpi)) - $scope.backupItem.loadBalancingSpi.push(newLoadBalancing); - else - $scope.backupItem.loadBalancingSpi = [newLoadBalancing]; - } - else if (field.type === 'checkpointSpi') { - const newCheckpointCfg = { - FS: { - directoryPaths: [] - }, - S3: { - awsCredentials: { - kind: 'Basic' - }, - clientConfiguration: { - retryPolicy: { - kind: 'Default' - }, - useReaper: true, - cacheResponseMetadata: true, - useExpectContinue: true, - useThrottleRetries: true - } - } - }; - - if (LegacyUtils.isDefined($scope.backupItem.checkpointSpi)) - $scope.backupItem.checkpointSpi.push(newCheckpointCfg); - else - $scope.backupItem.checkpointSpi = [newCheckpointCfg]; - } - else if (field.type === 'memoryPolicies') - $scope.backupItem.memoryConfiguration.memoryPolicies.push({}); - else if (field.type === 'dataRegions') - $scope.backupItem.dataStorageConfiguration.dataRegionConfigurations.push({}); - else if (field.type === 'serviceConfigurations') - $scope.backupItem.serviceConfigurations.push({}); - else if (field.type === 'executorConfigurations') - $scope.backupItem.executorConfiguration.push({}); - else - LegacyTable.tableNewItem(field); - } - }; - - $scope.tableNewItemActive = LegacyTable.tableNewItemActive; - - $scope.tableStartEdit = function(item, field, index) { - if ($scope.tableReset(true)) - LegacyTable.tableStartEdit(item, field, index, $scope.tableSave); - }; - - $scope.tableEditing = LegacyTable.tableEditing; - - $scope.tableRemove = function(item, field, index) { - if ($scope.tableReset(true)) - LegacyTable.tableRemove(item, field, index); - }; - - $scope.tablePairSave = LegacyTable.tablePairSave; - $scope.tablePairSaveVisible = LegacyTable.tablePairSaveVisible; - - $scope.attributesTbl = { - type: 'attributes', - model: 'attributes', - focusId: 'Attribute', - ui: 'table-pair', - keyName: 'name', - valueName: 'value', - save: $scope.tableSave - }; - - $scope.stealingAttributesTbl = { - type: 'attributes', - model: 'collision.JobStealing.stealingAttributes', - focusId: 'CAttribute', - ui: 'table-pair', - keyName: 'name', - valueName: 'value', - save: $scope.tableSave - }; - - $scope.removeFailoverConfiguration = function(idx) { - $scope.backupItem.failoverSpi.splice(idx, 1); - }; - - $scope.supportedJdbcTypes = LegacyUtils.mkOptions(LegacyUtils.SUPPORTED_JDBC_TYPES); - - // We need to initialize backupItem with empty object in order to properly used from angular directives. - $scope.backupItem = emptyCluster; - - $scope.ui = FormUtils.formUI(); - $scope.ui.activePanels = [0]; - $scope.ui.topPanels = [0]; - - $scope.saveBtnTipText = FormUtils.saveBtnTipText; - $scope.widthIsSufficient = FormUtils.widthIsSufficient; - - $scope.contentVisible = function() { - const item = $scope.backupItem; - - return !item.empty && (!item._id || _.find($scope.displayedRows, {_id: item._id})); - }; - - $scope.toggleExpanded = function() { - $scope.ui.expanded = !$scope.ui.expanded; - - ErrorPopover.hide(); - }; - - $scope.discoveries = [ - {value: 'Vm', label: 'Static IPs'}, - {value: 'Multicast', label: 'Multicast'}, - {value: 'S3', label: 'AWS S3'}, - {value: 'Cloud', label: 'Apache jclouds'}, - {value: 'GoogleStorage', label: 'Google cloud storage'}, - {value: 'Jdbc', label: 'JDBC'}, - {value: 'SharedFs', label: 'Shared filesystem'}, - {value: 'ZooKeeper', label: 'Apache ZooKeeper'}, - {value: 'Kubernetes', label: 'Kubernetes'} - ]; - - $scope.swapSpaceSpis = [ - {value: 'FileSwapSpaceSpi', label: 'File-based swap'}, - {value: null, label: 'Not set'} - ]; - - $scope.affinityFunction = [ - {value: 'Rendezvous', label: 'Rendezvous'}, - {value: 'Custom', label: 'Custom'}, - {value: null, label: 'Default'} - ]; - - $scope.clusters = []; - - function _clusterLbl(cluster) { - return cluster.name + ', ' + _.find($scope.discoveries, {value: cluster.discovery.kind}).label; - } - - function selectFirstItem() { - if ($scope.clusters.length > 0) - $scope.selectItem($scope.clusters[0]); - } - - Loading.start('loadingClustersScreen'); - - // When landing on the page, get clusters and show them. - Resource.read() - .then(({spaces, clusters, caches, domains, igfss}) => { - $scope.spaces = spaces; - - $scope.clusters = clusters; - - $scope.caches = _.map(caches, (cache) => { - cache.domains = _.filter(domains, ({_id}) => _.includes(cache.domains, _id)); - - if (_.get(cache, 'nodeFilter.kind') === 'IGFS') - cache.nodeFilter.IGFS.instance = _.find(igfss, {_id: cache.nodeFilter.IGFS.igfs}); - - return {value: cache._id, label: cache.name, cache}; - }); - - $scope.igfss = _.map(igfss, (igfs) => ({value: igfs._id, label: igfs.name, igfs})); - - _.forEach($scope.clusters, (cluster) => { - cluster.label = _clusterLbl(cluster); - - if (!cluster.collision || !cluster.collision.kind) - cluster.collision = {kind: 'Noop', JobStealing: {stealingEnabled: true}, PriorityQueue: {starvationPreventionEnabled: true}}; - - if (!cluster.failoverSpi) - cluster.failoverSpi = []; - - if (!cluster.logger) - cluster.logger = {Log4j: { mode: 'Default'}}; - - if (!cluster.peerClassLoadingLocalClassPathExclude) - cluster.peerClassLoadingLocalClassPathExclude = []; - - if (!cluster.deploymentSpi) { - cluster.deploymentSpi = {URI: { - uriList: [], - scanners: [] - }}; - } - - if (!cluster.memoryConfiguration) - cluster.memoryConfiguration = { memoryPolicies: [] }; - - if (!cluster.dataStorageConfiguration) - cluster.dataStorageConfiguration = { dataRegionConfigurations: [] }; - - if (!cluster.hadoopConfiguration) - cluster.hadoopConfiguration = { nativeLibraryNames: [] }; - - if (!cluster.serviceConfigurations) - cluster.serviceConfigurations = []; - - if (!cluster.executorConfiguration) - cluster.executorConfiguration = []; - }); - - if ($state.params.linkId) - $scope.createItem($state.params.linkId); - else { - const lastSelectedCluster = angular.fromJson(sessionStorage.lastSelectedCluster); - - if (lastSelectedCluster) { - const idx = _.findIndex($scope.clusters, (cluster) => cluster._id === lastSelectedCluster); - - if (idx >= 0) - $scope.selectItem($scope.clusters[idx]); - else { - sessionStorage.removeItem('lastSelectedCluster'); - - selectFirstItem(); - } - } - else - selectFirstItem(); - } - - $scope.$watch('ui.inputForm.$valid', function(valid) { - if (valid && ModelNormalizer.isEqual(__original_value, $scope.backupItem)) - $scope.ui.inputForm.$dirty = false; - }); - - $scope.$watch('backupItem', function(val) { - if (!$scope.ui.inputForm) - return; - - const form = $scope.ui.inputForm; - - if (form.$valid && ModelNormalizer.isEqual(__original_value, val)) - form.$setPristine(); - else - form.$setDirty(); - - $scope.clusterCaches = _.filter($scope.caches, - (cache) => _.find($scope.backupItem.caches, - (selCache) => selCache === cache.value - ) - ); - - $scope.clusterCachesEmpty = _.clone($scope.clusterCaches); - $scope.clusterCachesEmpty.push({label: 'Not set'}); - }, true); - - $scope.$watch('ui.activePanels.length', () => { - ErrorPopover.hide(); - }); - - if ($root.IgniteDemoMode && sessionStorage.showDemoInfo !== 'true') { - sessionStorage.showDemoInfo = 'true'; - - DemoInfo.show(); - } - }) - .catch(Messages.showError) - .then(() => { - $scope.ui.ready = true; - $scope.ui.inputForm && $scope.ui.inputForm.$setPristine(); - - Loading.finish('loadingClustersScreen'); - }); - - $scope.clusterCaches = []; - $scope.clusterCachesEmpty = []; - - $scope.selectItem = function(item, backup) { - function selectItem() { - $scope.selectedItem = item; - - try { - if (item && item._id) - sessionStorage.lastSelectedCluster = angular.toJson(item._id); - else - sessionStorage.removeItem('lastSelectedCluster'); - } - catch (ignored) { - // No-op. - } - - if (backup) - $scope.backupItem = backup; - else if (item) - $scope.backupItem = angular.copy(item); - else - $scope.backupItem = emptyCluster; - - $scope.backupItem = _.merge({}, blank, $scope.backupItem); - - if ($scope.ui.inputForm) { - $scope.ui.inputForm.$error = {}; - $scope.ui.inputForm.$setPristine(); - } - - __original_value = ModelNormalizer.normalize($scope.backupItem); - - filterModel(); - - if (LegacyUtils.getQueryVariable('new')) - $state.go('base.configuration.tabs.advanced.clusters'); - } - - FormUtils.confirmUnsavedChanges($scope.backupItem && $scope.ui.inputForm && $scope.ui.inputForm.$dirty, selectItem); - }; - - $scope.linkId = () => $scope.backupItem._id ? $scope.backupItem._id : 'create'; - - function prepareNewItem(linkId) { - return _.merge({}, blank, { - space: $scope.spaces[0]._id, - discovery: { - kind: 'Multicast', - Vm: {addresses: ['127.0.0.1:47500..47510']}, - Multicast: {addresses: ['127.0.0.1:47500..47510']}, - Jdbc: {initSchema: true} - }, - binaryConfiguration: {typeConfigurations: [], compactFooter: true}, - communication: {tcpNoDelay: true}, - connector: {noDelay: true}, - collision: {kind: 'Noop', JobStealing: {stealingEnabled: true}, PriorityQueue: {starvationPreventionEnabled: true}}, - failoverSpi: [], - logger: {Log4j: { mode: 'Default'}}, - caches: linkId && _.find($scope.caches, {value: linkId}) ? [linkId] : [], - igfss: linkId && _.find($scope.igfss, {value: linkId}) ? [linkId] : [], - clientConnectorConfiguration: { - tcpNoDelay: true, - jdbcEnabled: true, - odbcEnabled: true, - thinClientEnabled: true, - useIgniteSslContextFactory: true - } - }); - } - - // Add new cluster. - $scope.createItem = function(linkId) { - $timeout(() => FormUtils.ensureActivePanel($scope.ui, 'general', 'clusterNameInput')); - - $scope.selectItem(null, prepareNewItem(linkId)); - }; - - $scope.indexOfCache = function(cacheId) { - return _.findIndex($scope.caches, (cache) => cache.value === cacheId); - }; - - function clusterCaches(item) { - return _.filter(_.map($scope.caches, (scopeCache) => scopeCache.cache), - (cache) => _.includes(item.caches, cache._id)); - } - - const _objToString = (type, name, prefix = '') => { - if (type === 'checkpoint') - return prefix + ' checkpoint configuration'; - if (type === 'cluster') - return prefix + ' discovery IP finder'; - - return `${prefix} ${type} "${name}"`; - }; - - function checkCacheDatasources(item) { - const caches = clusterCaches(item); - - const checkRes = LegacyUtils.checkDataSources(item, caches); - - if (!checkRes.checked) { - let ids; - - if (checkRes.secondType === 'cluster') - ids = { section: 'general', fieldId: 'dialectInput' }; - else if (checkRes.secondType === 'cache') - ids = { section: 'general', fieldId: 'cachesInput' }; - else if (checkRes.secondType === 'checkpoint') - ids = { section: 'checkpoint', fieldId: `checkpointJdbcDialect${checkRes.index}Input` }; - else - return true; - - if (checkRes.firstType === checkRes.secondType && checkRes.firstType === 'cache') { - return ErrorPopover.show(ids.fieldId, 'Found caches "' + checkRes.firstObj.name + '" and "' + checkRes.secondObj.name + '" with the same data source bean name "' + - checkRes.firstDs.dataSourceBean + '" and different database: "' + - LegacyUtils.cacheStoreJdbcDialectsLabel(checkRes.secondDs.dialect) + '" in ' + _objToString(checkRes.secondType, checkRes.secondObj.name) + ' and "' + - LegacyUtils.cacheStoreJdbcDialectsLabel(checkRes.firstDs.dialect) + '" in ' + _objToString(checkRes.firstType, checkRes.firstObj.name), - $scope.ui, ids.section, 10000); - } - - return ErrorPopover.show(ids.fieldId, 'Found ' + _objToString(checkRes.firstType, checkRes.firstObj.name) + ' with the same data source bean name "' + - checkRes.firstDs.dataSourceBean + '" and different database: "' + - LegacyUtils.cacheStoreJdbcDialectsLabel(checkRes.secondDs.dialect) + '" in ' + _objToString(checkRes.secondType, checkRes.secondObj.name, 'current') + ' and "' + - LegacyUtils.cacheStoreJdbcDialectsLabel(checkRes.firstDs.dialect) + '" in ' + _objToString(checkRes.firstType, checkRes.firstObj.name), - $scope.ui, ids.section, 10000); - } - - return true; - } - - function checkCacheSQLSchemas(item) { - const caches = clusterCaches(item); - - const checkRes = LegacyUtils.checkCacheSQLSchemas(caches); - - if (!checkRes.checked) { - return ErrorPopover.show('cachesInput', - 'Found caches "' + checkRes.firstCache.name + '" and "' + checkRes.secondCache.name + '" ' + - 'with the same SQL schema name "' + checkRes.firstCache.sqlSchema + '"', - $scope.ui, 'general', 10000); - } - - return true; - } - - function checkBinaryConfiguration(item) { - const b = item.binaryConfiguration; - - if (LegacyUtils.isDefined(b)) { - if (!_.isEmpty(b.typeConfigurations)) { - for (let typeIx = 0; typeIx < b.typeConfigurations.length; typeIx++) { - const type = b.typeConfigurations[typeIx]; - - if (LegacyUtils.isEmptyString(type.typeName)) - return ErrorPopover.show('typeName' + typeIx + 'Input', 'Type name should be specified!', $scope.ui, 'binary'); - - if (_.find(b.typeConfigurations, (t, ix) => ix < typeIx && t.typeName === type.typeName)) - return ErrorPopover.show('typeName' + typeIx + 'Input', 'Type with such name is already specified!', $scope.ui, 'binary'); - } - } - } - - return true; - } - - function checkCacheKeyConfiguration(item) { - const cfgs = item.cacheKeyConfiguration; - - if (_.isEmpty(cfgs)) - return true; - - for (let typeIx = 0; typeIx < cfgs.length; typeIx++) { - const type = cfgs[typeIx]; - - if (LegacyUtils.isEmptyString(type.typeName)) - return ErrorPopover.show('cacheKeyTypeName' + typeIx + 'Input', 'Cache type configuration name should be specified!', $scope.ui, 'cacheKeyCfg'); - - if (_.find(cfgs, (t, ix) => ix < typeIx && t.typeName === type.typeName)) - return ErrorPopover.show('cacheKeyTypeName' + typeIx + 'Input', 'Cache type configuration with such name is already specified!', $scope.ui, 'cacheKeyCfg'); - } - - return true; - } - - function checkCheckpointSpis(item) { - const cfgs = item.checkpointSpi; - - if (_.isEmpty(cfgs)) - return true; - - return _.isNil(_.find(cfgs, (cfg, ix) => { - if (_.isNil(cfg.kind)) { - ErrorPopover.show('checkpointKind' + ix, 'Choose checkpoint implementation variant', $scope.ui, 'checkpoint'); - - return true; - } - - switch (cfg.kind) { - case 'Cache': - const cache = _.get(cfg, 'Cache.cache'); - - if (_.isNil(cache) || !_.find($scope.backupItem.caches, (selCache) => cache === selCache)) { - ErrorPopover.show('checkpointCacheCache' + ix, 'Choose cache from configured cluster caches', $scope.ui, 'checkpoint'); - - return true; - } - - break; - - default: break; - } - - return false; - })); - } - - function checkCommunicationConfiguration(item) { - const c = item.communication; - - if (LegacyUtils.isDefined(c)) { - if (LegacyUtils.isDefined(c.unacknowledgedMessagesBufferSize)) { - if (LegacyUtils.isDefined(c.messageQueueLimit) && c.unacknowledgedMessagesBufferSize < 5 * c.messageQueueLimit) - return ErrorPopover.show('unacknowledgedMessagesBufferSizeInput', 'Maximum number of stored unacknowledged messages should be at least 5 * message queue limit!', $scope.ui, 'communication'); - - if (LegacyUtils.isDefined(c.ackSendThreshold) && c.unacknowledgedMessagesBufferSize < 5 * c.ackSendThreshold) - return ErrorPopover.show('unacknowledgedMessagesBufferSizeInput', 'Maximum number of stored unacknowledged messages should be at least 5 * ack send threshold!', $scope.ui, 'communication'); - } - - if (c.sharedMemoryPort === 0) - return ErrorPopover.show('sharedMemoryPortInput', 'Shared memory port should be more than "0" or equals to "-1"!', $scope.ui, 'communication'); - } - - return true; - } - - function checkDiscoveryConfiguration(item) { - const d = item.discovery; - - if (d) { - if ((_.isNil(d.maxAckTimeout) ? 600000 : d.maxAckTimeout) < (d.ackTimeout || 5000)) - return ErrorPopover.show('ackTimeoutInput', 'Acknowledgement timeout should be less than max acknowledgement timeout!', $scope.ui, 'discovery'); - - if (d.kind === 'Vm' && d.Vm && d.Vm.addresses.length === 0) - return ErrorPopover.show('addresses', 'Addresses are not specified!', $scope.ui, 'general'); - } - - return true; - } - - function checkLoadBalancingConfiguration(item) { - const balancingSpis = item.loadBalancingSpi; - - return _.isNil(_.find(balancingSpis, (curSpi, curIx) => { - if (_.find(balancingSpis, (spi, ix) => curIx > ix && curSpi.kind === spi.kind)) { - ErrorPopover.show('loadBalancingKind' + curIx, 'Load balancing SPI of that type is already configured', $scope.ui, 'loadBalancing'); - - return true; - } - - return false; - })); - } - - function checkMemoryConfiguration(item) { - const memory = item.memoryConfiguration; - - if ((memory.systemCacheMaxSize || 104857600) < (memory.systemCacheInitialSize || 41943040)) - return ErrorPopover.show('systemCacheMaxSize', 'System cache maximum size should be greater than initial size', $scope.ui, 'memoryConfiguration'); - - const pageSize = memory.pageSize; - - if (pageSize > 0 && (pageSize & (pageSize - 1) !== 0)) { - ErrorPopover.show('MemoryConfigurationPageSize', 'Page size must be power of 2', $scope.ui, 'memoryConfiguration'); - - return false; - } - - const dfltPlc = memory.defaultMemoryPolicyName; - - if (!_.isEmpty(dfltPlc) && !_.find(memory.memoryPolicies, (plc) => plc.name === dfltPlc)) - return ErrorPopover.show('defaultMemoryPolicyName', 'Memory policy with that name should be configured', $scope.ui, 'memoryConfiguration'); - - return _.isNil(_.find(memory.memoryPolicies, (curPlc, curIx) => { - if (curPlc.name === 'sysMemPlc') { - ErrorPopover.show('MemoryPolicyName' + curIx, '"sysMemPlc" policy name is reserved for internal use', $scope.ui, 'memoryConfiguration'); - - return true; - } - - if (_.find(memory.memoryPolicies, (plc, ix) => curIx > ix && (curPlc.name || 'default') === (plc.name || 'default'))) { - ErrorPopover.show('MemoryPolicyName' + curIx, 'Memory policy with that name is already configured', $scope.ui, 'memoryConfiguration'); - - return true; - } - - if (curPlc.maxSize && curPlc.maxSize < (curPlc.initialSize || 268435456)) { - ErrorPopover.show('MemoryPolicyMaxSize' + curIx, 'Maximum size should be greater than initial size', $scope.ui, 'memoryConfiguration'); - - return true; - } - - if (curPlc.maxSize) { - const maxPoolSize = Math.floor(curPlc.maxSize / (memory.pageSize || 2048) / 10); - - if (maxPoolSize < (curPlc.emptyPagesPoolSize || 100)) { - ErrorPopover.show('MemoryPolicyEmptyPagesPoolSize' + curIx, 'Evicted pages pool size should be lesser than ' + maxPoolSize, $scope.ui, 'memoryConfiguration'); - - return true; - } - } - - return false; - })); - } - - function checkDataStorageConfiguration(item) { - const dataStorage = item.dataStorageConfiguration; - - if ((dataStorage.systemRegionMaxSize || 104857600) < (dataStorage.systemRegionInitialSize || 41943040)) - return ErrorPopover.show('DataStorageSystemRegionMaxSize', 'System data region maximum size should be greater than initial size', $scope.ui, 'dataStorageConfiguration'); - - const pageSize = dataStorage.pageSize; - - if (pageSize > 0 && (pageSize & (pageSize - 1) !== 0)) { - ErrorPopover.show('DataStorageConfigurationPageSize', 'Page size must be power of 2', $scope.ui, 'dataStorageConfiguration'); - - return false; - } - - return _.isNil(_.find(dataStorage.dataRegionConfigurations, (curPlc, curIx) => { - if (curPlc.name === 'sysMemPlc') { - ErrorPopover.show('DfltRegionPolicyName' + curIx, '"sysMemPlc" policy name is reserved for internal use', $scope.ui, 'dataStorageConfiguration'); - - return true; - } - - if (_.find(dataStorage.dataRegionConfigurations, (plc, ix) => curIx > ix && (curPlc.name || 'default') === (plc.name || 'default'))) { - ErrorPopover.show('DfltRegionPolicyName' + curIx, 'Data region with that name is already configured', $scope.ui, 'dataStorageConfiguration'); - - return true; - } - - if (curPlc.maxSize && curPlc.maxSize < (curPlc.initialSize || 268435456)) { - ErrorPopover.show('DfltRegionPolicyMaxSize' + curIx, 'Maximum size should be greater than initial size', $scope.ui, 'dataStorageConfiguration'); - - return true; - } - - if (curPlc.maxSize) { - const maxPoolSize = Math.floor(curPlc.maxSize / (dataStorage.pageSize || 2048) / 10); - - if (maxPoolSize < (curPlc.emptyPagesPoolSize || 100)) { - ErrorPopover.show('DfltRegionPolicyEmptyPagesPoolSize' + curIx, 'Evicted pages pool size should be lesser than ' + maxPoolSize, $scope.ui, 'dataStorageConfiguration'); - - return true; - } - } - - return false; - })); - } - - function checkODBC(item) { - if (_.get(item, 'odbc.odbcEnabled') && _.get(item, 'marshaller.kind')) - return ErrorPopover.show('odbcEnabledInput', 'ODBC can only be used with BinaryMarshaller', $scope.ui, 'odbcConfiguration'); - - return true; - } - - function checkSwapConfiguration(item) { - const swapKind = item.swapSpaceSpi && item.swapSpaceSpi.kind; - - if (swapKind && item.swapSpaceSpi[swapKind]) { - const swap = item.swapSpaceSpi[swapKind]; - - const sparsity = swap.maximumSparsity; - - if (LegacyUtils.isDefined(sparsity) && (sparsity < 0 || sparsity >= 1)) - return ErrorPopover.show('maximumSparsityInput', 'Maximum sparsity should be more or equal 0 and less than 1!', $scope.ui, 'swap'); - - const readStripesNumber = swap.readStripesNumber; - - if (readStripesNumber && !(readStripesNumber === -1 || (readStripesNumber & (readStripesNumber - 1)) === 0)) - return ErrorPopover.show('readStripesNumberInput', 'Read stripe size must be positive and power of two!', $scope.ui, 'swap'); - } - - return true; - } - - function checkServiceConfiguration(item) { - return _.isNil(_.find(_.get(item, 'serviceConfigurations'), (curSrv, curIx) => { - if (_.find(item.serviceConfigurations, (srv, ix) => curIx > ix && curSrv.name === srv.name)) { - ErrorPopover.show('ServiceName' + curIx, 'Service configuration with that name is already configured', $scope.ui, 'serviceConfiguration'); - - return true; - } - - return false; - })); - } - - function checkSslConfiguration(item) { - const r = item.connector; - - if (LegacyUtils.isDefined(r)) { - if (r.sslEnabled && LegacyUtils.isEmptyString(r.sslFactory)) - return ErrorPopover.show('connectorSslFactoryInput', 'SSL factory should not be empty!', $scope.ui, 'connector'); - } - - if (item.sslEnabled) { - if (!LegacyUtils.isDefined(item.sslContextFactory) || LegacyUtils.isEmptyString(item.sslContextFactory.keyStoreFilePath)) - return ErrorPopover.show('keyStoreFilePathInput', 'Key store file should not be empty!', $scope.ui, 'sslConfiguration'); - - if (LegacyUtils.isEmptyString(item.sslContextFactory.trustStoreFilePath) && _.isEmpty(item.sslContextFactory.trustManagers)) - return ErrorPopover.show('sslConfiguration-title', 'Trust storage file or managers should be configured!', $scope.ui, 'sslConfiguration'); - } - - return true; - } - - function checkPoolSizes(item) { - if (item.rebalanceThreadPoolSize && item.systemThreadPoolSize && item.systemThreadPoolSize <= item.rebalanceThreadPoolSize) - return ErrorPopover.show('rebalanceThreadPoolSizeInput', 'Rebalance thread pool size exceed or equals System thread pool size!', $scope.ui, 'pools'); - - return _.isNil(_.find(_.get(item, 'executorConfiguration'), (curExec, curIx) => { - if (_.find(item.executorConfiguration, (srv, ix) => curIx > ix && curExec.name === srv.name)) { - ErrorPopover.show('ExecutorName' + curIx, 'Executor configuration with that name is already configured', $scope.ui, 'pools'); - - return true; - } - - return false; - })); - } - - // Check cluster logical consistency. - this.validate = (item) => { - ErrorPopover.hide(); - - if (LegacyUtils.isEmptyString(item.name)) - return ErrorPopover.show('clusterNameInput', 'Cluster name should not be empty!', $scope.ui, 'general'); - - if (!LegacyUtils.checkFieldValidators($scope.ui)) - return false; - - if (!checkCacheSQLSchemas(item)) - return false; - - if (!checkCacheDatasources(item)) - return false; - - if (!checkBinaryConfiguration(item)) - return false; - - if (!checkCacheKeyConfiguration(item)) - return false; - - if (!checkCheckpointSpis(item)) - return false; - - if (!checkCommunicationConfiguration(item)) - return false; - - if (!this.available('2.3.0') && !checkDataStorageConfiguration(item)) - return false; - - if (!checkDiscoveryConfiguration(item)) - return false; - - if (!checkLoadBalancingConfiguration(item)) - return false; - - if (this.available(['2.0.0', '2.3.0']) && !checkMemoryConfiguration(item)) - return false; - - if (!checkODBC(item)) - return false; - - if (!checkSwapConfiguration(item)) - return false; - - if (!checkServiceConfiguration(item)) - return false; - - if (!checkSslConfiguration(item)) - return false; - - if (!checkPoolSizes(item)) - return false; - - return true; - }; - - // Save cluster in database. - function save(item) { - $http.post('/api/v1/configuration/clusters/save', item) - .then(({data}) => { - const _id = data; - - item.label = _clusterLbl(item); - - $scope.ui.inputForm.$setPristine(); - - const idx = _.findIndex($scope.clusters, {_id}); - - if (idx >= 0) - _.assign($scope.clusters[idx], item); - else { - item._id = _id; - - $scope.clusters.push(item); - } - - _.forEach($scope.caches, (cache) => { - if (_.includes(item.caches, cache.value)) - cache.cache.clusters = _.union(cache.cache.clusters, [_id]); - else - _.pull(cache.cache.clusters, _id); - }); - - _.forEach($scope.igfss, (igfs) => { - if (_.includes(item.igfss, igfs.value)) - igfs.igfs.clusters = _.union(igfs.igfs.clusters, [_id]); - else - _.pull(igfs.igfs.clusters, _id); - }); - - $scope.selectItem(item); - - Messages.showInfo(`Cluster "${item.name}" saved.`); - }) - .catch(Messages.showError); - } - - // Save cluster. - $scope.saveItem = () => { - const item = $scope.backupItem; - - const swapConfigured = item.swapSpaceSpi && item.swapSpaceSpi.kind; - - if (!swapConfigured && _.find(clusterCaches(item), (cache) => cache.swapEnabled)) - _.merge(item, {swapSpaceSpi: {kind: 'FileSwapSpaceSpi'}}); - - if (this.validate(item)) - save(item); - }; - - function _clusterNames() { - return _.map($scope.clusters, (cluster) => cluster.name); - } - - // Clone cluster with new name. - $scope.cloneItem = () => { - if (this.validate($scope.backupItem)) { - Input.clone($scope.backupItem.name, _clusterNames()).then((newName) => { - const item = angular.copy($scope.backupItem); - - delete item._id; - item.name = newName; - - save(item); - }); - } - }; - - // Remove cluster from db. - $scope.removeItem = function() { - const selectedItem = $scope.selectedItem; - - Confirm.confirm('Are you sure you want to remove cluster: "' + selectedItem.name + '"?') - .then(function() { - const _id = selectedItem._id; - - $http.post('/api/v1/configuration/clusters/remove', {_id}) - .then(() => { - Messages.showInfo('Cluster has been removed: ' + selectedItem.name); - - const clusters = $scope.clusters; - - const idx = _.findIndex(clusters, (cluster) => cluster._id === _id); - - if (idx >= 0) { - clusters.splice(idx, 1); - - $scope.ui.inputForm.$setPristine(); - - if (clusters.length > 0) - $scope.selectItem(clusters[0]); - else - $scope.backupItem = emptyCluster; - - _.forEach($scope.caches, (cache) => _.remove(cache.cache.clusters, (id) => id === _id)); - _.forEach($scope.igfss, (igfs) => _.remove(igfs.igfs.clusters, (id) => id === _id)); - } - }) - .catch(Messages.showError); - }); - }; - - // Remove all clusters from db. - $scope.removeAllItems = function() { - Confirm.confirm('Are you sure you want to remove all clusters?') - .then(function() { - $http.post('/api/v1/configuration/clusters/remove/all') - .then(() => { - Messages.showInfo('All clusters have been removed'); - - $scope.clusters = []; - - _.forEach($scope.caches, (cache) => cache.cache.clusters = []); - _.forEach($scope.igfss, (igfs) => igfs.igfs.clusters = []); - - $scope.backupItem = emptyCluster; - $scope.ui.inputForm.$error = {}; - $scope.ui.inputForm.$setPristine(); - }) - .catch(Messages.showError); - }); - }; - - $scope.resetAll = function() { - Confirm.confirm('Are you sure you want to undo all changes for current cluster?') - .then(function() { - $scope.backupItem = $scope.selectedItem ? angular.copy($scope.selectedItem) : prepareNewItem(); - $scope.ui.inputForm.$error = {}; - $scope.ui.inputForm.$setPristine(); - }); - }; - } -];
