You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@eagle.apache.org by ha...@apache.org on 2016/12/30 08:27:55 UTC

[03/14] eagle git commit: [MINOR] Migrate 0.5.0-incubating-SNAPSHOT to 0.5.0-SNAPSHOT

http://git-wip-us.apache.org/repos/asf/eagle/blob/8b3729f9/eagle-webservice/src/main/webapp/_app/public/feature/metrics/controller.js
----------------------------------------------------------------------
diff --git a/eagle-webservice/src/main/webapp/_app/public/feature/metrics/controller.js b/eagle-webservice/src/main/webapp/_app/public/feature/metrics/controller.js
deleted file mode 100644
index d717ad1..0000000
--- a/eagle-webservice/src/main/webapp/_app/public/feature/metrics/controller.js
+++ /dev/null
@@ -1,571 +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.
- */
-
-(function() {
-	'use strict';
-
-	var featureControllers = angular.module('featureControllers');
-	var feature = featureControllers.register("metrics");
-
-	// ==============================================================
-	// =                       Initialization                       =
-	// ==============================================================
-
-	// ==============================================================
-	// =                          Function                          =
-	// ==============================================================
-	// Format dashboard unit. Will adjust format with old version and add miss attributes.
-	feature.service("DashboardFormatter", function() {
-		return {
-			parse: function(unit) {
-				unit = unit || {};
-				unit.groups = unit.groups || [];
-
-				$.each(unit.groups, function (i, group) {
-					group.charts = group.charts || [];
-					$.each(group.charts, function (i, chart) {
-						if (!chart.metrics && chart.metric) {
-							chart.metrics = [{
-								aggregations: chart.aggregations,
-								dataSource: chart.dataSource,
-								metric: chart.metric
-							}];
-
-							delete chart.aggregations;
-							delete chart.dataSource;
-							delete chart.metric;
-						} else if (!chart.metrics) {
-							chart.metrics = [];
-						}
-					});
-				});
-
-				return unit;
-			}
-		};
-	});
-
-	// ==============================================================
-	// =                         Controller                         =
-	// ==============================================================
-
-	// ========================= Dashboard ==========================
-	feature.navItem("dashboard", "Metrics", "line-chart");
-
-	feature.controller('dashboard', function(PageConfig, $scope, $http, $q, UI, Site, Authorization, Application, Entities, DashboardFormatter) {
-		var _siteApp = Site.currentSiteApplication();
-		var _druidConfig = _siteApp.configObj.getValueByPath("web.druid");
-		var _refreshInterval;
-
-		var _menu_newChart;
-
-		$scope.lock = false;
-
-		$scope.dataSourceListReady = false;
-		$scope.dataSourceList = [];
-		$scope.dashboard = {
-			groups: []
-		};
-		$scope.dashboardEntity = null;
-		$scope.dashboardReady = false;
-
-		$scope._newMetricFilter = "";
-		$scope._newMetricDataSrc = null;
-		$scope._newMetricDataMetric = null;
-
-		$scope.tabHolder = {};
-
-		$scope.endTime = app.time.now();
-		$scope.startTime = $scope.endTime.clone();
-
-		// =================== Initialization ===================
-		if(!_druidConfig || !_druidConfig.coordinator || !_druidConfig.broker) {
-			$.dialog({
-				title: "OPS",
-				content: "Druid configuration can't be empty!"
-			});
-			return;
-		}
-
-		$scope.autoRefreshList = [
-			{title: "Last 1 Month", timeDes: "day", getStartTime: function(endTime) {return endTime.clone().subtract(1, "month");}},
-			{title: "Last 1 Day", timeDes: "thirty_minute", getStartTime: function(endTime) {return endTime.clone().subtract(1, "day");}},
-			{title: "Last 6 Hour", timeDes: "fifteen_minute", getStartTime: function(endTime) {return endTime.clone().subtract(6, "hour");}},
-			{title: "Last 2 Hour", timeDes: "fifteen_minute", getStartTime: function(endTime) {return endTime.clone().subtract(2, "hour");}},
-			{title: "Last 1 Hour", timeDes: "minute", getStartTime: function(endTime) {return endTime.clone().subtract(1, "hour");}}
-		];
-		$scope.autoRefreshSelect = $scope.autoRefreshList[2];
-
-		// ====================== Function ======================
-		$scope.setAuthRefresh = function(item) {
-			$scope.autoRefreshSelect = item;
-			$scope.refreshAllChart(true);
-		};
-
-		$scope.refreshTimeDisplay = function() {
-			PageConfig.pageSubTitle = common.format.date($scope.startTime) + " ~ " + common.format.date($scope.endTime) + " [refresh interval: 30s]";
-		};
-		$scope.refreshTimeDisplay();
-
-		// ======================= Metric =======================
-		// Fetch metric data
-		$http.get(_druidConfig.coordinator + "/druid/coordinator/v1/metadata/datasources", {withCredentials: false}).then(function(data) {
-			var _endTime = new moment();
-			var _startTime = _endTime.clone().subtract(1, "day");
-			var _intervals = _startTime.toISOString() + "/" + _endTime.toISOString();
-
-			$scope.dataSourceList = $.map(data.data, function(dataSrc) {
-				return {
-					dataSource: dataSrc,
-					metricList: []
-				};
-			});
-
-			// List dataSource metrics
-			var _metrixList_promiseList = $.map($scope.dataSourceList, function(dataSrc) {
-				var _data = JSON.stringify({
-					"queryType": "groupBy",
-					"dataSource": dataSrc.dataSource,
-					"granularity": "all",
-					"dimensions": ["metric"],
-					"aggregations": [
-						{
-							"type":"count",
-							"name":"count"
-						}
-					],
-					"intervals": [_intervals]
-				});
-
-				return $http.post(_druidConfig.broker + "/druid/v2", _data, {withCredentials: false}).then(function(response) {
-					dataSrc.metricList = $.map(response.data, function(entity) {
-						return entity.event.metric;
-					});
-				});
-			});
-
-			$q.all(_metrixList_promiseList).finally(function() {
-				$scope.dataSourceListReady = true;
-
-				$scope._newMetricDataSrc = $scope.dataSourceList[0];
-				$scope._newMetricDataMetric = common.getValueByPath($scope._newMetricDataSrc, "metricList.0");
-			});
-		}, function() {
-			$.dialog({
-				title: "OPS",
-				content: "Fetch data source failed. Please check Site Application Metrics configuration."
-			});
-		});
-
-		// Filter data source
-		$scope.dataSourceMetricList = function(dataSrc, filter) {
-			filter = (filter || "").toLowerCase().trim().split(/\s+/);
-			return $.grep((dataSrc && dataSrc.metricList) || [], function(metric) {
-				for(var i = 0 ; i < filter.length ; i += 1) {
-					if(metric.toLowerCase().indexOf(filter[i]) === -1) return false;
-				}
-				return true;
-			});
-		};
-
-		// New metric select
-		$scope.newMetricSelectDataSource = function(dataSrc) {
-			if(dataSrc !== $scope._newMetricDataMetric) $scope._newMetricDataMetric = dataSrc.metricList[0];
-			$scope._newMetricDataSrc = dataSrc;
-		};
-		$scope.newMetricSelectMetric = function(metric) {
-			$scope._newMetricDataMetric = metric;
-		};
-
-		// Confirm new metric
-		$scope.confirmSelectMetric = function() {
-			var group = $scope.tabHolder.selectedPane.data;
-			var metric = {
-				dataSource: $scope._newMetricDataSrc.dataSource,
-				metric: $scope._newMetricDataMetric,
-				aggregations: ["max"]
-			};
-			$("#metricMDL").modal('hide');
-
-			if($scope.metricForConfigChart) {
-				$scope.configPreviewChart.metrics.push(metric);
-				$scope.refreshChart($scope.configPreviewChart, true, true);
-			} else {
-				group.charts.push({
-					chart: "line",
-					metrics: [metric]
-				});
-				$scope.refreshAllChart();
-			}
-		};
-
-		// ======================== Menu ========================
-		function _checkGroupName(entity) {
-			if(common.array.find(entity.name, $scope.dashboard.groups, "name")) {
-				return "Group name conflict";
-			}
-		}
-
-		$scope.newGroup = function() {
-			if($scope.lock) return;
-
-			UI.createConfirm("Group", {}, [{field: "name"}], _checkGroupName).then(null, null, function(holder) {
-				$scope.dashboard.groups.push({
-					name: holder.entity.name,
-					charts: []
-				});
-				holder.closeFunc();
-
-				setTimeout(function() {
-					$scope.tabHolder.setSelect(holder.entity.name);
-				}, 0);
-			});
-		};
-
-		function renameGroup() {
-			var group = $scope.tabHolder.selectedPane.data;
-			UI.updateConfirm("Group", {}, [{field: "name", name: "New Name"}], _checkGroupName).then(null, null, function(holder) {
-				group.name = holder.entity.name;
-				holder.closeFunc();
-			});
-		}
-
-		function deleteGroup() {
-			var group = $scope.tabHolder.selectedPane.data;
-			UI.deleteConfirm(group.name).then(null, null, function(holder) {
-				common.array.remove(group, $scope.dashboard.groups);
-				holder.closeFunc();
-			});
-		}
-
-		_menu_newChart = {title: "Add Metric", func: function() {$scope.newChart();}};
-		Object.defineProperties(_menu_newChart, {
-			icon: {
-				get: function() {return $scope.dataSourceListReady ? 'plus' : 'refresh fa-spin';}
-			},
-			disabled: {
-				get: function() {return !$scope.dataSourceListReady;}
-			}
-		});
-
-		$scope.menu = Authorization.isRole('ROLE_ADMIN') ? [
-			{icon: "cog", title: "Configuration", list: [
-				_menu_newChart,
-				{icon: "pencil", title: "Rename Group", func: renameGroup},
-				{icon: "trash", title: "Delete Group", danger: true, func: deleteGroup}
-			]},
-			{icon: "plus", title: "New Group", func: $scope.newGroup}
-		] : [];
-
-		// ===================== Dashboard ======================
-		$scope.dashboardList = Entities.queryEntities("GenericResourceService", {
-			site: Site.current().tags.site,
-			application: Application.current().tags.application
-		});
-		$scope.dashboardList._promise.then(function(list) {
-			$scope.dashboardEntity = list[0];
-			$scope.dashboard = DashboardFormatter.parse(common.parseJSON($scope.dashboardEntity.value));
-			$scope.refreshAllChart();
-		}).finally(function() {
-			$scope.dashboardReady = true;
-		});
-
-		$scope.saveDashboard = function() {
-			$scope.lock = true;
-
-			if(!$scope.dashboardEntity) {
-				$scope.dashboardEntity = {
-					tags: {
-						site: Site.current().tags.site,
-						application: Application.current().tags.application,
-						name: "/metric_dashboard/dashboard/default"
-					}
-				};
-			}
-			$scope.dashboardEntity.value = common.stringify($scope.dashboard);
-
-			Entities.updateEntity("GenericResourceService", $scope.dashboardEntity)._promise.then(function() {
-				$.dialog({
-					title: "Done",
-					content: "Save success!"
-				});
-			}, function() {
-				$.dialog({
-					title: "POS",
-					content: "Save failed. Please retry."
-				});
-			}).finally(function() {
-				$scope.lock = false;
-			});
-		};
-
-		// ======================= Chart ========================
-		$scope.configTargetChart = null;
-		$scope.configPreviewChart = null;
-		$scope.metricForConfigChart = false;
-		$scope.viewChart = null;
-
-		$scope.chartConfig = {
-			xType: "time"
-		};
-
-		$scope.chartTypeList = [
-			{icon: "line-chart", chart: "line"},
-			{icon: "area-chart", chart: "area"},
-			{icon: "bar-chart", chart: "column"},
-			{icon: "pie-chart", chart: "pie"}
-		];
-
-		$scope.chartSeriesList = [
-			{name: "Min", series: "min"},
-			{name: "Max", series: "max"},
-			{name: "Avg", series: "avg"},
-			{name: "Count", series: "count"},
-			{name: "Sum", series: "sum"}
-		];
-
-		$scope.newChart = function() {
-			$scope.metricForConfigChart = false;
-			$("#metricMDL").modal();
-		};
-
-		$scope.configPreviewChartMinimumCheck = function() {
-			$scope.configPreviewChart.min = $scope.configPreviewChart.min === 0 ? undefined : 0;
-		};
-
-		$scope.seriesChecked = function(metric, series) {
-			if(!metric) return false;
-			return $.inArray(series, metric.aggregations || []) !== -1;
-		};
-		$scope.seriesCheckClick = function(metric, series, chart) {
-			if(!metric || !chart) return;
-			if($scope.seriesChecked(metric, series)) {
-				common.array.remove(series, metric.aggregations);
-			} else {
-				metric.aggregations.push(series);
-			}
-			$scope.chartSeriesUpdate(chart);
-		};
-
-		$scope.chartSeriesUpdate = function(chart) {
-			chart._data = $.map(chart._oriData, function(groupData, i) {
-				var metric = chart.metrics[i];
-				return $.map(groupData, function(series) {
-					if($.inArray(series._key, metric.aggregations) !== -1) return series;
-				});
-			});
-		};
-
-		$scope.configAddMetric = function() {
-			$scope.metricForConfigChart = true;
-			$("#metricMDL").modal();
-		};
-
-		$scope.configRemoveMetric = function(metric) {
-			common.array.remove(metric, $scope.configPreviewChart.metrics);
-		};
-
-		$scope.getChartConfig = function(chart) {
-			if(!chart) return null;
-
-			var _config = chart._config = chart._config || $.extend({}, $scope.chartConfig);
-			_config.yMin = chart.min;
-
-			return _config;
-		};
-
-		$scope.configChart = function(chart) {
-			$scope.configTargetChart = chart;
-			$scope.configPreviewChart = $.extend({}, chart);
-			$scope.configPreviewChart.metrics = $.map(chart.metrics, function(metric) {
-				return $.extend({}, metric, {aggregations: (metric.aggregations || []).slice()});
-			});
-			delete $scope.configPreviewChart._config;
-			$("#chartMDL").modal();
-			setTimeout(function() {
-				$(window).resize();
-			}, 200);
-		};
-
-		$scope.confirmUpdateChart = function() {
-			$("#chartMDL").modal('hide');
-			$.extend($scope.configTargetChart, $scope.configPreviewChart);
-			$scope.chartSeriesUpdate($scope.configTargetChart);
-			if($scope.configTargetChart._holder) $scope.configTargetChart._holder.refreshAll();
-			$scope.configPreviewChart = null;
-		};
-
-		$scope.deleteChart = function(group, chart) {
-			UI.deleteConfirm(chart.metric).then(null, null, function(holder) {
-				common.array.remove(chart, group.charts);
-				holder.closeFunc();
-				$scope.refreshAllChart(false, true);
-			});
-		};
-
-		$scope.showChart = function(chart) {
-			$scope.viewChart = chart;
-			$("#chartViewMDL").modal();
-			setTimeout(function() {
-				$(window).resize();
-			}, 200);
-		};
-
-		$scope.refreshChart = function(chart, forceRefresh, refreshAll) {
-			var _intervals = $scope.startTime.toISOString() + "/" + $scope.endTime.toISOString();
-
-			function _refreshChart() {
-				if (chart._holder) {
-					if (refreshAll) {
-						chart._holder.refreshAll();
-					} else {
-						chart._holder.refresh();
-					}
-				}
-			}
-
-			var _tmpData, _metricPromiseList;
-
-			if (chart._data && !forceRefresh) {
-				// Refresh chart without reload
-				_refreshChart();
-			} else {
-				// Refresh chart with reload
-				_tmpData = [];
-				_metricPromiseList = $.map(chart.metrics, function (metric, k) {
-					// Each Metric
-					var _query = JSON.stringify({
-						"queryType": "groupBy",
-						"dataSource": metric.dataSource,
-						"granularity": $scope.autoRefreshSelect.timeDes,
-						"dimensions": ["metric"],
-						"filter": {"type": "selector", "dimension": "metric", "value": metric.metric},
-						"aggregations": [
-							{
-								"type": "max",
-								"name": "max",
-								"fieldName": "maxValue"
-							},
-							{
-								"type": "min",
-								"name": "min",
-								"fieldName": "maxValue"
-							},
-							{
-								"type": "count",
-								"name": "count",
-								"fieldName": "maxValue"
-							},
-							{
-								"type": "longSum",
-								"name": "sum",
-								"fieldName": "maxValue"
-							}
-						],
-						"postAggregations" : [
-							{
-								"type": "javascript",
-								"name": "avg",
-								"fieldNames": ["sum", "count"],
-								"function": "function(sum, cnt) { return sum / cnt;}"
-							}
-						],
-						"intervals": [_intervals]
-					});
-
-					return $http.post(_druidConfig.broker + "/druid/v2", _query, {withCredentials: false}).then(function (response) {
-						var _data = nvd3.convert.druid([response.data]);
-						_tmpData[k] = _data;
-
-						// Process series name
-						$.each(_data, function(i, series) {
-							series._key = series.key;
-							if(chart.metrics.length > 1) {
-								series.key = metric.metric.replace(/^.*\./, "") + "-" +series._key;
-							}
-						});
-					});
-				});
-
-				$q.all(_metricPromiseList).then(function() {
-					chart._oriData = _tmpData;
-					$scope.chartSeriesUpdate(chart);
-					_refreshChart();
-				});
-			}
-		};
-
-		$scope.refreshAllChart = function(forceRefresh, refreshAll) {
-			setTimeout(function() {
-				$scope.endTime = app.time.now();
-				$scope.startTime = $scope.autoRefreshSelect.getStartTime($scope.endTime);
-
-				$scope.refreshTimeDisplay();
-
-				$.each($scope.dashboard.groups, function (i, group) {
-					$.each(group.charts, function (j, chart) {
-						$scope.refreshChart(chart, forceRefresh, refreshAll);
-					});
-				});
-
-				$(window).resize();
-			}, 0);
-		};
-
-		$scope.chartSwitchRefresh = function(source, target) {
-			var _oriSize = source.size;
-			source.size = target.size;
-			target.size = _oriSize;
-
-			if(source._holder) source._holder.refreshAll();
-			if(target._holder) target._holder.refreshAll();
-
-		};
-
-		_refreshInterval = setInterval(function() {
-			if(!$scope.dashboardReady) return;
-			$scope.refreshAllChart(true);
-		}, 1000 * 30);
-
-		// > Chart UI
-		$scope.configChartSize = function(chart, sizeOffset) {
-			chart.size = (chart.size || 6) + sizeOffset;
-			if(chart.size <= 0) chart.size = 1;
-			if(chart.size > 12) chart.size = 12;
-			setTimeout(function() {
-				$(window).resize();
-			}, 1);
-		};
-
-		// ========================= UI =========================
-		$("#metricMDL").on('hidden.bs.modal', function () {
-			if($(".modal-backdrop").length) {
-				$("body").addClass("modal-open");
-			}
-		});
-
-		$("#chartViewMDL").on('hidden.bs.modal', function () {
-			$scope.viewChart = null;
-		});
-
-		// ====================== Clean Up ======================
-		$scope.$on('$destroy', function() {
-			clearInterval(_refreshInterval);
-		});
-	});
-})();
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/eagle/blob/8b3729f9/eagle-webservice/src/main/webapp/_app/public/feature/metrics/page/dashboard.html
----------------------------------------------------------------------
diff --git a/eagle-webservice/src/main/webapp/_app/public/feature/metrics/page/dashboard.html b/eagle-webservice/src/main/webapp/_app/public/feature/metrics/page/dashboard.html
deleted file mode 100644
index 2acb954..0000000
--- a/eagle-webservice/src/main/webapp/_app/public/feature/metrics/page/dashboard.html
+++ /dev/null
@@ -1,250 +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.
-  -->
-
-<div class="page-fixed">
-	<div class="dropdown inline">
-		<button data-toggle="dropdown" class="btn btn-primary">
-			<span class="fa fa-clock-o"></span> {{autoRefreshSelect.title}}
-		</button>
-		<ul class="dropdown-menu left">
-			<li ng-repeat="item in autoRefreshList track by $index">
-				<a ng-click="setAuthRefresh(item)">
-					<span class="fa fa-clock-o"></span>
-					<span ng-class="{'text-bold': item === autoRefreshSelect}">{{item.title}}</span>
-				</a>
-			</li>
-		</ul>
-	</div>
-
-	<button class="btn btn-primary" ng-if="Auth.isRole('ROLE_ADMIN')"
-			ng-click="saveDashboard()" ng-disabled="lock">
-		<span class="fa fa-floppy-o"></span> Save
-	</button>
-</div>
-
-<div class="box box-default" ng-if="!dashboard.groups.length">
-	<div class="box-header with-border">
-		<h3 class="box-title">Empty Dashboard</h3>
-	</div>
-	<div class="box-body">
-		<div ng-show="!dashboardReady">
-			Loading...
-		</div>
-		<div ng-show="dashboardReady">
-			Current dashboard is empty.
-			<span ng-if="Auth.isRole('ROLE_ADMIN')">Click <a ng-click="newGroup()">here</a> to create a new group.</span>
-		</div>
-	</div>
-	<div class="overlay" ng-show="!dashboardReady">
-		<i class="fa fa-refresh fa-spin"></i>
-	</div>
-</div>
-
-<div tabs menu="menu" holder="tabHolder" ng-show="dashboard.groups.length" data-sortable-model="Auth.isRole('ROLE_ADMIN') ? dashboard.groups : null">
-	<pane ng-repeat="group in dashboard.groups" data-data="group" data-title="{{group.name}}">
-		<div uie-sortable ng-model="group.charts" class="row narrow" sortable-update-func="chartSwitchRefresh" ng-show="group.charts.length">
-			<div ng-repeat="chart in group.charts track by $index" class="col-md-{{chart.size || 6}}">
-				<div class="nvd3-chart-wrapper">
-					<div nvd3="chart._data" data-holder="chart._holder" data-title="{{chart.title || chart.metrics[0].metric}}" data-watching="false"
-						 data-chart="{{chart.chart || 'line'}}" data-config="getChartConfig(chart)" class="nvd3-chart-cntr"></div>
-					<div class="nvd3-chart-config">
-						<a class="fa fa-expand" ng-click="showChart(chart, -1)"></a>
-						<span ng-if="Auth.isRole('ROLE_ADMIN')">
-							<a class="fa fa-minus" ng-click="configChartSize(chart, -1)"></a>
-							<a class="fa fa-plus" ng-click="configChartSize(chart, 1)"></a>
-							<a class="fa fa-cog" ng-click="configChart(chart)"></a>
-							<a class="fa fa-trash" ng-click="deleteChart(group, chart)"></a>
-						</span>
-					</div>
-				</div>
-			</div>
-		</div>
-
-		<p ng-if="!group.charts.length">
-			Empty group.
-			<span ng-if="Auth.isRole('ROLE_ADMIN')">
-				Click
-				<span ng-hide="dataSourceListReady" class="fa fa-refresh fa-spin"></span>
-				<a ng-show="dataSourceListReady" ng-click="newChart()">here</a>
-				to add metric.
-			</span>
-		</p>
-	</pane>
-</div>
-
-
-
-<!-- Modal: Chart configuration -->
-<div class="modal fade" id="chartMDL" tabindex="-1" role="dialog">
-	<div class="modal-dialog modal-lg" role="document">
-		<div class="modal-content">
-			<div class="modal-header">
-				<button type="button" class="close" data-dismiss="modal" aria-label="Close">
-					<span aria-hidden="true">&times;</span>
-				</button>
-				<h4 class="modal-title">Chart Configuration</h4>
-			</div>
-			<div class="modal-body">
-				<div class="row">
-					<div class="col-md-6">
-						<div class="nvd3-chart-wrapper">
-							<div nvd3="configPreviewChart._data" data-title="{{configPreviewChart.title || configPreviewChart.metrics[0].metric}}"
-								 data-watching="true" data-chart="{{configPreviewChart.chart || 'line'}}" data-config="getChartConfig(configPreviewChart)" class="nvd3-chart-cntr"></div>
-						</div>
-					</div>
-					<div class="col-md-6">
-						<!-- Chart Configuration -->
-						<table class="table">
-							<tbody>
-							<tr>
-								<th width="100">Name</th>
-								<td><input type="text" class="form-control input-xs" ng-model="configPreviewChart.title" placeholder="Default: {{configPreviewChart.metrics[0].metric}}" /></td>
-							</tr>
-							<tr>
-								<th>Chart Type</th>
-								<td>
-									<div class="btn-group" data-toggle="buttons">
-										<label class="btn btn-default btn-xs" ng-class="{active: (configPreviewChart.chart || 'line') === type.chart}"
-											   ng-repeat="type in chartTypeList track by $index" ng-click="configPreviewChart.chart = type.chart;">
-											<input type="radio" name="chartType" autocomplete="off"
-												   ng-checked="(configPreviewChart.chart || 'line') === type.chart">
-											<span class="fa fa-{{type.icon}}"></span>
-										</label>
-									</div>
-								</td>
-							</tr>
-							<tr>
-								<th>Minimum</th>
-								<td><input type="checkbox" ng-checked="configPreviewChart.min === 0" ng-disabled="configPreviewChart.chart === 'area' || configPreviewChart.chart === 'pie'"
-										   ng-click="configPreviewChartMinimumCheck()" /></td>
-							</tr>
-							<tr>
-								<th>Metrics</th>
-								<td>
-									<div ng-repeat="metric in configPreviewChart.metrics" class="box inner-box">
-										<div class="box-tools">
-											<button class="btn btn-box-tool" ng-click="configRemoveMetric(metric)">
-												<span class="fa fa-times"></span>
-											</button>
-										</div>
-
-										<h3 class="box-title">{{metric.metric}}</h3>
-										<div class="checkbox noMargin" ng-repeat="series in chartSeriesList track by $index">
-											<label>
-												<input type="checkbox" ng-checked="seriesChecked(metric, series.series)"
-													   ng-click="seriesCheckClick(metric, series.series, configPreviewChart)" />
-												{{series.name}}
-											</label>
-										</div>
-									</div>
-									<a ng-click="configAddMetric()">+ Add Metric</a>
-								</td>
-							</tr>
-							</tbody>
-						</table>
-					</div>
-				</div>
-			</div>
-			<div class="modal-footer">
-				<button type="button" class="btn btn-default" data-dismiss="modal">
-					Close
-				</button>
-				<button type="button" class="btn btn-primary" ng-click="confirmUpdateChart()">
-					Confirm
-				</button>
-			</div>
-		</div>
-	</div>
-</div>
-
-
-
-<!-- Modal: Metric selector -->
-<div class="modal fade" id="metricMDL" tabindex="-1" role="dialog">
-	<div class="modal-dialog modal-lg" role="document">
-		<div class="modal-content">
-			<div class="modal-header">
-				<button type="button" class="close" data-dismiss="modal" aria-label="Close">
-					<span aria-hidden="true">&times;</span>
-				</button>
-				<h4 class="modal-title">Select Metric</h4>
-			</div>
-			<div class="modal-body">
-				<div class="input-group" style="margin-bottom: 10px;">
-					<input type="text" class="form-control" placeholder="Filter..." ng-model="_newMetricFilter" />
-					<span class="input-group-btn">
-						<button class="btn btn-default btn-flat" ng-click="_newMetricFilter = '';"><span class="fa fa-times"></span></button>
-					</span>
-				</div>
-
-				<div class="row">
-					<div class="col-md-4">
-						<ul class="nav nav-pills nav-stacked fixed-height">
-							<li class="disabled"><a>Data Source</a></li>
-							<li ng-repeat="dataSrc in dataSourceList track by $index" ng-class="{active: _newMetricDataSrc === dataSrc}">
-								<a ng-click="newMetricSelectDataSource(dataSrc)">{{dataSrc.dataSource}}</a>
-							</li>
-						</ul>
-					</div>
-					<div class="col-md-8">
-						<ul class="nav nav-pills nav-stacked fixed-height">
-							<li class="disabled"><a>Metric</a></li>
-							<li ng-repeat="metric in dataSourceMetricList(_newMetricDataSrc, _newMetricFilter) track by $index" ng-class="{active: _newMetricDataMetric === metric}">
-								<a ng-click="newMetricSelectMetric(metric)">{{metric}}</a>
-							</li>
-						</ul>
-					</div>
-				</div>
-			</div>
-			<div class="modal-footer">
-				<span class="text-primary pull-left">{{_newMetricDataSrc.dataSource}} <span class="fa fa-arrow-right"></span> {{_newMetricDataMetric}}</span>
-				<button type="button" class="btn btn-default" data-dismiss="modal">
-					Close
-				</button>
-				<button type="button" class="btn btn-primary" ng-click="confirmSelectMetric()">
-					Select
-				</button>
-			</div>
-		</div>
-	</div>
-</div>
-
-
-
-<!-- Modal: Chart View -->
-<div class="modal fade" id="chartViewMDL" tabindex="-1" role="dialog">
-	<div class="modal-dialog modal-lg" role="document">
-		<div class="modal-content">
-			<div class="modal-header">
-				<button type="button" class="close" data-dismiss="modal" aria-label="Close">
-					<span aria-hidden="true">&times;</span>
-				</button>
-				<h4 class="modal-title">{{viewChart.title || viewChart.metrics[0].metric}}</h4>
-			</div>
-			<div class="modal-body">
-				<div nvd3="viewChart._data" data-title="{{viewChart.title || viewChart.metrics[0].metric}}"
-					 data-watching="true" data-chart="{{viewChart.chart || 'line'}}" data-config="getChartConfig(viewChart)" class="nvd3-chart-cntr lg"></div>
-			</div>
-			<div class="modal-footer">
-				<button type="button" class="btn btn-default" data-dismiss="modal">
-					Close
-				</button>
-			</div>
-		</div>
-	</div>
-</div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/eagle/blob/8b3729f9/eagle-webservice/src/main/webapp/_app/public/feature/topology/controller.js
----------------------------------------------------------------------
diff --git a/eagle-webservice/src/main/webapp/_app/public/feature/topology/controller.js b/eagle-webservice/src/main/webapp/_app/public/feature/topology/controller.js
deleted file mode 100644
index 94886c9..0000000
--- a/eagle-webservice/src/main/webapp/_app/public/feature/topology/controller.js
+++ /dev/null
@@ -1,257 +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.
- */
-
-(function() {
-	'use strict';
-
-	var featureControllers = angular.module('featureControllers');
-	var feature = featureControllers.register("topology", {
-		global: true	// Global Feature needn't add to applications
-	});
-
-	// ==============================================================
-	// =                       Initialization                       =
-	// ==============================================================
-
-	// ==============================================================
-	// =                          Function                          =
-	// ==============================================================
-	//feature.service("DashboardFormatter", function() {
-	//});
-
-	// ==============================================================
-	// =                         Controller                         =
-	// ==============================================================
-	feature.configNavItem("monitoring", "Topology", "usb");
-
-	// ========================= Monitoring =========================
-	feature.configController('monitoring', function(PageConfig, $scope, $interval, Entities, UI, Site, Application) {
-		var topologyRefreshInterval;
-
-		PageConfig.hideApplication = true;
-		PageConfig.hideSite = true;
-		PageConfig.pageTitle = "Topology Execution";
-
-		$scope.topologyExecutionList = null;
-
-		$scope.currentTopologyExecution = null;
-		$scope.currentTopologyExecutionOptList = [];
-
-		// ======================= Function =======================
-		function refreshExecutionList() {
-			var _list = Entities.queryEntities("TopologyExecutionService");
-			_list._promise.then(function () {
-				$scope.topologyExecutionList = _list;
-			});
-		}
-
-		$scope.showTopologyDetail = function (topologyExecution) {
-			$scope.currentTopologyExecution = topologyExecution;
-			$("#topologyMDL").modal();
-
-			$scope.currentTopologyExecutionOptList = Entities.queryEntities("TopologyOperationService", {
-				site: topologyExecution.tags.site,
-				application: topologyExecution.tags.application,
-				topology: topologyExecution.tags.topology,
-				_pageSize: 10,
-				_duration: 1000 * 60 * 60 * 24 * 30
-			});
-		};
-
-		$scope.getStatusClass = function (status) {
-			switch (status) {
-				case "NEW":
-					return "info";
-				case "STARTING":
-				case "STOPPING":
-					return "warning";
-				case "STARTED":
-					return "success";
-				case "STOPPED":
-					return "danger";
-				default:
-					return "default";
-			}
-		};
-
-		// ==================== Initialization ====================
-		refreshExecutionList();
-		topologyRefreshInterval = $interval(refreshExecutionList, 10 * 1000);
-
-		$scope.topologyList = Entities.queryEntities("TopologyDescriptionService");
-		$scope.topologyList._promise.then(function () {
-			$scope.topologyList = $.map($scope.topologyList, function (topology) {
-				return topology.tags.topology;
-			});
-		});
-
-		$scope.applicationList = $.map(Application.list, function (application) {
-			return application.tags.application;
-		});
-
-		$scope.siteList = $.map(Site.list, function (site) {
-			return site.tags.site;
-		});
-
-		// ================== Topology Execution ==================
-		$scope.newTopologyExecution = function () {
-			UI.createConfirm("Topology", {}, [
-				{field: "site", type: "select", valueList: $scope.siteList},
-				{field: "application", type: "select", valueList: $scope.applicationList},
-				{field: "topology", type: "select", valueList: $scope.topologyList}
-			], function (entity) {
-				for(var i = 0 ; i < $scope.topologyExecutionList.length; i += 1) {
-					var _entity = $scope.topologyExecutionList[i].tags;
-					if(_entity.site === entity.site && _entity.application === entity.application && _entity.topology === entity.topology) {
-						return "Topology already exist!";
-					}
-				}
-			}).then(null, null, function(holder) {
-				var _entity = {
-					tags: {
-						site: holder.entity.site,
-						application: holder.entity.application,
-						topology: holder.entity.topology
-					},
-					status: "NEW"
-				};
-				Entities.updateEntity("TopologyExecutionService", _entity)._promise.then(function() {
-					holder.closeFunc();
-					$scope.topologyExecutionList.push(_entity);
-					refreshExecutionList();
-				});
-			});
-		};
-
-		$scope.deleteTopologyExecution = function (topologyExecution) {
-			UI.deleteConfirm(topologyExecution.tags.topology).then(null, null, function(holder) {
-				Entities.deleteEntities("TopologyExecutionService", topologyExecution.tags)._promise.then(function() {
-					holder.closeFunc();
-					common.array.remove(topologyExecution, $scope.topologyExecutionList);
-				});
-			});
-		};
-
-		// ================== Topology Operation ==================
-		$scope.doTopologyOperation = function (topologyExecution, operation) {
-			$.dialog({
-				title: operation + " Confirm",
-				content: "Do you want to " + operation + " '" + topologyExecution.tags.topology + "'?",
-				confirm: true
-			}, function (ret) {
-				if(!ret) return;
-
-				var list = Entities.queryEntities("TopologyOperationService", {
-					site: topologyExecution.tags.site,
-					application: topologyExecution.tags.application,
-					topology: topologyExecution.tags.topology,
-					_pageSize: 20
-				});
-
-				list._promise.then(function () {
-					var lastOperation = common.array.find(operation, list, "tags.operation");
-					if(lastOperation && (lastOperation.status === "INITIALIZED" || lastOperation.status === "PENDING")) {
-						refreshExecutionList();
-						return;
-					}
-
-					Entities.updateEntity("rest/app/operation", {
-						tags: {
-							site: topologyExecution.tags.site,
-							application: topologyExecution.tags.application,
-							topology: topologyExecution.tags.topology,
-							operation: operation
-						},
-						status: "INITIALIZED"
-					}, {timestamp: false, hook: true});
-				});
-			});
-		};
-
-		$scope.startTopologyOperation = function (topologyExecution) {
-			$scope.doTopologyOperation(topologyExecution, "START");
-		};
-		$scope.stopTopologyOperation = function (topologyExecution) {
-			$scope.doTopologyOperation(topologyExecution, "STOP");
-		};
-
-		// ======================= Clean Up =======================
-		$scope.$on('$destroy', function() {
-			$interval.cancel(topologyRefreshInterval);
-		});
-	});
-
-	// ========================= Management =========================
-	feature.configController('management', function(PageConfig, $scope, Entities, UI) {
-		PageConfig.hideApplication = true;
-		PageConfig.hideSite = true;
-		PageConfig.pageTitle = "Topology";
-
-		var typeList = ["CLASS", "DYNAMIC"];
-		var topologyDefineAttrs = [
-			{field: "topology", name: "name"},
-			{field: "type", type: "select", valueList: typeList},
-			{field: "exeClass", name: "execution entry", description: function (entity) {
-				if(entity.type === "CLASS") return "Class implements interface TopologyExecutable";
-				if(entity.type === "DYNAMIC") return "DSL based topology definition";
-			}, type: "blob", rows: 5},
-			{field: "version", optional: true},
-			{field: "description", optional: true, type: "blob"}
-		];
-		var topologyUpdateAttrs = $.extend(topologyDefineAttrs.concat(), [{field: "topology", name: "name", readonly: true}]);
-
-		$scope.topologyList = Entities.queryEntities("TopologyDescriptionService");
-
-		$scope.newTopology = function () {
-			UI.createConfirm("Topology", {}, topologyDefineAttrs, function (entity) {
-				if(common.array.find(entity.topology, $scope.topologyList, "tags.topology", false, false)) {
-					return "Topology name conflict!";
-				}
-			}).then(null, null, function(holder) {
-				holder.entity.tags = {
-					topology: holder.entity.topology
-				};
-				Entities.updateEntity("TopologyDescriptionService", holder.entity, {timestamp: false})._promise.then(function() {
-					holder.closeFunc();
-					$scope.topologyList.push(holder.entity);
-				});
-			});
-		};
-
-		$scope.updateTopology = function (topology) {
-			UI.updateConfirm("Topology", $.extend({}, topology, {topology: topology.tags.topology}), topologyUpdateAttrs).then(null, null, function(holder) {
-				holder.entity.tags = {
-					topology: holder.entity.topology
-				};
-				Entities.updateEntity("TopologyDescriptionService", holder.entity, {timestamp: false})._promise.then(function() {
-					holder.closeFunc();
-					$.extend(topology, holder.entity);
-				});
-			});
-		};
-
-		$scope.deleteTopology = function (topology) {
-			UI.deleteConfirm(topology.tags.topology).then(null, null, function(holder) {
-				Entities.delete("TopologyDescriptionService", {topology: topology.tags.topology})._promise.then(function() {
-					holder.closeFunc();
-					common.array.remove(topology, $scope.topologyList);
-				});
-			});
-		};
-	});
-})();
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/eagle/blob/8b3729f9/eagle-webservice/src/main/webapp/_app/public/feature/topology/page/management.html
----------------------------------------------------------------------
diff --git a/eagle-webservice/src/main/webapp/_app/public/feature/topology/page/management.html b/eagle-webservice/src/main/webapp/_app/public/feature/topology/page/management.html
deleted file mode 100644
index 9e22c84..0000000
--- a/eagle-webservice/src/main/webapp/_app/public/feature/topology/page/management.html
+++ /dev/null
@@ -1,52 +0,0 @@
-<div class="box box-primary">
-	<div class="box-header with-border">
-		<i class="fa fa-cog"></i>
-		<a class="pull-right" href="#/config/topology/monitoring"><span class="fa fa-angle-right"></span> Monitoring</a>
-		<h3 class="box-title">
-			Management
-		</h3>
-	</div>
-	<div class="box-body">
-		<table class="table table-bordered">
-			<thead>
-				<tr>
-					<th>Name</th>
-					<th width="20%">Execution Class</th>
-					<th>Type</th>
-					<th width="50%">Description</th>
-					<th>Version</th>
-					<th width="70"></th>
-				</tr>
-			</thead>
-			<tbody>
-				<tr ng-repeat="item in topologyList">
-					<td>{{item.tags.topology}}</td>
-					<td><pre class="noWrap">{{item.exeClass}}</pre></td>
-					<td>{{item.type}}</td>
-					<td>{{item.description}}</td>
-					<td>{{item.version}}</td>
-					<td class="text-center">
-						<button class="rm fa fa-pencil btn btn-default btn-xs" uib-tooltip="Edit" tooltip-animation="false" ng-click="updateTopology(item)"> </button>
-						<button class="rm fa fa-trash-o btn btn-danger btn-xs" uib-tooltip="Delete" tooltip-animation="false" ng-click="deleteTopology(item)"> </button>
-					</td>
-				</tr>
-				<tr ng-if="topologyList.length === 0">
-					<td colspan="6">
-						<span class="text-muted">Empty list</span>
-					</td>
-				</tr>
-			</tbody>
-		</table>
-	</div>
-
-	<div class="box-footer">
-		<button class="btn btn-primary pull-right" ng-click="newTopology()">
-			New Topology
-			<i class="fa fa-plus-circle"> </i>
-		</button>
-	</div>
-
-	<div class="overlay" ng-hide="topologyList._promise.$$state.status === 1;">
-		<i class="fa fa-refresh fa-spin"></i>
-	</div>
-</div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/eagle/blob/8b3729f9/eagle-webservice/src/main/webapp/_app/public/feature/topology/page/monitoring.html
----------------------------------------------------------------------
diff --git a/eagle-webservice/src/main/webapp/_app/public/feature/topology/page/monitoring.html b/eagle-webservice/src/main/webapp/_app/public/feature/topology/page/monitoring.html
deleted file mode 100644
index 0acb2c1..0000000
--- a/eagle-webservice/src/main/webapp/_app/public/feature/topology/page/monitoring.html
+++ /dev/null
@@ -1,151 +0,0 @@
-<div class="box box-primary">
-	<div class="box-header with-border">
-		<i class="fa fa-eye"></i>
-		<a class="pull-right" href="#/config/topology/management"><span class="fa fa-angle-right"></span> Management</a>
-		<h3 class="box-title">
-			Monitoring
-		</h3>
-	</div>
-	<div class="box-body">
-		<div sorttable source="topologyExecutionList">
-			<table class="table table-bordered" ng-non-bindable>
-				<thead>
-				<tr>
-					<th width="70" sortpath="status">Status</th>
-					<th width="90" sortpath="tags.topology">Topology</th>
-					<th width="60" sortpath="tags.site">Site</th>
-					<th width="100" sortpath="tags.application">Application</th>
-					<th width="60" sortpath="mode">Mode</th>
-					<th sortpath="description">Description</th>
-					<th width="70" style="min-width: 70px;"></th>
-				</tr>
-				</thead>
-				<tbody>
-				<tr>
-					<td class="text-center">
-						<span class="label label-{{_parent.getStatusClass(item.status)}}">{{item.status}}</span>
-					</td>
-					<td><a ng-click="_parent.showTopologyDetail(item)">{{item.tags.topology}}</a></td>
-					<td>{{item.tags.site}}</td>
-					<td>{{item.tags.application}}</td>
-					<td>{{item.mode}}</td>
-					<td>{{item.description}}</td>
-					<td class="text-center">
-						<button ng-if="item.status === 'NEW' || item.status === 'STOPPED'" class="fa fa-play sm btn btn-default btn-xs" uib-tooltip="Start" tooltip-animation="false" ng-click="_parent.startTopologyOperation(item)"> </button>
-						<button ng-if="item.status === 'STARTED'" class="fa fa-stop sm btn btn-default btn-xs" uib-tooltip="Stop" tooltip-animation="false" ng-click="_parent.stopTopologyOperation(item)"> </button>
-						<button ng-if="item.status !== 'NEW' && item.status !== 'STARTED' && item.status !== 'STOPPED'" class="fa fa-ban sm btn btn-default btn-xs" disabled="disabled"> </button>
-						<button class="rm fa fa-trash-o btn btn-danger btn-xs" uib-tooltip="Delete" tooltip-animation="false" ng-click="_parent.deleteTopologyExecution(item)"> </button>
-					</td>
-				</tr>
-				</tbody>
-			</table>
-		</div>
-	</div>
-
-	<div class="box-footer">
-		<button class="btn btn-primary pull-right" ng-click="newTopologyExecution()">
-			New Topology Execution
-			<i class="fa fa-plus-circle"> </i>
-		</button>
-	</div>
-
-	<div class="overlay" ng-hide="topologyExecutionList._promise.$$state.status === 1;">
-		<i class="fa fa-refresh fa-spin"></i>
-	</div>
-</div>
-
-
-
-
-<!-- Modal: Topology Detail -->
-<div class="modal fade" id="topologyMDL" tabindex="-1" role="dialog">
-	<div class="modal-dialog modal-lg" role="document">
-		<div class="modal-content">
-			<div class="modal-header">
-				<button type="button" class="close" data-dismiss="modal" aria-label="Close">
-					<span aria-hidden="true">&times;</span>
-				</button>
-				<h4 class="modal-title">Topology Detail</h4>
-			</div>
-			<div class="modal-body">
-				<h3>Detail</h3>
-				<table class="table">
-					<tbody>
-						<tr>
-							<th>Site</th>
-							<td>{{currentTopologyExecution.tags.site}}</td>
-						</tr>
-						<tr>
-							<th>Application</th>
-							<td>{{currentTopologyExecution.tags.application}}</td>
-						</tr>
-						<tr>
-							<th>Topology</th>
-							<td>{{currentTopologyExecution.tags.topology}}</td>
-						</tr>
-						<tr>
-							<th>Full Name</th>
-							<td>{{currentTopologyExecution.fullName || "-"}}</td>
-						</tr>
-						<tr>
-							<th>Status</th>
-							<td>
-								<span class="label label-{{getStatusClass(currentTopologyExecution.status)}}">{{currentTopologyExecution.status}}</span>
-							</td>
-						</tr>
-						<tr>
-							<th>Mode</th>
-							<td>{{currentTopologyExecution.mode || "-"}}</td>
-						</tr>
-						<tr>
-							<th>Environment</th>
-							<td>{{currentTopologyExecution.environment || "-"}}</td>
-						</tr>
-						<tr>
-							<th>Url</th>
-							<td>
-								<a ng-if="currentTopologyExecution.url" href="{{currentTopologyExecution.url}}" target="_blank">{{currentTopologyExecution.url}}</a>
-								<span ng-if="!currentTopologyExecution.url">-</span>
-							</td>
-						</tr>
-						<tr>
-							<th>Description</th>
-							<td>{{currentTopologyExecution.description || "-"}}</td>
-						</tr>
-						<tr>
-							<th>Last Modified Date</th>
-							<td>{{common.format.date(currentTopologyExecution.lastModifiedDate) || "-"}}</td>
-						</tr>
-					</tbody>
-				</table>
-
-				<h3>Latest Operations</h3>
-				<div class="table-responsive">
-					<table class="table table-bordered table-sm margin-bottom-none">
-						<thead>
-							<tr>
-								<th>Date Time</th>
-								<th>Operation</th>
-								<th>Status</th>
-								<th>Message</th>
-							</tr>
-						</thead>
-						<tbody>
-							<tr ng-repeat="action in currentTopologyExecutionOptList track by $index">
-								<td>{{common.format.date(action.lastModifiedDate) || "-"}}</td>
-								<td>{{action.tags.operation}}</td>
-								<td>{{action.status}}</td>
-								<td><pre class="noWrap">{{action.message}}</pre></td>
-							</tr>
-						</tbody>
-					</table>
-				</div>
-			</div>
-			<div class="modal-footer">
-				<button type="button" class="btn btn-default" data-dismiss="modal">
-					Close
-				</button>
-			</div>
-		</div>
-	</div>
-</div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/eagle/blob/8b3729f9/eagle-webservice/src/main/webapp/_app/public/feature/userProfile/controller.js
----------------------------------------------------------------------
diff --git a/eagle-webservice/src/main/webapp/_app/public/feature/userProfile/controller.js b/eagle-webservice/src/main/webapp/_app/public/feature/userProfile/controller.js
deleted file mode 100644
index ed619d3..0000000
--- a/eagle-webservice/src/main/webapp/_app/public/feature/userProfile/controller.js
+++ /dev/null
@@ -1,268 +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.
- */
-
-(function() {
-	'use strict';
-
-	var featureControllers = angular.module('featureControllers');
-	var feature = featureControllers.register("userProfile");
-
-	// ==============================================================
-	// =                          Function                          =
-	// ==============================================================
-
-	// ==============================================================
-	// =                        User Profile                        =
-	// ==============================================================
-
-	// ======================== Profile List ========================
-	//feature.navItem("list", "User Profiles", "graduation-cap");
-	feature.controller('list', function(PageConfig, Site, $scope, $interval, Entities) {
-		PageConfig.pageSubTitle = Site.current().tags.site;
-
-		$scope.common = common;
-		$scope.algorithms = [];
-
-		// ======================================== Algorithms ========================================
-		$scope.algorithmEntity = {};
-		Entities.queryEntities("AlertDefinitionService", {site: Site.current().tags.site, application: "userProfile"})._promise.then(function(data) {
-			$scope.algorithmEntity = common.getValueByPath(data, "obj[0]");
-			$scope.algorithmEntity.policy = common.parseJSON($scope.algorithmEntity.policyDef);
-		});
-
-		// ======================================= User profile =======================================
-		$scope.profileList = Entities.queryEntities("MLModelService", {site: Site.current().tags.site}, ["user", "algorithm", "content", "version"]);
-		$scope.profileList._promise.then(function() {
-			var _algorithms = {};
-			var _users = {};
-
-			// Map user
-			$.each($scope.profileList, function(i, unit) {
-				_algorithms[unit.tags.algorithm] = unit.tags.algorithm;
-				var _user = _users[unit.tags.user] = _users[unit.tags.user] || {user: unit.tags.user};
-				_user[unit.tags.algorithm] = {
-					version: unit.version
-				};
-
-				// DE
-				if(unit.tags.algorithm === "DE") {
-					var _statistics = common.parseJSON(unit.content);
-					_statistics = common.getValueByPath(_statistics, "statistics", []);
-					_user[unit.tags.algorithm].topCommands = $.map(common.array.top(_statistics, "mean"), function(command) {
-						return command.commandName;
-					});
-				}
-			});
-
-			// Map algorithms
-			$scope.algorithms = $.map(_algorithms, function(algorithm) {
-				return algorithm;
-			}).sort();
-
-			$scope.profileList.splice(0);
-			$scope.profileList.push.apply($scope.profileList, common.map.toArray(_users));
-		});
-
-		// =========================================== Task ===========================================
-		$scope.tasks = [];
-		function _loadTasks() {
-			var _tasks = Entities.queryEntities("ScheduleTaskService", {
-				site: Site.current().tags.site,
-				_pageSize: 100,
-				_duration: 1000 * 60 * 60 * 24 * 14,
-				__ETD: 1000 * 60 * 60 * 24
-			});
-			_tasks._promise.then(function() {
-				$scope.tasks.splice(0);
-				$scope.tasks.push.apply($scope.tasks, _tasks);
-
-				// Duration
-				$.each($scope.tasks, function(i, data) {
-					if(data.timestamp && data.updateTime) {
-						var _ms = (new moment(data.updateTime)).diff(new moment(data.timestamp));
-						var _d = moment.duration(_ms);
-						data._duration = Math.floor(_d.asHours()) + moment.utc(_ms).format(":mm:ss");
-						data.duration = _ms;
-					} else {
-						data._duration = "--";
-					}
-				});
-			});
-		}
-
-		$scope.runningTaskCount = function () {
-			return common.array.count($scope.tasks, "INITIALIZED", "status") +
-				common.array.count($scope.tasks, "PENDING", "status") +
-				common.array.count($scope.tasks, "EXECUTING", "status");
-		};
-
-		// Create task
-		$scope.updateTask = function() {
-			$.dialog({
-				title: "Confirm",
-				content: "Do you want to update now?",
-				confirm: true
-			}, function(ret) {
-				if(!ret) return;
-
-				var _entity = {
-					status: "INITIALIZED",
-					detail: "Newly created command",
-					tags: {
-						site: Site.current().tags.site,
-						type: "USER_PROFILE_TRAINING"
-					},
-					timestamp: +new Date()
-				};
-				Entities.updateEntity("ScheduleTaskService", _entity, {timestamp: false})._promise.success(function(data) {
-					if(!Entities.dialog(data)) {
-						_loadTasks();
-					}
-				});
-			});
-		};
-
-		// Show detail
-		$scope.showTaskDetail = function(task) {
-			var _content = $("<pre>").text(task.detail);
-
-			var $mdl = $.dialog({
-				title: "Detail",
-				content: _content
-			});
-
-			_content.click(function(e) {
-				if(!e.ctrlKey) return;
-
-				$.dialog({
-					title: "Confirm",
-					content: "Remove this task?",
-					confirm: true
-				}, function(ret) {
-					if(!ret) return;
-
-					$mdl.modal('hide');
-					Entities.deleteEntity("ScheduleTaskService", task)._promise.then(function() {
-						_loadTasks();
-					});
-				});
-			});
-		};
-
-		_loadTasks();
-		var _loadInterval = $interval(_loadTasks, app.time.refreshInterval);
-		$scope.$on('$destroy',function(){
-			$interval.cancel(_loadInterval);
-		});
-	});
-
-	// ======================= Profile Detail =======================
-	feature.controller('detail', function(PageConfig, Site, $scope, $wrapState, Entities) {
-		PageConfig.pageTitle = "User Profile";
-		PageConfig.pageSubTitle = Site.current().tags.site;
-		PageConfig
-			.addNavPath("User Profile", "/userProfile/list")
-			.addNavPath("Detail");
-
-		$scope.user = $wrapState.param.filter;
-
-		// User profile
-		$scope.profiles = {};
-		$scope.profileList = Entities.queryEntities("MLModelService", {site: Site.current().tags.site, user: $scope.user});
-		$scope.profileList._promise.then(function() {
-			$.each($scope.profileList, function(i, unit) {
-				unit._content = common.parseJSON(unit.content);
-				$scope.profiles[unit.tags.algorithm] = unit;
-			});
-
-			// DE
-			if($scope.profiles.DE) {
-				console.log($scope.profiles.DE);
-
-				$scope.profiles.DE._chart = {};
-
-				$scope.profiles.DE.estimates = {};
-				$.each($scope.profiles.DE._content, function(key, value) {
-					if(key !== "statistics") {
-						$scope.profiles.DE.estimates[key] = value;
-					}
-				});
-
-				var _meanList = [];
-				var _stddevList = [];
-
-				$.each($scope.profiles.DE._content.statistics, function(i, unit) {
-					_meanList[i] = {
-						x: unit.commandName,
-						y: unit.mean
-					};
-					_stddevList[i] = {
-						x: unit.commandName,
-						y: unit.stddev
-					};
-				});
-				$scope.profiles.DE._chart.series = [
-					{
-						key: "mean",
-						values: _meanList
-					},
-					{
-						key: "stddev",
-						values: _stddevList
-					}
-				];
-
-				// Percentage table list
-				$scope.profiles.DE.meanList = [];
-				var _total = common.array.sum($scope.profiles.DE._content.statistics, "mean");
-				$.each($scope.profiles.DE._content.statistics, function(i, unit) {
-					$scope.profiles.DE.meanList.push({
-						command: unit.commandName,
-						percentage: unit.mean / _total
-					});
-				});
-			}
-
-			// EigenDecomposition
-			if($scope.profiles.EigenDecomposition && $scope.profiles.EigenDecomposition._content.principalComponents) {
-				$scope.profiles.EigenDecomposition._chart = {
-					series: [],
-				};
-
-				$.each($scope.profiles.EigenDecomposition._content.principalComponents, function(z, grp) {
-					var _line = [];
-					$.each(grp, function(x, y) {
-						_line.push([x,y,z]);
-					});
-
-					$scope.profiles.EigenDecomposition._chart.series.push({
-						data: _line
-					});
-				});
-			}
-		});
-
-		// UI
-		$scope.showRawData = function(content) {
-			$.dialog({
-				title: "Raw Data",
-				content: $("<pre>").text(content)
-			});
-		};
-	});
-})();
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/eagle/blob/8b3729f9/eagle-webservice/src/main/webapp/_app/public/feature/userProfile/page/detail.html
----------------------------------------------------------------------
diff --git a/eagle-webservice/src/main/webapp/_app/public/feature/userProfile/page/detail.html b/eagle-webservice/src/main/webapp/_app/public/feature/userProfile/page/detail.html
deleted file mode 100644
index 0f94e03..0000000
--- a/eagle-webservice/src/main/webapp/_app/public/feature/userProfile/page/detail.html
+++ /dev/null
@@ -1,87 +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.
-  -->
-<div class="box box-primary">
-	<div class="box-header with-border">
-		<i class="fa fa-user"> </i>
-		<h3 class="box-title">
-			{{user}}
-		</h3>
-	</div>
-	<div class="box-body">
-		<div>
-			<div class="inline-group">
-				<dl><dt>User</dt><dd>{{user}}</dd></dl>
-				<dl><dt>Site</dt><dd>{{Site.current().tags.site}}</dd></dl>
-			</div>
-			<div class="inline-group">
-				<dl><dt>Other Info</dt><dd class="text-muted">N/A</dd></dl>
-			</div>
-		</div>
-
-		<div class="overlay" ng-hide="profileList._promise.$$state.status === 1;">
-			<span class="fa fa-refresh fa-spin"></span>
-		</div>
-	</div>
-</div>
-
-<!-- Analysis -->
-<div class="nav-tabs-custom">
-	<ul class="nav nav-tabs">
-		<li class="active">
-			<a href="[data-id='DE']" data-toggle="tab" ng-click=" currentTab='DE'">DE</a>
-		</li>
-		<li>
-			<a href="[data-id='EigenDecomposition']" data-toggle="tab" ng-click=" currentTab='EigenDecomposition'">EigenDecomposition</a>
-		</li>
-		<li class="pull-right">
-			<button class="btn btn-primary" ng-click="showRawData(currentTab === 'EigenDecomposition' ? profiles.EigenDecomposition.content : profiles.DE.content)">Raw Data</button>
-		</li>
-	</ul>
-	<div class="tab-content">
-		<div class="tab-pane active" data-id="DE">
-			<div class="row">
-				<div class="col-md-9">
-					<div nvd3="profiles.DE._chart.series" data-config="{chart: 'column', xType: 'text', height: 400}" class="nvd3-chart-cntr" height="400"></div>
-					<div class="inline-group text-center">
-						<dl ng-repeat="(key, value) in profiles.DE.estimates"><dt>{{key}}</dt><dd>{{value}}</dd></dl>
-					</div>
-				</div>
-
-				<div class="col-md-3">
-					<table class="table table-bordered">
-						<thead>
-							<tr>
-								<th>Command</th>
-								<th>Percentage</th>
-							</tr>
-						</thead>
-						<tbody>
-							<tr ng-repeat="unit in profiles.DE.meanList">
-								<td>{{unit.command}}</td>
-								<td class="text-right">{{(unit.percentage*100).toFixed(2)}}%</td>
-							</tr>
-						</tbody>
-					</table>
-				</div>
-			</div>
-		</div><!-- /.tab-pane -->
-		<div class="tab-pane" data-id="EigenDecomposition">
-			<div line3d-chart height="400" data="profiles.EigenDecomposition._chart.series"> </div>
-		</div><!-- /.tab-pane -->
-	</div><!-- /.tab-content -->
-</div>

http://git-wip-us.apache.org/repos/asf/eagle/blob/8b3729f9/eagle-webservice/src/main/webapp/_app/public/feature/userProfile/page/list.html
----------------------------------------------------------------------
diff --git a/eagle-webservice/src/main/webapp/_app/public/feature/userProfile/page/list.html b/eagle-webservice/src/main/webapp/_app/public/feature/userProfile/page/list.html
deleted file mode 100644
index 2f14479..0000000
--- a/eagle-webservice/src/main/webapp/_app/public/feature/userProfile/page/list.html
+++ /dev/null
@@ -1,138 +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.
-  -->
-<div class="box box-primary">
-	<div class="box-header with-border">
-		<i class="fa fa-list-alt"> </i>
-		<h3 class="box-title">
-			User Profiles
-			<small><a data-toggle="collapse" href="[data-id='algorithms']">Detail</a></small>
-		</h3>
-		<div class="pull-right">
-			<a class="label label-primary" ng-class="runningTaskCount() ? 'label-primary' : 'label-default'" data-toggle="modal" data-target="#taskMDL">Update</a>
-		</div>
-	</div>
-	<div class="box-body">
-		<!-- Algorithms -->
-		<div data-id="algorithms" class="collapse">
-			<table class="table table-bordered">
-				<thead>
-					<tr>
-						<th>Name</th>
-						<td>Feature</td>
-					</tr>
-				</thead>
-				<tbody>
-					<tr ng-repeat="algorithm in algorithmEntity.policy.algorithms">
-						<td>{{algorithm.name}}</td>
-						<td>{{algorithm.features}}</td>
-					</tr>
-				</tbody>
-			</table>
-			<hr/>
-		</div>
-
-		<!-- User Profile List -->
-		<p ng-show="profileList._promise.$$state.status !== 1">
-			<span class="fa fa-refresh fa-spin"> </span>
-			Loading...
-		</p>
-
-		<div sorttable source="profileList" ng-show="profileList._promise.$$state.status === 1">
-			<table class="table table-bordered" ng-non-bindable>
-				<thead>
-					<tr>
-						<th width="10%" sortpath="user">User</th>
-						<th>Most Predominat Feature</th>
-						<th width="10"></th>
-					</tr>
-				</thead>
-				<tbody>
-					<tr>
-						<td>
-							<a href="#/userProfile/detail/{{item.user}}">{{item.user}}</a>
-						</td>
-						<td>
-							{{item.DE.topCommands.slice(0,3).join(", ")}}
-						</td>
-						<td>
-							<a href="#/userProfile/detail/{{item.user}}">Detail</a>
-						</td>
-					</tr>
-				</tbody>
-			</table>
-		</div>
-	</div>
-</div>
-
-<!-- Modal: User profile Schedule Task -->
-<div class="modal fade" id="taskMDL" tabindex="-1" role="dialog">
-	<div class="modal-dialog modal-lg" role="document">
-		<div class="modal-content">
-			<div class="modal-header">
-				<button type="button" class="close" data-dismiss="modal" aria-label="Close">
-					<span aria-hidden="true">&times;</span>
-				</button>
-				<h4 class="modal-title">Training History</h4>
-			</div>
-			<div class="modal-body">
-				<div sorttable source="tasks">
-					<table class="table table-bordered" ng-non-bindable>
-						<thead>
-							<tr>
-								<th sortpath="tags.type">Command</th>
-								<th sortpath="timestamp">Start Time</th>
-								<th sortpath="updateTime">Update Time</th>
-								<th sortpath="duration">Duration</th>
-								<th sortpath="status">Status</th>
-								<th width="10"> </th>
-							</tr>
-						</thead>
-						<tbody>
-							<tr>
-								<td>{{item.tags.type}}</td>
-								<td>{{common.format.date(item.timestamp) || "--"}}</td>
-								<td>{{common.format.date(item.updateTime) || "--"}}</td>
-								<td>{{item._duration}}</td>
-								<td class="text-nowrap">
-									<span class="fa fa-hourglass-start text-muted" ng-show="item.status === 'INITIALIZED'"></span>
-									<span class="fa fa-hourglass-half text-info" ng-show="item.status === 'PENDING'"></span>
-									<span class="fa fa-circle-o-notch text-primary" ng-show="item.status === 'EXECUTING'"></span>
-									<span class="fa fa-check-circle text-success" ng-show="item.status === 'SUCCEEDED'"></span>
-									<span class="fa fa-exclamation-circle text-danger" ng-show="item.status === 'FAILED'"></span>
-									<span class="fa fa-ban text-muted" ng-show="item.status === 'CANCELED'"></span>
-									{{item.status}}
-								</td>
-								<td>
-									<a ng-click="_parent.showTaskDetail(item)">Detail</a>
-								</td>
-							</tr>
-						</tbody>
-					</table>
-				</div>
-			</div>
-			<div class="modal-footer">
-				<button type="button" class="btn btn-primary pull-left" ng-click="updateTask()" ng-show="Auth.isRole('ROLE_ADMIN')">
-					Update Now
-				</button>
-				<button type="button" class="btn btn-default" data-dismiss="modal">
-					Close
-				</button>
-			</div>
-		</div>
-	</div>
-</div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/eagle/blob/8b3729f9/eagle-webservice/src/main/webapp/_app/public/images/favicon.png
----------------------------------------------------------------------
diff --git a/eagle-webservice/src/main/webapp/_app/public/images/favicon.png b/eagle-webservice/src/main/webapp/_app/public/images/favicon.png
deleted file mode 100644
index 3bede2a..0000000
Binary files a/eagle-webservice/src/main/webapp/_app/public/images/favicon.png and /dev/null differ

http://git-wip-us.apache.org/repos/asf/eagle/blob/8b3729f9/eagle-webservice/src/main/webapp/_app/public/images/favicon_white.png
----------------------------------------------------------------------
diff --git a/eagle-webservice/src/main/webapp/_app/public/images/favicon_white.png b/eagle-webservice/src/main/webapp/_app/public/images/favicon_white.png
deleted file mode 100644
index 9879e92..0000000
Binary files a/eagle-webservice/src/main/webapp/_app/public/images/favicon_white.png and /dev/null differ

http://git-wip-us.apache.org/repos/asf/eagle/blob/8b3729f9/eagle-webservice/src/main/webapp/_app/public/js/app.config.js
----------------------------------------------------------------------
diff --git a/eagle-webservice/src/main/webapp/_app/public/js/app.config.js b/eagle-webservice/src/main/webapp/_app/public/js/app.config.js
deleted file mode 100644
index d7c4be9..0000000
--- a/eagle-webservice/src/main/webapp/_app/public/js/app.config.js
+++ /dev/null
@@ -1,126 +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.
- */
-
-(function() {
-	'use strict';
-
-	app.config = {
-		// ============================================================================
-		// =                                   URLs                                   =
-		// ============================================================================
-		urls: {
-			HOST: '..',
-
-			updateEntity: 'rest/entities?serviceName=${serviceName}',
-			queryEntity: 'rest/entities/rowkey?serviceName=${serviceName}&value=${encodedRowkey}',
-			queryEntities: 'rest/entities?query=${serviceName}[${condition}]{${values}}&pageSize=100000',
-			deleteEntity: 'rest/entities/delete?serviceName=${serviceName}&byId=true',
-			deleteEntities: 'rest/entities?query=${serviceName}[${condition}]{*}&pageSize=100000',
-
-			queryGroup: 'rest/entities?query=${serviceName}[${condition}]<${groupBy}>{${values}}&pageSize=100000',
-			querySeries: 'rest/entities?query=${serviceName}[${condition}]<${groupBy}>{${values}}&pageSize=100000&timeSeries=true&intervalmin=${intervalmin}',
-
-			query: 'rest/',
-
-			userProfile: 'rest/authentication',
-			logout: 'logout',
-
-			maprNameResolver: '../rest/maprNameResolver',
-
-			DELETE_HOOK: {
-				FeatureDescService: 'rest/module/feature?feature=${feature}',
-				ApplicationDescService: 'rest/module/application?application=${application}',
-				SiteDescService: 'rest/module/site?site=${site}',
-				TopologyDescriptionService: 'rest/app/topology?topology=${topology}'
-			},
-			UPDATE_HOOK: {
-				SiteDescService: 'rest/module/siteApplication'
-			}
-		},
-	};
-
-	// ============================================================================
-	// =                                   URLs                                   =
-	// ============================================================================
-	app.getURL = function(name, kvs) {
-		var _path = app.config.urls[name];
-		if(!_path) throw "URL:'" + name + "' not exist!";
-		var _url = app.packageURL(_path);
-		if(kvs !== undefined) {
-			_url = common.template(_url, kvs);
-		}
-		return _url;
-	};
-
-	app.getMapRNameResolverURL = function(name,value, site) {
-		var key = "maprNameResolver";
-		var _path = app.config.urls[key];
-		if(!_path) throw "URL:'" + name + "' not exist!";
-		var _url = _path;
-		if(name == "fNameResolver") {
-			_url +=  "/" + name + "?fName=" + value + "&site=" + site;
-		} else if(name == "sNameResolver") {
-			_url +=  "/" + name + "?sName=" + value + "&site=" + site;
-		} else if (name == "vNameResolver") {
-			_url += "/" + name + "?vName=" + value + "&site=" + site;
-		} else{
-			throw "resolver:'" + name + "' not exist!";
-		}
-		return _url;
-	};
-
-	function getHookURL(hookType, serviceName) {
-		var _path = app.config.urls[hookType][serviceName];
-		if(!_path) return null;
-
-		return app.packageURL(_path);
-	}
-
-	/***
-	 * Eagle support delete function to process special entity delete. Which will delete all the relative entity.
-	 * @param serviceName
-	 */
-	app.getDeleteURL = function(serviceName) {
-		return getHookURL('DELETE_HOOK', serviceName);
-	};
-
-	/***
-	 * Eagle support update function to process special entity update. Which will update all the relative entity.
-	 * @param serviceName
-	 */
-	app.getUpdateURL = function(serviceName) {
-		return getHookURL('UPDATE_HOOK', serviceName);
-	};
-
-	app.packageURL = function (path) {
-		var _host = localStorage.getItem("HOST") || app.config.urls.HOST;
-		return (_host ? _host + "/" : '') + path;
-	};
-
-	app._Host = function(host) {
-		if(host) {
-			localStorage.setItem("HOST", host);
-			return app;
-		}
-		return localStorage.getItem("HOST");
-	};
-	app._Host.clear = function() {
-		localStorage.removeItem("HOST");
-	};
-	app._Host.sample = "http://localhost:9099/eagle-service";
-})();
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/eagle/blob/8b3729f9/eagle-webservice/src/main/webapp/_app/public/js/app.js
----------------------------------------------------------------------
diff --git a/eagle-webservice/src/main/webapp/_app/public/js/app.js b/eagle-webservice/src/main/webapp/_app/public/js/app.js
deleted file mode 100644
index 70b4afe..0000000
--- a/eagle-webservice/src/main/webapp/_app/public/js/app.js
+++ /dev/null
@@ -1,499 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-var app = {};
-
-(function() {
-	'use strict';
-
-	/* App Module */
-	var eagleApp = angular.module('eagleApp', ['ngRoute', 'ngAnimate', 'ui.router', 'eagleControllers', 'featureControllers', 'eagle.service']);
-
-	// GRUNT REPLACEMENT: eagleApp.buildTimestamp = TIMESTAMP
-	eagleApp._TRS = function() {
-		return eagleApp.buildTimestamp || Math.random();
-	};
-
-	// ======================================================================================
-	// =                                   Feature Module                                   =
-	// ======================================================================================
-	var FN_ARGS = /^[^\(]*\(\s*([^\)]*)\)/m;
-	var FN_ARG_SPLIT = /,/;
-	var FN_ARG = /^\s*(_?)(\S+?)\1\s*$/;
-	var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;
-
-	var featureControllers = angular.module('featureControllers', ['ui.bootstrap', 'eagle.components']);
-	var featureControllerCustomizeHtmlTemplate = {};
-	var featureControllerProvider;
-	var featureProvider;
-
-	featureControllers.config(function ($controllerProvider, $provide) {
-		featureControllerProvider = $controllerProvider;
-		featureProvider = $provide;
-	});
-
-	featureControllers.service("Feature", function($wrapState, PageConfig, ConfigPageConfig, FeaturePageConfig) {
-		var _features = {};
-		var _services = {};
-
-		var Feature = function(name, config) {
-			this.name = name;
-			this.config = config || {};
-			this.features = {};
-		};
-
-		/***
-		 * Inner function. Replace the dependency of constructor.
-		 * @param constructor
-		 * @private
-		 */
-		Feature.prototype._replaceDependencies = function(constructor) {
-			var i, srvName;
-			var _constructor, _$inject;
-			var fnText, argDecl;
-
-			if($.isArray(constructor)) {
-				_constructor = constructor[constructor.length - 1];
-				_$inject = constructor.slice(0, -1);
-			} else if(constructor.$inject) {
-				_constructor = constructor;
-				_$inject = constructor.$inject;
-			} else {
-				_$inject = [];
-				_constructor = constructor;
-				fnText = constructor.toString().replace(STRIP_COMMENTS, '');
-				argDecl = fnText.match(FN_ARGS);
-				$.each(argDecl[1].split(FN_ARG_SPLIT), function(i, arg) {
-					arg.replace(FN_ARG, function(all, underscore, name) {
-						_$inject.push(name);
-					});
-				});
-			}
-			_constructor.$inject = _$inject;
-
-			for(i = 0 ; i < _$inject.length ; i += 1) {
-				srvName = _$inject[i];
-				_$inject[i] = this.features[srvName] || _$inject[i];
-			}
-
-			return _constructor;
-		};
-
-		/***
-		 * Register a common service for feature usage. Common service will share between the feature. If you are coding customize feature, use 'Feature.service' is the better way.
-		 * @param name
-		 * @param constructor
-		 */
-		Feature.prototype.commonService = function(name, constructor) {
-			if(!_services[name]) {
-				featureProvider.service(name, constructor);
-				_services[name] = this.name;
-			} else {
-				throw "Service '" + name + "' has already be registered by feature '" + _services[name] + "'";
-			}
-		};
-
-		/***
-		 * Register a service for feature usage.
-		 * @param name
-		 * @param constructor
-		 */
-		Feature.prototype.service = function(name, constructor) {
-			var _serviceName;
-			if(!this.features[name]) {
-				_serviceName = "__FEATURE_" + this.name + "_" + name;
-				featureProvider.service(_serviceName, this._replaceDependencies(constructor));
-				this.features[name] = _serviceName;
-			} else {
-				console.warn("Service '" + name + "' has already be registered.");
-			}
-		};
-
-		/***
-		 * Create an navigation item in left navigation bar
-		 * @param path
-		 * @param title
-		 * @param icon use Font Awesome. Needn't with 'fa fa-'.
-		 */
-		Feature.prototype.navItem = function(path, title, icon) {
-			title = title || path;
-			icon = icon || "question";
-
-			FeaturePageConfig.addNavItem(this.name, {
-				icon: icon,
-				title: title,
-				url: "#/" + this.name + "/" + path
-			});
-		};
-
-		/***
-		 * Register a controller.
-		 * @param name
-		 * @param constructor
-		 */
-		Feature.prototype.controller = function(name, constructor, htmlTemplatePath) {
-			var _name = this.name + "_" + name;
-
-			// Replace feature registered service
-			constructor = this._replaceDependencies(constructor);
-
-			// Register controller
-			featureControllerProvider.register(_name, constructor);
-			if(htmlTemplatePath) {
-				featureControllerCustomizeHtmlTemplate[_name] = htmlTemplatePath;
-			}
-
-			return _name;
-		};
-
-		/***
-		 * Register a configuration controller for admin usage.
-		 * @param name
-		 * @param constructor
-		 */
-		Feature.prototype.configController = function(name, constructor, htmlTemplatePath) {
-			var _name = "config_" + this.name + "_" + name;
-
-			// Replace feature registered service
-			constructor = this._replaceDependencies(constructor);
-
-			// Register controller
-			featureControllerProvider.register(_name, constructor);
-			if(htmlTemplatePath) {
-				featureControllerCustomizeHtmlTemplate[_name] = htmlTemplatePath;
-			}
-
-			return _name;
-		};
-
-		/***
-		 * Create an navigation item in left navigation bar for admin configuraion page
-		 * @param path
-		 * @param title
-		 * @param icon use Font Awesome. Needn't with 'fa fa-'.
-		 */
-		Feature.prototype.configNavItem = function(path, title, icon) {
-			title = title || path;
-			icon = icon || "question";
-
-			ConfigPageConfig.addNavItem(this.name, {
-				icon: icon,
-				title: title,
-				url: "#/config/" + this.name + "/" + path
-			});
-		};
-
-		// Register
-		featureControllers.register = Feature.register = function(featureName, config) {
-			_features[featureName] = _features[featureName] || new Feature(featureName, config);
-			return _features[featureName];
-		};
-
-		// Page go
-		Feature.go = function(feature, page, filter) {
-			if(!filter) {
-				$wrapState.go("page", {
-					feature: feature,
-					page: page
-				}, 2);
-			} else {
-				$wrapState.go("pageFilter", {
-					feature: feature,
-					page: page,
-					filter: filter
-				}, 2);
-			}
-		};
-
-		// Get feature by name
-		Feature.get = function (featureName) {
-			return _features[featureName];
-		};
-
-		return Feature;
-	});
-
-	// ======================================================================================
-	// =                                   Router config                                    =
-	// ======================================================================================
-	eagleApp.config(function ($stateProvider, $urlRouterProvider, $animateProvider) {
-		// Resolve
-		function _resolve(config) {
-			config = config || {};
-
-			var resolve = {
-				Site: function (Site) {
-					return Site._promise();
-				},
-				Authorization: function (Authorization) {
-					if(!config.roleType) {
-						return Authorization._promise();
-					} else {
-						return Authorization.rolePromise(config.roleType);
-					}
-				},
-				Application: function (Application) {
-					return Application._promise();
-				}
-			};
-
-			if(config.featureCheck) {
-				resolve._navigationCheck = function($q, $wrapState, Site, Application) {
-					var _deferred = $q.defer();
-
-					$q.all(Site._promise(), Application._promise()).then(function() {
-						var _match, i, tmpApp;
-						var _site = Site.current();
-						var _app = Application.current();
-
-						// Check application
-						if(_site && (
-							!_app ||
-							!_site.applicationList.set[_app.tags.application] ||
-							!_site.applicationList.set[_app.tags.application].enabled
-							)
-						) {
-							_match = false;
-
-							for(i = 0 ; i < _site.applicationGroupList.length ; i += 1) {
-								tmpApp = _site.applicationGroupList[i].enabledList[0];
-								if(tmpApp) {
-									_app = Application.current(tmpApp);
-									_match = true;
-									break;
-								}
-							}
-
-							if(!_match) {
-								_app = null;
-								Application.current(null);
-							}
-						}
-					}).finally(function() {
-						_deferred.resolve();
-					});
-
-					return _deferred.promise;
-				};
-			}
-
-			return resolve;
-		}
-
-		// Router
-		var _featureBase = {
-			templateUrl: function ($stateParams) {
-				var _htmlTemplate = featureControllerCustomizeHtmlTemplate[$stateParams.feature + "_" + $stateParams.page];
-				return  "public/feature/" + $stateParams.feature + "/page/" + (_htmlTemplate ||  $stateParams.page) + ".html?_=" + eagleApp._TRS();
-			},
-			controllerProvider: function ($stateParams) {
-				return $stateParams.feature + "_" + $stateParams.page;
-			},
-			resolve: _resolve({featureCheck: true}),
-			pageConfig: "FeaturePageConfig"
-		};
-
-		$urlRouterProvider.otherwise("/landing");
-		$stateProvider
-			// =================== Landing ===================
-			.state('landing', {
-				url: "/landing",
-				templateUrl: "partials/landing.html?_=" + eagleApp._TRS(),
-				controller: "landingCtrl",
-				resolve: _resolve({featureCheck: true})
-			})
-
-			// ================ Authorization ================
-			.state('login', {
-				url: "/login",
-				templateUrl: "partials/login.html?_=" + eagleApp._TRS(),
-				controller: "authLoginCtrl",
-				access: {skipCheck: true}
-			})
-
-			// ================ Configuration ================
-			// Site
-			.state('configSite', {
-				url: "/config/site",
-				templateUrl: "partials/config/site.html?_=" + eagleApp._TRS(),
-				controller: "configSiteCtrl",
-				pageConfig: "ConfigPageConfig",
-				resolve: _resolve({roleType: 'ROLE_ADMIN'})
-			})
-
-			// Application
-			.state('configApplication', {
-				url: "/config/application",
-				templateUrl: "partials/config/application.html?_=" + eagleApp._TRS(),
-				controller: "configApplicationCtrl",
-				pageConfig: "ConfigPageConfig",
-				resolve: _resolve({roleType: 'ROLE_ADMIN'})
-			})
-
-			// Feature
-			.state('configFeature', {
-				url: "/config/feature",
-				templateUrl: "partials/config/feature.html?_=" + eagleApp._TRS(),
-				controller: "configFeatureCtrl",
-				pageConfig: "ConfigPageConfig",
-				resolve: _resolve({roleType: 'ROLE_ADMIN'})
-			})
-
-			// Feature configuration page
-			.state('configFeatureDetail', $.extend({url: "/config/:feature/:page"}, {
-				templateUrl: function ($stateParams) {
-					var _htmlTemplate = featureControllerCustomizeHtmlTemplate[$stateParams.feature + "_" + $stateParams.page];
-					return  "public/feature/" + $stateParams.feature + "/page/" + (_htmlTemplate ||  $stateParams.page) + ".html?_=" + eagleApp._TRS();
-				},
-				controllerProvider: function ($stateParams) {
-					return "config_" + $stateParams.feature + "_" + $stateParams.page;
-				},
-				pageConfig: "ConfigPageConfig",
-				resolve: _resolve({roleType: 'ROLE_ADMIN'})
-			}))
-
-			// =================== Feature ===================
-			// Dynamic feature page
-			.state('page', $.extend({url: "/:feature/:page"}, _featureBase))
-			.state('pageFilter', $.extend({url: "/:feature/:page/:filter"}, _featureBase))
-		;
-
-		// Animation
-		$animateProvider.classNameFilter(/^((?!(fa-spin)).)*$/);
-		$animateProvider.classNameFilter(/^((?!(tab-pane)).)*$/);
-	});
-
-	eagleApp.filter('parseJSON', function () {
-		return function (input, defaultVal) {
-			return common.parseJSON(input, defaultVal);
-		};
-	});
-
-	eagleApp.filter('split', function () {
-		return function (input, regex) {
-			return input.split(regex);
-		};
-	});
-
-	eagleApp.filter('reverse', function () {
-		return function (items) {
-			return items.slice().reverse();
-		};
-	});
-
-	// ======================================================================================
-	// =                                   Main Controller                                  =
-	// ======================================================================================
-	eagleApp.controller('MainCtrl', function ($scope, $wrapState, $http, $injector, ServiceError, PageConfig, FeaturePageConfig, Site, Authorization, Entities, nvd3, Application, Feature, UI) {
-		window.serviceError = $scope.ServiceError = ServiceError;
-		window.site = $scope.Site = Site;
-		window.auth = $scope.Auth = Authorization;
-		window.entities = $scope.Entities = Entities;
-		window.application = $scope.Application = Application;
-		window.pageConfig = $scope.PageConfig = PageConfig;
-		window.featurePageConfig = $scope.FeaturePageConfig = FeaturePageConfig;
-		window.feature = $scope.Feature = Feature;
-		window.ui = $scope.UI = UI;
-		window.nvd3 = nvd3;
-		$scope.app = app;
-		$scope.common = common;
-
-		Object.defineProperty(window, "scope",{
-			get: function() {
-				return angular.element("[ui-view]").scope();
-			}
-		});
-
-		// Clean up
-		$scope.$on('$stateChangeStart', function (event, next, nextParam, current, currentParam) {
-			console.log("[Switch] current ->", current, currentParam);
-			console.log("[Switch] next ->", next, nextParam);
-			// Page initialization
-			PageConfig.reset();
-
-			// Dynamic navigation list
-			if(next.pageConfig) {
-				$scope.PageConfig.navConfig = $injector.get(next.pageConfig);
-			} else {
-				$scope.PageConfig.navConfig = {};
-			}
-
-			// Authorization
-			// > Login check
-			if (!common.getValueByPath(next, "access.skipCheck", false)) {
-				if (!Authorization.isLogin) {
-					console.log("[Authorization] Need access. Redirect...");
-					$wrapState.go("login");
-				}
-			}
-
-			// > Role control
-			/*var _roles = common.getValueByPath(next, "access.roles", []);
-			if (_roles.length && Authorization.userProfile.roles) {
-				var _roleMatch = false;
-				$.each(_roles, function (i, roleName) {
-					if (Authorization.isRole(roleName)) {
-						_roleMatch = true;
-						return false;
-					}
-				});
-
-				if (!_roleMatch) {
-					$wrapState.path("/dam");
-				}
-			}*/
-		});
-
-		$scope.$on('$stateChangeError', function (event, next, nextParam, current, currentParam, error) {
-			console.error("[Switch] Error", arguments);
-		});
-
-		// Get side bar navigation item class
-		$scope.getNavClass = function (page) {
-			var path = page.url.replace(/^#/, '');
-
-			if ($wrapState.path() === path) {
-				PageConfig.pageTitle = PageConfig.pageTitle || page.title;
-				return "active";
-			} else {
-				return "";
-			}
-		};
-
-		// Get side bar navigation item class visible
-		$scope.getNavVisible = function (page) {
-			if (!page.roles) return true;
-
-			for (var i = 0; i < page.roles.length; i += 1) {
-				var roleName = page.roles[i];
-				if (Authorization.isRole(roleName)) {
-					return true;
-				}
-			}
-
-			return false;
-		};
-
-		// Authorization
-		$scope.logout = function () {
-			console.log("[Authorization] Logout. Redirect...");
-			Authorization.logout();
-			$wrapState.go("login");
-		};
-	});
-})();
\ No newline at end of file