You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by ak...@apache.org on 2018/04/12 04:12:00 UTC

[16/17] ignite git commit: IGNITE-7996 Move configuration assets into page-configure module.

IGNITE-7996 Move configuration assets into page-configure module.


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/d02e87b9
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/d02e87b9
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/d02e87b9

Branch: refs/heads/master
Commit: d02e87b9dafd95bf13fa52b7d7e5bc75bec3303b
Parents: 14dd2df
Author: Ilya Borisov <Kl...@gmail.com>
Authored: Fri Apr 6 11:22:20 2018 +0700
Committer: Ilya Borisov <Kl...@gmail.com>
Committed: Fri Apr 6 11:22:20 2018 +0700

----------------------------------------------------------------------
 modules/web-console/frontend/app/app.js         |   2 -
 .../components/preview-panel/directive.js       | 246 +++++++++++++++++++
 .../components/preview-panel/index.js           |  23 ++
 .../app/components/page-configure/index.js      |  25 +-
 .../services/ConfigurationResource.js           |  49 ++++
 .../page-configure/services/SummaryZipper.js    |  44 ++++
 .../page-configure/services/summary.worker.js   | 147 +++++++++++
 .../configuration/Configuration.resource.js     |  42 ----
 .../configuration/preview-panel.directive.js    | 239 ------------------
 .../summary/summary-zipper.service.js           |  39 ---
 .../configuration/summary/summary.worker.js     | 147 -----------
 11 files changed, 533 insertions(+), 470 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/d02e87b9/modules/web-console/frontend/app/app.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/app.js b/modules/web-console/frontend/app/app.js
index 757be22..692acc5 100644
--- a/modules/web-console/frontend/app/app.js
+++ b/modules/web-console/frontend/app/app.js
@@ -27,7 +27,6 @@ import './modules/nodes/nodes.module';
 import './modules/demo/Demo.module';
 
 import './modules/states/logout.state';
-import './modules/states/configuration.state';
 import './modules/states/admin.state';
 import './modules/states/errors.state';
 
@@ -192,7 +191,6 @@ angular.module('ignite-console', [
     'ignite-console.demo',
     // States.
     'ignite-console.states.logout',
-    'ignite-console.states.configuration',
     'ignite-console.states.admin',
     'ignite-console.states.errors',
     // Common modules.

http://git-wip-us.apache.org/repos/asf/ignite/blob/d02e87b9/modules/web-console/frontend/app/components/page-configure/components/preview-panel/directive.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/components/page-configure/components/preview-panel/directive.js b/modules/web-console/frontend/app/components/page-configure/components/preview-panel/directive.js
new file mode 100644
index 0000000..b7519ce
--- /dev/null
+++ b/modules/web-console/frontend/app/components/page-configure/components/preview-panel/directive.js
@@ -0,0 +1,246 @@
+/*
+ * 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 ace from 'brace';
+import _ from 'lodash';
+
+/**
+ * @param {ng.IIntervalService} $interval
+ * @param {ng.ITimeoutService} $timeout
+ */
+export default function previewPanelDirective($interval, $timeout) {
+    let animation = {editor: null, stage: 0, start: 0, stop: 0};
+    let prevContent = [];
+
+    const Range = ace.acequire('ace/range').Range;
+
+    const _clearSelection = (editor) => {
+        _.forEach(editor.session.getMarkers(false), (marker) => {
+            editor.session.removeMarker(marker.id);
+        });
+    };
+
+    /**
+     * Switch to next stage of animation.
+     */
+    const _animate = () => {
+        animation.stage += animation.step;
+
+        const stage = animation.stage;
+        const editor = animation.editor;
+
+        _clearSelection(editor);
+
+        animation.selections.forEach((selection) => {
+            editor.session.addMarker(new Range(selection.start, 0, selection.stop, 0),
+                'preview-highlight-' + stage, 'line', false);
+        });
+
+        if (stage === animation.finalStage) {
+            editor.animatePromise = null;
+
+            if (animation.clearOnFinal)
+                _clearSelection(editor);
+        }
+    };
+
+    /**
+     * Selection with animation.
+     *
+     * @param editor Editor to show selection animation.
+     * @param selections Array of selection intervals.
+     * @param step Step of animation (1 or -1).
+     * @param stage Start stage of animation.
+     * @param finalStage Final stage of animation.
+     * @param clearOnFinal Boolean flat to clear selection on animation finish.
+     */
+    const _fade = (editor, selections, step, stage, finalStage, clearOnFinal) => {
+        const promise = editor.animatePromise;
+
+        if (promise) {
+            $interval.cancel(promise);
+
+            _clearSelection(editor);
+        }
+
+        animation = {editor, selections, step, stage, finalStage, clearOnFinal};
+
+        editor.animatePromise = $interval(_animate, 100, 10, false);
+    };
+
+    /**
+     * Show selections with animation.
+     *
+     * @param editor Editor to show selection.
+     * @param selections Array of selection intervals.
+     */
+    const _fadeIn = (editor, selections) => {
+        _fade(editor, selections, 1, 0, 10, false);
+    };
+
+    /**
+     * Hide selections with animation.
+     *
+     * @param editor Editor to show selection.
+     * @param selections Array of selection intervals.
+     */
+    const _fadeOut = (editor, selections) => {
+        _fade(editor, selections, -1, 10, 0, true);
+    };
+
+    const onChange = ([content, editor]) => {
+        const {clearPromise} = editor;
+        const {lines} = content;
+
+        if (content.action === 'remove')
+            prevContent = lines;
+        else if (prevContent.length > 0 && lines.length > 0 && editor.attractAttention) {
+            if (clearPromise) {
+                $timeout.cancel(clearPromise);
+
+                _clearSelection(editor);
+            }
+
+            const selections = [];
+
+            let newIx = 0;
+            let prevIx = 0;
+
+            let prevLen = prevContent.length - (prevContent[prevContent.length - 1] === '' ? 1 : 0);
+            let newLen = lines.length - (lines[lines.length - 1] === '' ? 1 : 0);
+
+            const removed = newLen < prevLen;
+
+            let skipEnd = 0;
+
+            let selected = false;
+            let scrollTo = -1;
+
+            while (lines[newLen - 1] === prevContent[prevLen - 1] && newLen > 0 && prevLen > 0) {
+                prevLen -= 1;
+                newLen -= 1;
+
+                skipEnd += 1;
+            }
+
+            while (newIx < newLen || prevIx < prevLen) {
+                let start = -1;
+                let stop = -1;
+
+                // Find an index of a first line with different text.
+                for (; (newIx < newLen || prevIx < prevLen) && start < 0; newIx++, prevIx++) {
+                    if (newIx >= newLen || prevIx >= prevLen || lines[newIx] !== prevContent[prevIx]) {
+                        start = newIx;
+
+                        break;
+                    }
+                }
+
+                if (start >= 0) {
+                    // Find an index of a last line with different text by checking last string of old and new content in reverse order.
+                    for (let i = start; i < newLen && stop < 0; i++) {
+                        for (let j = prevIx; j < prevLen && stop < 0; j++) {
+                            if (lines[i] === prevContent[j] && lines[i] !== '') {
+                                stop = i;
+
+                                newIx = i;
+                                prevIx = j;
+
+                                break;
+                            }
+                        }
+                    }
+
+                    if (stop < 0) {
+                        stop = newLen;
+
+                        newIx = newLen;
+                        prevIx = prevLen;
+                    }
+
+                    if (start === stop) {
+                        if (removed)
+                            start = Math.max(0, start - 1);
+
+                        stop = Math.min(newLen + skipEnd, stop + 1);
+                    }
+
+                    if (start <= stop) {
+                        selections.push({start, stop});
+
+                        if (!selected)
+                            scrollTo = start;
+
+                        selected = true;
+                    }
+                }
+            }
+
+            // Run clear selection one time.
+            if (selected) {
+                _fadeIn(editor, selections);
+
+                editor.clearPromise = $timeout(() => {
+                    _fadeOut(editor, selections);
+
+                    editor.clearPromise = null;
+                }, 2000);
+
+                editor.scrollToRow(scrollTo);
+            }
+
+            prevContent = [];
+        }
+        else
+            editor.attractAttention = true;
+    };
+
+
+    const link = (scope, $element, $attrs, [igniteUiAceTabs1, igniteUiAceTabs2]) => {
+        const igniteUiAceTabs = igniteUiAceTabs1 || igniteUiAceTabs2;
+
+        if (!igniteUiAceTabs)
+            return;
+
+        igniteUiAceTabs.onLoad = (editor) => {
+            editor.setReadOnly(true);
+            editor.setOption('highlightActiveLine', false);
+            editor.setAutoScrollEditorIntoView(true);
+            editor.$blockScrolling = Infinity;
+            editor.attractAttention = false;
+
+            const renderer = editor.renderer;
+
+            renderer.setHighlightGutterLine(false);
+            renderer.setShowPrintMargin(false);
+            renderer.setOption('fontSize', '10px');
+            renderer.setOption('maxLines', '50');
+
+            editor.setTheme('ace/theme/chrome');
+        };
+
+        igniteUiAceTabs.onChange = onChange;
+    };
+
+    return {
+        restrict: 'C',
+        link,
+        require: ['?igniteUiAceTabs', '?^igniteUiAceTabs']
+    };
+}
+
+previewPanelDirective.$inject = ['$interval', '$timeout'];

http://git-wip-us.apache.org/repos/asf/ignite/blob/d02e87b9/modules/web-console/frontend/app/components/page-configure/components/preview-panel/index.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/components/page-configure/components/preview-panel/index.js b/modules/web-console/frontend/app/components/page-configure/components/preview-panel/index.js
new file mode 100644
index 0000000..ff1367b
--- /dev/null
+++ b/modules/web-console/frontend/app/components/page-configure/components/preview-panel/index.js
@@ -0,0 +1,23 @@
+/*
+ * 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 angular from 'angular';
+import directive from './directive';
+
+export default angular
+    .module('ignite-console.page-configure.preview-panel', [])
+    .directive('previewPanel', directive);

http://git-wip-us.apache.org/repos/asf/ignite/blob/d02e87b9/modules/web-console/frontend/app/components/page-configure/index.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/components/page-configure/index.js b/modules/web-console/frontend/app/components/page-configure/index.js
index 5874df5..3209ede 100644
--- a/modules/web-console/frontend/app/components/page-configure/index.js
+++ b/modules/web-console/frontend/app/components/page-configure/index.js
@@ -28,6 +28,8 @@ import PageConfigure from './services/PageConfigure';
 import ConfigurationDownload from './services/ConfigurationDownload';
 import ConfigChangesGuard from './services/ConfigChangesGuard';
 import ConfigSelectionManager from './services/ConfigSelectionManager';
+import SummaryZipper from './services/SummaryZipper';
+import ConfigurationResource from './services/ConfigurationResource';
 import selectors from './store/selectors';
 import effects from './store/effects';
 
@@ -43,8 +45,10 @@ import modalImportModels from './components/modal-import-models';
 import buttonImportModels from './components/button-import-models';
 import buttonDownloadProject from './components/button-download-project';
 import buttonPreviewProject from './components/button-preview-project';
+import previewPanel from './components/preview-panel';
 
 import {errorState} from './transitionHooks/errorState';
+import {default as ActivitiesData} from 'app/core/activities/Activities.data';
 
 import 'rxjs/add/operator/withLatestFrom';
 import 'rxjs/add/operator/skip';
@@ -73,10 +77,24 @@ import {
     shortIGFSsActionTypes,
     refsReducer
 } from './reducer';
+
 import {reducer as reduxDevtoolsReducer, devTools} from './reduxDevtoolsIntegration';
+import {registerStates} from './states';
+
+/**
+ * @param {ActivitiesData} ActivitiesData
+ * @param {uirouter.UIRouter} $uiRouter
+ */
+function registerActivitiesHook(ActivitiesData, $uiRouter) {
+    $uiRouter.transitionService.onSuccess({to: 'base.configuration.**'}, (transition) => {
+        ActivitiesData.post({group: 'configuration', action: transition.targetState().name()});
+    });
+}
+registerActivitiesHook.$inject = ['IgniteActivitiesData', '$uiRouter'];
 
 export default angular
     .module('ignite-console.page-configure', [
+        'ui.router',
         'asyncFilter',
         uiValidate,
         pcFormFieldSize.name,
@@ -87,11 +105,14 @@ export default angular
         modalImportModels.name,
         buttonImportModels.name,
         buttonDownloadProject.name,
-        buttonPreviewProject.name
+        buttonPreviewProject.name,
+        previewPanel.name
     ])
+    .config(registerStates)
     .config(['DefaultStateProvider', (DefaultState) => {
         DefaultState.setRedirectTo(() => 'base.configuration.overview');
     }])
+    .run(registerActivitiesHook)
     .run(['ConfigEffects', 'ConfigureState', '$uiRouter', (ConfigEffects, ConfigureState, $uiRouter) => {
         $uiRouter.plugin(UIRouterRx);
         // $uiRouter.plugin(Visualizer);
@@ -153,6 +174,8 @@ export default angular
     .directive(fakeUiCanExit.name, fakeUiCanExit)
     .directive(formUICanExitGuard.name, formUICanExitGuard)
     .factory('configSelectionManager', ConfigSelectionManager)
+    .service('IgniteSummaryZipper', SummaryZipper)
+    .service('IgniteConfigurationResource', ConfigurationResource)
     .service('ConfigSelectors', selectors)
     .service('ConfigEffects', effects)
     .service('ConfigChangesGuard', ConfigChangesGuard)

http://git-wip-us.apache.org/repos/asf/ignite/blob/d02e87b9/modules/web-console/frontend/app/components/page-configure/services/ConfigurationResource.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/components/page-configure/services/ConfigurationResource.js b/modules/web-console/frontend/app/components/page-configure/services/ConfigurationResource.js
new file mode 100644
index 0000000..2dab8a3
--- /dev/null
+++ b/modules/web-console/frontend/app/components/page-configure/services/ConfigurationResource.js
@@ -0,0 +1,49 @@
+/*
+ * 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 _ from 'lodash';
+
+/**
+ * @param {ng.IHttpService} $http
+ */
+export default function ConfigurationResourceService($http) {
+    return {
+        read() {
+            return $http.get('/api/v1/configuration/list')
+                .then(({data}) => data)
+                .catch(({data}) => Promise.reject(data));
+        },
+        populate({spaces, clusters, caches, igfss, domains}) {
+            _.forEach(clusters, (cluster) => {
+                cluster.caches = _.filter(caches, ({_id}) => _.includes(cluster.caches, _id));
+
+                _.forEach(cluster.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});
+                });
+
+                cluster.igfss = _.filter(igfss, ({_id}) => _.includes(cluster.igfss, _id));
+            });
+
+            return Promise.resolve({spaces, clusters, caches, igfss, domains});
+        }
+    };
+}
+
+ConfigurationResourceService.$inject = ['$http'];

http://git-wip-us.apache.org/repos/asf/ignite/blob/d02e87b9/modules/web-console/frontend/app/components/page-configure/services/SummaryZipper.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/components/page-configure/services/SummaryZipper.js b/modules/web-console/frontend/app/components/page-configure/services/SummaryZipper.js
new file mode 100644
index 0000000..8bc16b4
--- /dev/null
+++ b/modules/web-console/frontend/app/components/page-configure/services/SummaryZipper.js
@@ -0,0 +1,44 @@
+/*
+ * 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 Worker from './summary.worker';
+
+/**
+ * @param {ng.IQService} $q
+ */
+export default function SummaryZipperService($q) {
+    return function(message) {
+        const defer = $q.defer();
+        const worker = new Worker();
+
+        worker.postMessage(message);
+
+        worker.onmessage = (e) => {
+            defer.resolve(e.data);
+            worker.terminate();
+        };
+
+        worker.onerror = (err) => {
+            defer.reject(err);
+            worker.terminate();
+        };
+
+        return defer.promise;
+    };
+}
+
+SummaryZipperService.$inject = ['$q'];

http://git-wip-us.apache.org/repos/asf/ignite/blob/d02e87b9/modules/web-console/frontend/app/components/page-configure/services/summary.worker.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/components/page-configure/services/summary.worker.js b/modules/web-console/frontend/app/components/page-configure/services/summary.worker.js
new file mode 100644
index 0000000..c80d698
--- /dev/null
+++ b/modules/web-console/frontend/app/components/page-configure/services/summary.worker.js
@@ -0,0 +1,147 @@
+/*
+ * 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 JSZip from 'jszip';
+
+import IgniteMavenGenerator from 'app/modules/configuration/generator/Maven.service';
+import IgniteDockerGenerator from 'app/modules/configuration/generator/Docker.service';
+import IgniteReadmeGenerator from 'app/modules/configuration/generator/Readme.service';
+import IgnitePropertiesGenerator from 'app/modules/configuration/generator/Properties.service';
+import IgniteConfigurationGenerator from 'app/modules/configuration/generator/ConfigurationGenerator';
+
+import IgniteJavaTransformer from 'app/modules/configuration/generator/JavaTransformer.service';
+import IgniteSpringTransformer from 'app/modules/configuration/generator/SpringTransformer.service';
+
+import {nonEmpty, nonNil} from 'app/utils/lodashMixins';
+import get from 'lodash/get';
+import filter from 'lodash/filter';
+import isEmpty from 'lodash/isEmpty';
+
+const maven = new IgniteMavenGenerator();
+const docker = new IgniteDockerGenerator();
+const readme = new IgniteReadmeGenerator();
+const properties = new IgnitePropertiesGenerator();
+
+const java = IgniteJavaTransformer;
+const spring = IgniteSpringTransformer;
+
+const generator = IgniteConfigurationGenerator;
+
+const escapeFileName = (name) => name.replace(/[\\\/*\"\[\],\.:;|=<>?]/g, '-').replace(/ /g, '_');
+
+const kubernetesConfig = (cluster) => {
+    if (!cluster.discovery.Kubernetes)
+        cluster.discovery.Kubernetes = { serviceName: 'ignite' };
+
+    return `apiVersion: v1\n\
+kind: Service\n\
+metadata:\n\
+  # Name of Ignite Service used by Kubernetes IP finder for IP addresses lookup.\n\
+  name: ${ cluster.discovery.Kubernetes.serviceName || 'ignite' }\n\
+spec:\n\
+  clusterIP: None # custom value.\n\
+  ports:\n\
+    - port: 9042 # custom value.\n\
+  selector:\n\
+    # Must be equal to one of the labels set in Ignite pods'\n\
+    # deployement configuration.\n\
+    app: ${ cluster.discovery.Kubernetes.serviceName || 'ignite' }`;
+};
+
+// eslint-disable-next-line no-undef
+onmessage = function(e) {
+    const {cluster, data, demo, targetVer} = e.data;
+
+    const zip = new JSZip();
+
+    if (!data.docker)
+        data.docker = docker.generate(cluster, targetVer);
+
+    zip.file('Dockerfile', data.docker);
+    zip.file('.dockerignore', docker.ignoreFile());
+
+    const cfg = generator.igniteConfiguration(cluster, targetVer, false);
+    const clientCfg = generator.igniteConfiguration(cluster, targetVer, true);
+    const clientNearCaches = filter(cluster.caches, (cache) =>
+        cache.cacheMode === 'PARTITIONED' && get(cache, 'clientNearConfiguration.enabled'));
+
+    const secProps = properties.generate(cfg);
+
+    if (secProps)
+        zip.file('src/main/resources/secret.properties', secProps);
+
+    const srcPath = 'src/main/java';
+    const resourcesPath = 'src/main/resources';
+
+    const serverXml = `${escapeFileName(cluster.name)}-server.xml`;
+    const clientXml = `${escapeFileName(cluster.name)}-client.xml`;
+
+    const metaPath = `${resourcesPath}/META-INF`;
+
+    if (cluster.discovery.kind === 'Kubernetes')
+        zip.file(`${metaPath}/ignite-service.yaml`, kubernetesConfig(cluster));
+
+    zip.file(`${metaPath}/${serverXml}`, spring.igniteConfiguration(cfg, targetVer).asString());
+    zip.file(`${metaPath}/${clientXml}`, spring.igniteConfiguration(clientCfg, targetVer, clientNearCaches).asString());
+
+    const cfgPath = `${srcPath}/config`;
+
+    zip.file(`${cfgPath}/ServerConfigurationFactory.java`, java.igniteConfiguration(cfg, targetVer, 'config', 'ServerConfigurationFactory').asString());
+    zip.file(`${cfgPath}/ClientConfigurationFactory.java`, java.igniteConfiguration(clientCfg, targetVer, 'config', 'ClientConfigurationFactory', clientNearCaches).asString());
+
+    if (java.isDemoConfigured(cluster, demo)) {
+        zip.file(`${srcPath}/demo/DemoStartup.java`, java.nodeStartup(cluster, 'demo.DemoStartup',
+            'ServerConfigurationFactory.createConfiguration()', 'config.ServerConfigurationFactory'));
+    }
+
+    // Generate loader for caches with configured store.
+    const cachesToLoad = filter(cluster.caches, (cache) => nonNil(cache.cacheStoreFactory));
+
+    if (nonEmpty(cachesToLoad))
+        zip.file(`${srcPath}/load/LoadCaches.java`, java.loadCaches(cachesToLoad, 'load', 'LoadCaches', `"${clientXml}"`));
+
+    const startupPath = `${srcPath}/startup`;
+
+    zip.file(`${startupPath}/ServerNodeSpringStartup.java`, java.nodeStartup(cluster, 'startup.ServerNodeSpringStartup', `"${serverXml}"`));
+    zip.file(`${startupPath}/ClientNodeSpringStartup.java`, java.nodeStartup(cluster, 'startup.ClientNodeSpringStartup', `"${clientXml}"`));
+
+    zip.file(`${startupPath}/ServerNodeCodeStartup.java`, java.nodeStartup(cluster, 'startup.ServerNodeCodeStartup',
+        'ServerConfigurationFactory.createConfiguration()', 'config.ServerConfigurationFactory'));
+    zip.file(`${startupPath}/ClientNodeCodeStartup.java`, java.nodeStartup(cluster, 'startup.ClientNodeCodeStartup',
+        'ClientConfigurationFactory.createConfiguration()', 'config.ClientConfigurationFactory', clientNearCaches));
+
+    zip.file('pom.xml', maven.generate(cluster, targetVer));
+
+    zip.file('README.txt', readme.generate());
+    zip.file('jdbc-drivers/README.txt', readme.generateJDBC());
+
+    if (isEmpty(data.pojos))
+        data.pojos = java.pojos(cluster.caches, true);
+
+    for (const pojo of data.pojos) {
+        if (pojo.keyClass)
+            zip.file(`${srcPath}/${pojo.keyType.replace(/\./g, '/')}.java`, pojo.keyClass);
+
+        zip.file(`${srcPath}/${pojo.valueType.replace(/\./g, '/')}.java`, pojo.valueClass);
+    }
+
+    zip.generateAsync({
+        type: 'blob',
+        compression: 'DEFLATE',
+        mimeType: 'application/octet-stream'
+    }).then((blob) => postMessage(blob));
+};

http://git-wip-us.apache.org/repos/asf/ignite/blob/d02e87b9/modules/web-console/frontend/app/modules/states/configuration/Configuration.resource.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/states/configuration/Configuration.resource.js b/modules/web-console/frontend/app/modules/states/configuration/Configuration.resource.js
deleted file mode 100644
index 0582d5c..0000000
--- a/modules/web-console/frontend/app/modules/states/configuration/Configuration.resource.js
+++ /dev/null
@@ -1,42 +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.
- */
-
-export default ['$http', ($http) => {
-    return {
-        read() {
-            return $http.get('/api/v1/configuration/list')
-                .then(({data}) => data)
-                .catch(({data}) => Promise.reject(data));
-        },
-        populate({spaces, clusters, caches, igfss, domains}) {
-            _.forEach(clusters, (cluster) => {
-                cluster.caches = _.filter(caches, ({_id}) => _.includes(cluster.caches, _id));
-
-                _.forEach(cluster.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});
-                });
-
-                cluster.igfss = _.filter(igfss, ({_id}) => _.includes(cluster.igfss, _id));
-            });
-
-            return Promise.resolve({spaces, clusters, caches, igfss, domains});
-        }
-    };
-}];

http://git-wip-us.apache.org/repos/asf/ignite/blob/d02e87b9/modules/web-console/frontend/app/modules/states/configuration/preview-panel.directive.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/states/configuration/preview-panel.directive.js b/modules/web-console/frontend/app/modules/states/configuration/preview-panel.directive.js
deleted file mode 100644
index be7bf1e..0000000
--- a/modules/web-console/frontend/app/modules/states/configuration/preview-panel.directive.js
+++ /dev/null
@@ -1,239 +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 ace from 'brace';
-
-export default ['previewPanel', ['$interval', '$timeout', ($interval, $timeout) => {
-    let animation = {editor: null, stage: 0, start: 0, stop: 0};
-    let prevContent = [];
-
-    const Range = ace.acequire('ace/range').Range;
-
-    const _clearSelection = (editor) => {
-        _.forEach(editor.session.getMarkers(false), (marker) => {
-            editor.session.removeMarker(marker.id);
-        });
-    };
-
-    /**
-     * Switch to next stage of animation.
-     */
-    const _animate = () => {
-        animation.stage += animation.step;
-
-        const stage = animation.stage;
-        const editor = animation.editor;
-
-        _clearSelection(editor);
-
-        animation.selections.forEach((selection) => {
-            editor.session.addMarker(new Range(selection.start, 0, selection.stop, 0),
-                'preview-highlight-' + stage, 'line', false);
-        });
-
-        if (stage === animation.finalStage) {
-            editor.animatePromise = null;
-
-            if (animation.clearOnFinal)
-                _clearSelection(editor);
-        }
-    };
-
-    /**
-     * Selection with animation.
-     *
-     * @param editor Editor to show selection animation.
-     * @param selections Array of selection intervals.
-     * @param step Step of animation (1 or -1).
-     * @param stage Start stage of animation.
-     * @param finalStage Final stage of animation.
-     * @param clearOnFinal Boolean flat to clear selection on animation finish.
-     */
-    const _fade = (editor, selections, step, stage, finalStage, clearOnFinal) => {
-        const promise = editor.animatePromise;
-
-        if (promise) {
-            $interval.cancel(promise);
-
-            _clearSelection(editor);
-        }
-
-        animation = {editor, selections, step, stage, finalStage, clearOnFinal};
-
-        editor.animatePromise = $interval(_animate, 100, 10, false);
-    };
-
-    /**
-     * Show selections with animation.
-     *
-     * @param editor Editor to show selection.
-     * @param selections Array of selection intervals.
-     */
-    const _fadeIn = (editor, selections) => {
-        _fade(editor, selections, 1, 0, 10, false);
-    };
-
-    /**
-     * Hide selections with animation.
-     *
-     * @param editor Editor to show selection.
-     * @param selections Array of selection intervals.
-     */
-    const _fadeOut = (editor, selections) => {
-        _fade(editor, selections, -1, 10, 0, true);
-    };
-
-    const onChange = ([content, editor]) => {
-        const {clearPromise} = editor;
-        const {lines} = content;
-
-        if (content.action === 'remove')
-            prevContent = lines;
-        else if (prevContent.length > 0 && lines.length > 0 && editor.attractAttention) {
-            if (clearPromise) {
-                $timeout.cancel(clearPromise);
-
-                _clearSelection(editor);
-            }
-
-            const selections = [];
-
-            let newIx = 0;
-            let prevIx = 0;
-
-            let prevLen = prevContent.length - (prevContent[prevContent.length - 1] === '' ? 1 : 0);
-            let newLen = lines.length - (lines[lines.length - 1] === '' ? 1 : 0);
-
-            const removed = newLen < prevLen;
-
-            let skipEnd = 0;
-
-            let selected = false;
-            let scrollTo = -1;
-
-            while (lines[newLen - 1] === prevContent[prevLen - 1] && newLen > 0 && prevLen > 0) {
-                prevLen -= 1;
-                newLen -= 1;
-
-                skipEnd += 1;
-            }
-
-            while (newIx < newLen || prevIx < prevLen) {
-                let start = -1;
-                let stop = -1;
-
-                // Find an index of a first line with different text.
-                for (; (newIx < newLen || prevIx < prevLen) && start < 0; newIx++, prevIx++) {
-                    if (newIx >= newLen || prevIx >= prevLen || lines[newIx] !== prevContent[prevIx]) {
-                        start = newIx;
-
-                        break;
-                    }
-                }
-
-                if (start >= 0) {
-                    // Find an index of a last line with different text by checking last string of old and new content in reverse order.
-                    for (let i = start; i < newLen && stop < 0; i++) {
-                        for (let j = prevIx; j < prevLen && stop < 0; j++) {
-                            if (lines[i] === prevContent[j] && lines[i] !== '') {
-                                stop = i;
-
-                                newIx = i;
-                                prevIx = j;
-
-                                break;
-                            }
-                        }
-                    }
-
-                    if (stop < 0) {
-                        stop = newLen;
-
-                        newIx = newLen;
-                        prevIx = prevLen;
-                    }
-
-                    if (start === stop) {
-                        if (removed)
-                            start = Math.max(0, start - 1);
-
-                        stop = Math.min(newLen + skipEnd, stop + 1);
-                    }
-
-                    if (start <= stop) {
-                        selections.push({start, stop});
-
-                        if (!selected)
-                            scrollTo = start;
-
-                        selected = true;
-                    }
-                }
-            }
-
-            // Run clear selection one time.
-            if (selected) {
-                _fadeIn(editor, selections);
-
-                editor.clearPromise = $timeout(() => {
-                    _fadeOut(editor, selections);
-
-                    editor.clearPromise = null;
-                }, 2000);
-
-                editor.scrollToRow(scrollTo);
-            }
-
-            prevContent = [];
-        }
-        else
-            editor.attractAttention = true;
-    };
-
-
-    const link = (scope, $element, $attrs, [igniteUiAceTabs1, igniteUiAceTabs2]) => {
-        const igniteUiAceTabs = igniteUiAceTabs1 || igniteUiAceTabs2;
-
-        if (!igniteUiAceTabs)
-            return;
-
-        igniteUiAceTabs.onLoad = (editor) => {
-            editor.setReadOnly(true);
-            editor.setOption('highlightActiveLine', false);
-            editor.setAutoScrollEditorIntoView(true);
-            editor.$blockScrolling = Infinity;
-            editor.attractAttention = false;
-
-            const renderer = editor.renderer;
-
-            renderer.setHighlightGutterLine(false);
-            renderer.setShowPrintMargin(false);
-            renderer.setOption('fontSize', '10px');
-            renderer.setOption('maxLines', '50');
-
-            editor.setTheme('ace/theme/chrome');
-        };
-
-        igniteUiAceTabs.onChange = onChange;
-    };
-
-    return {
-        restrict: 'C',
-        link,
-        require: ['?igniteUiAceTabs', '?^igniteUiAceTabs']
-    };
-}]];

http://git-wip-us.apache.org/repos/asf/ignite/blob/d02e87b9/modules/web-console/frontend/app/modules/states/configuration/summary/summary-zipper.service.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/states/configuration/summary/summary-zipper.service.js b/modules/web-console/frontend/app/modules/states/configuration/summary/summary-zipper.service.js
deleted file mode 100644
index 119fb52..0000000
--- a/modules/web-console/frontend/app/modules/states/configuration/summary/summary-zipper.service.js
+++ /dev/null
@@ -1,39 +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 Worker from './summary.worker';
-
-export default ['$q', function($q) {
-    return function(message) {
-        const defer = $q.defer();
-        const worker = new Worker();
-
-        worker.postMessage(message);
-
-        worker.onmessage = (e) => {
-            defer.resolve(e.data);
-            worker.terminate();
-        };
-
-        worker.onerror = (err) => {
-            defer.reject(err);
-            worker.terminate();
-        };
-
-        return defer.promise;
-    };
-}];

http://git-wip-us.apache.org/repos/asf/ignite/blob/d02e87b9/modules/web-console/frontend/app/modules/states/configuration/summary/summary.worker.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/states/configuration/summary/summary.worker.js b/modules/web-console/frontend/app/modules/states/configuration/summary/summary.worker.js
deleted file mode 100644
index c80d698..0000000
--- a/modules/web-console/frontend/app/modules/states/configuration/summary/summary.worker.js
+++ /dev/null
@@ -1,147 +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 JSZip from 'jszip';
-
-import IgniteMavenGenerator from 'app/modules/configuration/generator/Maven.service';
-import IgniteDockerGenerator from 'app/modules/configuration/generator/Docker.service';
-import IgniteReadmeGenerator from 'app/modules/configuration/generator/Readme.service';
-import IgnitePropertiesGenerator from 'app/modules/configuration/generator/Properties.service';
-import IgniteConfigurationGenerator from 'app/modules/configuration/generator/ConfigurationGenerator';
-
-import IgniteJavaTransformer from 'app/modules/configuration/generator/JavaTransformer.service';
-import IgniteSpringTransformer from 'app/modules/configuration/generator/SpringTransformer.service';
-
-import {nonEmpty, nonNil} from 'app/utils/lodashMixins';
-import get from 'lodash/get';
-import filter from 'lodash/filter';
-import isEmpty from 'lodash/isEmpty';
-
-const maven = new IgniteMavenGenerator();
-const docker = new IgniteDockerGenerator();
-const readme = new IgniteReadmeGenerator();
-const properties = new IgnitePropertiesGenerator();
-
-const java = IgniteJavaTransformer;
-const spring = IgniteSpringTransformer;
-
-const generator = IgniteConfigurationGenerator;
-
-const escapeFileName = (name) => name.replace(/[\\\/*\"\[\],\.:;|=<>?]/g, '-').replace(/ /g, '_');
-
-const kubernetesConfig = (cluster) => {
-    if (!cluster.discovery.Kubernetes)
-        cluster.discovery.Kubernetes = { serviceName: 'ignite' };
-
-    return `apiVersion: v1\n\
-kind: Service\n\
-metadata:\n\
-  # Name of Ignite Service used by Kubernetes IP finder for IP addresses lookup.\n\
-  name: ${ cluster.discovery.Kubernetes.serviceName || 'ignite' }\n\
-spec:\n\
-  clusterIP: None # custom value.\n\
-  ports:\n\
-    - port: 9042 # custom value.\n\
-  selector:\n\
-    # Must be equal to one of the labels set in Ignite pods'\n\
-    # deployement configuration.\n\
-    app: ${ cluster.discovery.Kubernetes.serviceName || 'ignite' }`;
-};
-
-// eslint-disable-next-line no-undef
-onmessage = function(e) {
-    const {cluster, data, demo, targetVer} = e.data;
-
-    const zip = new JSZip();
-
-    if (!data.docker)
-        data.docker = docker.generate(cluster, targetVer);
-
-    zip.file('Dockerfile', data.docker);
-    zip.file('.dockerignore', docker.ignoreFile());
-
-    const cfg = generator.igniteConfiguration(cluster, targetVer, false);
-    const clientCfg = generator.igniteConfiguration(cluster, targetVer, true);
-    const clientNearCaches = filter(cluster.caches, (cache) =>
-        cache.cacheMode === 'PARTITIONED' && get(cache, 'clientNearConfiguration.enabled'));
-
-    const secProps = properties.generate(cfg);
-
-    if (secProps)
-        zip.file('src/main/resources/secret.properties', secProps);
-
-    const srcPath = 'src/main/java';
-    const resourcesPath = 'src/main/resources';
-
-    const serverXml = `${escapeFileName(cluster.name)}-server.xml`;
-    const clientXml = `${escapeFileName(cluster.name)}-client.xml`;
-
-    const metaPath = `${resourcesPath}/META-INF`;
-
-    if (cluster.discovery.kind === 'Kubernetes')
-        zip.file(`${metaPath}/ignite-service.yaml`, kubernetesConfig(cluster));
-
-    zip.file(`${metaPath}/${serverXml}`, spring.igniteConfiguration(cfg, targetVer).asString());
-    zip.file(`${metaPath}/${clientXml}`, spring.igniteConfiguration(clientCfg, targetVer, clientNearCaches).asString());
-
-    const cfgPath = `${srcPath}/config`;
-
-    zip.file(`${cfgPath}/ServerConfigurationFactory.java`, java.igniteConfiguration(cfg, targetVer, 'config', 'ServerConfigurationFactory').asString());
-    zip.file(`${cfgPath}/ClientConfigurationFactory.java`, java.igniteConfiguration(clientCfg, targetVer, 'config', 'ClientConfigurationFactory', clientNearCaches).asString());
-
-    if (java.isDemoConfigured(cluster, demo)) {
-        zip.file(`${srcPath}/demo/DemoStartup.java`, java.nodeStartup(cluster, 'demo.DemoStartup',
-            'ServerConfigurationFactory.createConfiguration()', 'config.ServerConfigurationFactory'));
-    }
-
-    // Generate loader for caches with configured store.
-    const cachesToLoad = filter(cluster.caches, (cache) => nonNil(cache.cacheStoreFactory));
-
-    if (nonEmpty(cachesToLoad))
-        zip.file(`${srcPath}/load/LoadCaches.java`, java.loadCaches(cachesToLoad, 'load', 'LoadCaches', `"${clientXml}"`));
-
-    const startupPath = `${srcPath}/startup`;
-
-    zip.file(`${startupPath}/ServerNodeSpringStartup.java`, java.nodeStartup(cluster, 'startup.ServerNodeSpringStartup', `"${serverXml}"`));
-    zip.file(`${startupPath}/ClientNodeSpringStartup.java`, java.nodeStartup(cluster, 'startup.ClientNodeSpringStartup', `"${clientXml}"`));
-
-    zip.file(`${startupPath}/ServerNodeCodeStartup.java`, java.nodeStartup(cluster, 'startup.ServerNodeCodeStartup',
-        'ServerConfigurationFactory.createConfiguration()', 'config.ServerConfigurationFactory'));
-    zip.file(`${startupPath}/ClientNodeCodeStartup.java`, java.nodeStartup(cluster, 'startup.ClientNodeCodeStartup',
-        'ClientConfigurationFactory.createConfiguration()', 'config.ClientConfigurationFactory', clientNearCaches));
-
-    zip.file('pom.xml', maven.generate(cluster, targetVer));
-
-    zip.file('README.txt', readme.generate());
-    zip.file('jdbc-drivers/README.txt', readme.generateJDBC());
-
-    if (isEmpty(data.pojos))
-        data.pojos = java.pojos(cluster.caches, true);
-
-    for (const pojo of data.pojos) {
-        if (pojo.keyClass)
-            zip.file(`${srcPath}/${pojo.keyType.replace(/\./g, '/')}.java`, pojo.keyClass);
-
-        zip.file(`${srcPath}/${pojo.valueType.replace(/\./g, '/')}.java`, pojo.valueClass);
-    }
-
-    zip.generateAsync({
-        type: 'blob',
-        compression: 'DEFLATE',
-        mimeType: 'application/octet-stream'
-    }).then((blob) => postMessage(blob));
-};