Repository: kylin Updated Branches: refs/heads/master f50c0c873 -> c72e23202
KYLIN-2287 Speed up model and cube list load in Web Signed-off-by: zhongjian <jiat...@163.com> Project: http://git-wip-us.apache.org/repos/asf/kylin/repo Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/64a0a594 Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/64a0a594 Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/64a0a594 Branch: refs/heads/master Commit: 64a0a5943c034ea6f9cdc6d179d8be9da64fe5ac Parents: f50c0c8 Author: kangkaisen <kangkai...@live.com> Authored: Wed Dec 14 20:08:14 2016 +0800 Committer: zhongjian <jiat...@163.com> Committed: Tue Dec 20 15:12:54 2016 +0800 ---------------------------------------------------------------------- webapp/app/js/controllers/cubeSchema.js | 25 +- webapp/app/js/controllers/cubes.js | 318 ++++++++++------------- webapp/app/js/controllers/models.js | 54 ++-- webapp/app/js/model/cubeListModel.js | 4 - webapp/app/js/model/modelsManager.js | 49 +--- webapp/app/partials/cubes/cubes.html | 12 +- webapp/app/partials/models/models_tree.html | 16 +- 7 files changed, 215 insertions(+), 263 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/kylin/blob/64a0a594/webapp/app/js/controllers/cubeSchema.js ---------------------------------------------------------------------- diff --git a/webapp/app/js/controllers/cubeSchema.js b/webapp/app/js/controllers/cubeSchema.js index 357b6af..af8ee7c 100755 --- a/webapp/app/js/controllers/cubeSchema.js +++ b/webapp/app/js/controllers/cubeSchema.js @@ -45,18 +45,6 @@ KylinApp.controller('CubeSchemaCtrl', function ($scope, QueryService, UserServic $scope.state = {mode: "view"}; } - var queryParam = {offset: 0, limit: 65535}; - - CubeService.list(queryParam, function (all_cubes) { - if($scope.allCubes.length > 0){ - $scope.allCubes.splice(0,$scope.allCubes.length); - } - - for (var i = 0; i < all_cubes.length; i++) { - $scope.allCubes.push(all_cubes[i].name.toUpperCase()); - } - }); - $scope.$watch('cubeMetaFrame', function (newValue, oldValue) { if(!newValue){ return; @@ -198,6 +186,19 @@ KylinApp.controller('CubeSchemaCtrl', function ($scope, QueryService, UserServic }; $scope.check_cube_info = function(){ + + var queryParam = {offset: 0, limit: 65535}; + + CubeService.list(queryParam, function (all_cubes) { + if($scope.allCubes.length > 0){ + $scope.allCubes.splice(0,$scope.allCubes.length); + } + + for (var i = 0; i < all_cubes.length; i++) { + $scope.allCubes.push(all_cubes[i].name.toUpperCase()); + } + }); + if(($scope.state.mode === "edit") &&$scope.cubeMode=="addNewCube"&&($scope.allCubes.indexOf($scope.cubeMetaFrame.name.toUpperCase()) >= 0)){ SweetAlert.swal('Oops...', "The cube named [" + $scope.cubeMetaFrame.name.toUpperCase() + "] already exists", 'warning'); return false; http://git-wip-us.apache.org/repos/asf/kylin/blob/64a0a594/webapp/app/js/controllers/cubes.js ---------------------------------------------------------------------- diff --git a/webapp/app/js/controllers/cubes.js b/webapp/app/js/controllers/cubes.js index b672d3f..cbdbb7d 100644 --- a/webapp/app/js/controllers/cubes.js +++ b/webapp/app/js/controllers/cubes.js @@ -79,43 +79,6 @@ KylinApp.controller('CubesCtrl', function ($scope, $q, $routeParams, $location, return CubeList.list(queryParam).then(function (resp) { angular.forEach($scope.cubeList.cubes,function(cube,index){ - cube.streaming = false; - CubeDescService.query({cube_name: cube.name}, {}, function (detail) { - if (detail.length > 0 && detail[0].hasOwnProperty("name")) { - cube.detail = detail[0]; - ModelService.list({projectName:$scope.projectModel.selectedProject,modelName:cube.detail.model_name}, function (_models) { - if(_models && _models.length){ - for(var i=0;i<=_models.length;i++){ - if(_models[i].name == cube.detail.model_name){ - cube.model = _models[i]; - var factTable = cube.model.fact_table; - TableService.get({tableName:factTable},function(table){ - if(table && table.source_type == 1){ - cube.streaming = true; - } - }) - break; - } - } - } - - }) - //cube.model = modelsManager.getModel(cube.detail.model_name); - - defer.resolve(cube.detail); - - } else { - SweetAlert.swal('Oops...', "No cube detail info loaded.", 'error'); - } - }, function (e) { - if (e.data && e.data.exception) { - var message = e.data.exception; - var msg = !!(message) ? message : 'Failed to take action.'; - SweetAlert.swal('Oops...', msg, 'error'); - } else { - SweetAlert.swal('Oops...', "Failed to take action.", 'error'); - } - }); }) $scope.loading = false; @@ -331,140 +294,139 @@ KylinApp.controller('CubesCtrl', function ($scope, $q, $routeParams, $location, }; $scope.startJobSubmit = function (cube) { - $scope.loadDetail(cube); - // for streaming cube build tip - if(cube.streaming){ - - SweetAlert.swal({ - title: '', - text: "Are you sure to start the build?", - type: '', - showCancelButton: true, - confirmButtonColor: '#DD6B55', - confirmButtonText: "Yes", - closeOnConfirm: true - }, function(isConfirm) { - if(isConfirm){ - loadingRequest.show(); - CubeService.rebuildStreamingCube( - { - cubeId: cube.name - }, - { - sourceOffsetStart:0, - sourceOffsetEnd:'9223372036854775807', - buildType:'BUILD' - }, function (job) { - loadingRequest.hide(); - SweetAlert.swal('Success!', 'Rebuild job was submitted successfully', 'success'); - },function(e){ - - loadingRequest.hide(); - if(e.data&& e.data.exception){ - var message =e.data.exception; - var msg = !!(message) ? message : 'Failed to take action.'; - SweetAlert.swal('Oops...', msg, 'error'); - }else{ - SweetAlert.swal('Oops...', "Failed to take action.", 'error'); + + $scope.loadDetail(cube).then(function () { + $scope.metaModel={ + model:cube.model + }; + + TableService.get({tableName:$scope.metaModel.model.fact_table},function(table){ + if(table && table.source_type == 1){ + cube.streaming = true; + } + + // for streaming cube build tip + if(cube.streaming){ + $modal.open({ + templateUrl: 'streamingBuild.html', + controller: streamingBuildCtrl, + resolve: { + cube: function () { + return cube; + }, + metaModel:function(){ + return $scope.metaModel; + }, + buildType: function () { + return 'BUILD'; + }, + scope:function(){ + + return $scope; } + } }); + return; } - }) - return; - } - $scope.metaModel={ - model:modelsManager.getModelByCube(cube.name) - } - if ($scope.metaModel.model.name) { - if ($scope.metaModel.model.partition_desc.partition_date_column) { - - $modal.open({ - templateUrl: 'jobSubmit.html', - controller: jobSubmitCtrl, - resolve: { - cube: function () { - return cube; - }, - metaModel:function(){ - return $scope.metaModel; - }, - buildType: function () { - return 'BUILD'; - }, - scope:function(){ - - return $scope; - } + //for batch cube build tip + if ($scope.metaModel.model.name) { + + //for partition cube build tip + if ($scope.metaModel.model.partition_desc.partition_date_column) { + $modal.open({ + templateUrl: 'jobSubmit.html', + controller: jobSubmitCtrl, + resolve: { + cube: function () { + return cube; + }, + metaModel:function(){ + return $scope.metaModel; + }, + buildType: function () { + return 'BUILD'; + }, + scope:function(){ + return $scope; + } + } + }); } - }); - } - else { - SweetAlert.swal({ - title: '', - text: "Are you sure to start the build ?", - type: '', - showCancelButton: true, - confirmButtonColor: '#DD6B55', - confirmButtonText: "Yes", - closeOnConfirm: true - }, function(isConfirm) { - if(isConfirm){ + //for not partition cube build tip + else { + SweetAlert.swal({ + title: '', + text: "Are you sure to start the build ?", + type: '', + showCancelButton: true, + confirmButtonColor: '#DD6B55', + confirmButtonText: "Yes", + closeOnConfirm: true + }, function(isConfirm) { + if(isConfirm){ + + loadingRequest.show(); + CubeService.rebuildCube( + { + cubeId: cube.name + }, + { + buildType: 'BUILD', + startTime: 0, + endTime: 0 + }, function (job) { + + loadingRequest.hide(); + SweetAlert.swal('Success!', 'Rebuild job was submitted successfully', 'success'); + },function(e){ + + loadingRequest.hide(); + if(e.data&& e.data.exception){ + var message =e.data.exception; + var msg = !!(message) ? message : 'Failed to take action.'; + SweetAlert.swal('Oops...', msg, 'error'); + }else{ + SweetAlert.swal('Oops...', "Failed to take action.", 'error'); + } + }); + } - loadingRequest.show(); - CubeService.rebuildCube( - { - cubeId: cube.name - }, - { - buildType: 'BUILD', - startTime: 0, - endTime: 0 - }, function (job) { - - loadingRequest.hide(); - SweetAlert.swal('Success!', 'Rebuild job was submitted successfully', 'success'); - },function(e){ - - loadingRequest.hide(); - if(e.data&& e.data.exception){ - var message =e.data.exception; - var msg = !!(message) ? message : 'Failed to take action.'; - SweetAlert.swal('Oops...', msg, 'error'); - }else{ - SweetAlert.swal('Oops...', "Failed to take action.", 'error'); - } - }); + }); } + } + }) + }) - }); - } - } }; $scope.startRefresh = function (cube) { - $scope.metaModel={ - model:modelsManager.getModelByCube(cube.name) - }; - $modal.open({ - templateUrl: 'jobRefresh.html', - controller: jobSubmitCtrl, - resolve: { - cube: function () { - return cube; - }, - metaModel:function(){ - return $scope.metaModel; - }, - buildType: function () { - return 'REFRESH'; - }, - scope:function(){ - return $scope; + + $scope.loadDetail(cube).then(function () { + $scope.metaModel={ + model:cube.model + }; + $modal.open({ + templateUrl: 'jobRefresh.html', + controller: jobSubmitCtrl, + resolve: { + cube: function () { + return cube; + }, + metaModel:function(){ + return $scope.metaModel; + }, + buildType: function () { + return 'REFRESH'; + }, + scope:function(){ + return $scope; + } } + }); } - }); + ) }; @@ -493,27 +455,29 @@ KylinApp.controller('CubesCtrl', function ($scope, $q, $routeParams, $location, $location.path("cubes/edit/" + cube.name); } $scope.startMerge = function (cube) { - $scope.metaModel={ - model:modelsManager.getModelByCube(cube.name) - }; - $modal.open({ - templateUrl: 'jobMerge.html', - controller: jobSubmitCtrl, - resolve: { - cube: function () { - return cube; - }, - metaModel:function(){ - return $scope.metaModel; - }, - buildType: function () { - return 'MERGE'; - }, - scope:function(){ - return $scope; + $scope.loadDetail(cube).then(function () { + $scope.metaModel={ + model:cube.model + }; + $modal.open({ + templateUrl: 'jobMerge.html', + controller: jobSubmitCtrl, + resolve: { + cube: function () { + return cube; + }, + metaModel:function(){ + return $scope.metaModel; + }, + buildType: function () { + return 'MERGE'; + }, + scope:function(){ + return $scope; + } } - } - }); + }); + }) } }); http://git-wip-us.apache.org/repos/asf/kylin/blob/64a0a594/webapp/app/js/controllers/models.js ---------------------------------------------------------------------- diff --git a/webapp/app/js/controllers/models.js b/webapp/app/js/controllers/models.js index fb2c6d1..e3ee038 100644 --- a/webapp/app/js/controllers/models.js +++ b/webapp/app/js/controllers/models.js @@ -18,7 +18,7 @@ 'use strict'; -KylinApp.controller('ModelsCtrl', function ($scope, $q, $routeParams, $location, $window, $modal, MessageService, CubeDescService, CubeService, JobService, UserService, ProjectService, SweetAlert, loadingRequest, $log, modelConfig, ProjectModel, ModelService, MetaModel, modelsManager, cubesManager, TableModel, $animate) { +KylinApp.controller('ModelsCtrl', function ($scope, $q, $routeParams, $location, $window, $modal, MessageService, CubeDescService, CubeService, JobService, UserService, ProjectService, SweetAlert, loadingRequest, $log, modelConfig, ProjectModel, ModelService, MetaModel, modelsManager, cubesManager, TableModel, AccessService) { //tree data @@ -131,21 +131,28 @@ KylinApp.controller('ModelsCtrl', function ($scope, $q, $routeParams, $location, var cubename = []; var modelstate=false; var i=0; - if (model.cubes.length != 0) { - angular.forEach(model.cubes,function(cube){ - if (cube.status=="READY"){ - modelstate=true; - cubename[i] =cube.name; - i++; - } - }) - } - if(modelstate==false){ - $location.path("/models/edit/"+model.name); - } - else{ - SweetAlert.swal('Sorry','This model is still used by '+ cubename.join(',')); - } + + CubeService.list({modelName:model.name}, function (_cubes) { + model.cubes = _cubes; + + if (model.cubes.length != 0) { + angular.forEach(model.cubes,function(cube){ + if (cube.status=="READY"){ + modelstate=true; + cubename[i] =cube.name; + i++; + } + }) + } + + if(modelstate==false){ + $location.path("/models/edit/"+model.name); + } + else{ + SweetAlert.swal('Sorry','This model is still used by '+ cubename.join(',')); + } + }) + }; $scope.cloneModel = function(model){ @@ -176,6 +183,21 @@ KylinApp.controller('ModelsCtrl', function ($scope, $q, $routeParams, $location, }); }; + $scope.listModelAccess = function (model) { + if(model.uuid){ + AccessService.list({type: "DataModelDesc", uuid: model.uuid}, function (accessEntities) { + model.accessEntities = accessEntities; + try { + if (!model.owner) { + model.owner = accessEntities[0].sid.principal; + } + } catch (error) { + $log.error("No acl info."); + } + }) + } + }; + var ModelDetailModalCtrl = function ($scope, $location, $modalInstance, scope) { modelsManager.selectedModel.visiblePage='metadata'; $scope.cancel = function () { http://git-wip-us.apache.org/repos/asf/kylin/blob/64a0a594/webapp/app/js/model/cubeListModel.js ---------------------------------------------------------------------- diff --git a/webapp/app/js/model/cubeListModel.js b/webapp/app/js/model/cubeListModel.js index 13c924c..39853c0 100755 --- a/webapp/app/js/model/cubeListModel.js +++ b/webapp/app/js/model/cubeListModel.js @@ -25,10 +25,6 @@ KylinApp.service('CubeList',function(CubeService,$q,AccessService){ var defer = $q.defer(); CubeService.list(queryParam, function (_cubes) { angular.forEach(_cubes, function (cube, index) { - AccessService.list({type: "CubeInstance", uuid: cube.uuid}, function (accessEntities) { - cube.accessEntities = accessEntities; - }); - if(cube.name){ if (cube.segments && cube.segments.length > 0) { for(var i= cube.segments.length-1;i>=0;i--){ http://git-wip-us.apache.org/repos/asf/kylin/blob/64a0a594/webapp/app/js/model/modelsManager.js ---------------------------------------------------------------------- diff --git a/webapp/app/js/model/modelsManager.js b/webapp/app/js/model/modelsManager.js index c104405..faa8d39 100644 --- a/webapp/app/js/model/modelsManager.js +++ b/webapp/app/js/model/modelsManager.js @@ -25,56 +25,22 @@ KylinApp.service('modelsManager',function(ModelService,CubeService,$q,AccessServ this.loading = false; this.selectedModel={}; - this.cubeModel={}; - this.cubeSelected = false; - - //list models and complemete cube,access info + //list models this.list = function(queryParam){ _this.loading = true; var defer = $q.defer(); - var cubeDetail = []; - var modelPermission = []; ModelService.list(queryParam, function (_models) { - //_this.removeAll(); angular.forEach(_models, function (model, index) { - $log.info("Add model permission info"); - if(model.uuid){ - modelPermission.push( - AccessService.list({type: "DataModelDesc", uuid: model.uuid}, function (accessEntities) { - model.accessEntities = accessEntities; - try{ - if(!model.owner){ - model.owner = accessEntities[0].sid.principal; - } - } catch(error){ - $log.error("No acl info."); - } - - }).$promise - ) - } - - $log.info("Add cube info to model ,not detail info"); - cubeDetail.push( - CubeService.list({modelName:model.name}, function (_cubes) { - model.cubes = _cubes; - }).$promise - ); - _this.modelNameList.push(model.name); - - model.project = ProjectModel.getProjectByCubeModel(model.name); + model.project = ProjectModel.getProjectByCubeModel(model.name); }); - $q.all(cubeDetail,modelPermission).then( - function(result){ - _models = _.filter(_models,function(models){return models.name!=undefined}); - _this.models = _models; - _this.loading = false; - defer.resolve(_this.models); - } - ); + + _models = _.filter(_models,function(models){return models.name!=undefined}); + _this.models = _models; + _this.loading = false; + },function(){ defer.reject("Failed to load models"); }); @@ -127,5 +93,4 @@ KylinApp.service('modelsManager',function(ModelService,CubeService,$q,AccessServ return defer.promise; }; - }); http://git-wip-us.apache.org/repos/asf/kylin/blob/64a0a594/webapp/app/partials/cubes/cubes.html ---------------------------------------------------------------------- diff --git a/webapp/app/partials/cubes/cubes.html b/webapp/app/partials/cubes/cubes.html index 0187523..4be7ecd 100644 --- a/webapp/app/partials/cubes/cubes.html +++ b/webapp/app/partials/cubes/cubes.html @@ -54,7 +54,6 @@ </th> <th>Actions</th> <th ng-if="userService.hasRole('ROLE_ADMIN')">Admins</th> - <th>Streaming</th> </tr> </thead> <!--Body--> @@ -83,12 +82,12 @@ <td>{{ cube.owner}}</td> <td>{{ cube.create_time_utc | utcToConfigTimeZone}}</td> <td> - <div ng-click="$event.stopPropagation();" class="btn-group" ng-if="userService.hasRole('ROLE_ADMIN') || hasPermission(cube, permissions.ADMINISTRATION.mask, permissions.MANAGEMENT.mask, permissions.OPERATION.mask)"> + <div ng-click="$event.stopPropagation();" class="btn-group"> <button type="button" class="btn btn-default btn-xs dropdown-toggle" data-toggle="dropdown" ng-click="listAccess(cube, 'CubeInstance')"> Action <span class="ace-icon fa fa-caret-down icon-on-right"></span> </button> - <ul class="dropdown-menu" role="menu"> + <ul ng-if="userService.hasRole('ROLE_ADMIN') || hasPermission(cube, permissions.ADMINISTRATION.mask, permissions.MANAGEMENT.mask, permissions.OPERATION.mask)" class="dropdown-menu" role="menu"> <li ng-if="cube.status!='READY' && userService.hasRole('ROLE_ADMIN') "> <a ng-click="dropCube(cube)" tooltip="Drop the cube, related jobs and data permanently.">Drop</a></li> <li ng-if="(userService.hasRole('ROLE_ADMIN') || hasPermission(cube, permissions.ADMINISTRATION.mask, permissions.MANAGEMENT.mask))"> @@ -108,20 +107,17 @@ N/A </span> </td> - <td ng-if="userService.hasRole('ROLE_ADMIN')"> + <td> <div ng-click="$event.stopPropagation();" class="btn-group"> <button type="button" class="btn btn-default btn-xs dropdown-toggle" data-toggle="dropdown" ng-click="listAccess(cube, 'CubeInstance')"> Action <span class="ace-icon fa fa-caret-down icon-on-right"></span> </button> - <ul class="dropdown-menu" role="menu"> + <ul class="dropdown-menu" role="menu" ng-if="userService.hasRole('ROLE_ADMIN')"> <li ng-if="cube.status!='READY'"><a href="cubes/edit/{{cube.name}}/descriptionjson">Edit CubeDesc</a></li> <li><a href="cubes/view/{{cube.name}}/instancejson">View Cube</a></li> </ul> </div> </td> - <td> - <label class="badge" ng-class="{'label-info':cube.streaming==true}" style="cursor:pointer;">{{cube.streaming}}</label> - </td> </tr> <tr ng-show="cube.showDetail"> <td colspan="10" style="padding: 10px 30px 10px 30px;"> http://git-wip-us.apache.org/repos/asf/kylin/blob/64a0a594/webapp/app/partials/models/models_tree.html ---------------------------------------------------------------------- diff --git a/webapp/app/partials/models/models_tree.html b/webapp/app/partials/models/models_tree.html index 530139e..944d2dc 100644 --- a/webapp/app/partials/models/models_tree.html +++ b/webapp/app/partials/models/models_tree.html @@ -41,15 +41,23 @@ <div> <h3 class="text-info">Models</h3> </div> + <div style="width:100%; height:{{window}}px; overflow:auto;margin-top: 20px;" class="cube_model_trees"> <ul class="list-group models-tree"> <li class="list-group-item" ng-repeat="model in modelsManager.models"> - <div class="pull-right" showonhoverparent style="display:none;"> - <a ng-click="editModel(model)" title="Edit Model" style="cursor:pointer;margin-right: 8px;" ng-if="(userService.hasRole('ROLE_ADMIN') || hasPermission(model, permissions.ADMINISTRATION.mask, permissions.MANAGEMENT.mask, permissions.OPERATION.mask))"><span class="fa fa-pencil fa-lg fa-fw"></span></a> - <a ng-click="cloneModel(model)" title="Clone Model" style="cursor:pointer;margin-right: 8px;" ng-if="(userService.hasRole('ROLE_ADMIN') || hasPermission(model, permissions.ADMINISTRATION.mask, permissions.MANAGEMENT.mask, permissions.OPERATION.mask))"><span class="fa fa-copy fa-lg fa-fw"></span></a> - <a ng-click="dropModel(model)" title="Drop Model" style="cursor:pointer;margin-right: 8px;" ng-if="(userService.hasRole('ROLE_ADMIN') || hasPermission(model, permissions.ADMINISTRATION.mask, permissions.MANAGEMENT.mask, permissions.OPERATION.mask))"><span class="fa fa-trash-o fa-lg fa-fw"></span></a> + <div class="pull-right" showonhoverparent style="display:none;" > + <div ng-click="$event.stopPropagation();" class="btn-group"> + <button type="button" class="btn btn-default btn-xs dropdown-toggle" data-toggle="dropdown" ng-click="listModelAccess(model)"> + Action <span class="ace-icon fa fa-caret-down icon-on-right"></span> + </button> + <ul class="dropdown-menu" role="menu" ng-if="(userService.hasRole('ROLE_ADMIN') || hasPermission(model, permissions.ADMINISTRATION.mask, permissions.MANAGEMENT.mask, permissions.OPERATION.mask))"> + <li><a ng-click="editModel(model)" title="Edit Model" style="cursor:pointer;margin-right: 8px;" >Edit</a></li> + <li><a ng-click="cloneModel(model)" title="Clone Model" style="cursor:pointer;margin-right: 8px;" >Clone </a></li> + <li><a ng-click="dropModel(model)" title="Drop Model" style="cursor:pointer;margin-right: 8px;">Drop</a></li> + </ul> + </div> </div> <span class="strong"><a style="cursor: pointer;word-break:break-all;" ng-click="openModal(model)">{{model.name}}</a></span>