Repository: kylin
Updated Branches:
  refs/heads/master 34cbd1813 -> a41a7e7d3


KYLIN-2999 One click migrate cube in web


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

Branch: refs/heads/master
Commit: a41a7e7d3a97197a16360ab41e94d9ee5c77ebc6
Parents: 34cbd18
Author: kangkaisen <kangkai...@meituan.com>
Authored: Tue Dec 5 20:37:08 2017 +0800
Committer: kangkaisen <kangkai...@meituan.com>
Committed: Fri Jan 26 17:28:54 2018 +0800

----------------------------------------------------------------------
 .../apache/kylin/common/KylinConfigBase.java    | 25 +++++++++++++
 .../kylin/rest/controller/CubeController.java   |  7 ++++
 .../apache/kylin/rest/service/CubeService.java  | 39 ++++++++++++++++++++
 webapp/app/js/controllers/cubes.js              | 33 ++++++++++++++++-
 webapp/app/js/services/cubes.js                 |  3 +-
 webapp/app/js/services/kylinProperties.js       | 14 ++++++-
 webapp/app/partials/cubes/cubes.html            |  1 +
 7 files changed, 117 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/kylin/blob/a41a7e7d/core-common/src/main/java/org/apache/kylin/common/KylinConfigBase.java
----------------------------------------------------------------------
diff --git 
a/core-common/src/main/java/org/apache/kylin/common/KylinConfigBase.java 
b/core-common/src/main/java/org/apache/kylin/common/KylinConfigBase.java
index cfe6fe2..4c8a3f8 100644
--- a/core-common/src/main/java/org/apache/kylin/common/KylinConfigBase.java
+++ b/core-common/src/main/java/org/apache/kylin/common/KylinConfigBase.java
@@ -1572,4 +1572,29 @@ abstract public class KylinConfigBase implements 
Serializable {
         return getOptional("kylin.metrics.subject-query-rpc", 
"METRICS_QUERY_RPC") + "_"
                 + getKylinMetricsSubjectSuffix();
     }
+
+    // 
============================================================================
+    // tool
+    // 
============================================================================
+    public boolean isAllowAutoMigrateCube() {
+        return 
Boolean.parseBoolean(getOptional("kylin.tool.auto-migrate-cube.enabled", 
"false"));
+    }
+
+    public boolean isAutoMigrateCubeCopyAcl() {
+        return 
Boolean.parseBoolean(getOptional("kylin.tool.auto-migrate-cube.copy-acl", 
"true"));
+    }
+
+    public boolean isAutoMigrateCubePurge() {
+        return 
Boolean.parseBoolean(getOptional("kylin.tool.auto-migrate-cube.purge-src-cube", 
"true"));
+    }
+
+    public String getAutoMigrateCubeSrcConfig() {
+        return getOptional("kylin.tool.auto-migrate-cube.src-config", "");
+    }
+
+    public String getAutoMigrateCubeDestConfig() {
+        return getOptional("kylin.tool.auto-migrate-cube.dest-config", "");
+    }
+
+
 }

http://git-wip-us.apache.org/repos/asf/kylin/blob/a41a7e7d/server-base/src/main/java/org/apache/kylin/rest/controller/CubeController.java
----------------------------------------------------------------------
diff --git 
a/server-base/src/main/java/org/apache/kylin/rest/controller/CubeController.java
 
b/server-base/src/main/java/org/apache/kylin/rest/controller/CubeController.java
index f6c2abf..89c11a8 100644
--- 
a/server-base/src/main/java/org/apache/kylin/rest/controller/CubeController.java
+++ 
b/server-base/src/main/java/org/apache/kylin/rest/controller/CubeController.java
@@ -1022,6 +1022,13 @@ public class CubeController extends BasicController {
         }
     }
 
+    @RequestMapping(value = "/{cube}/{project}/migrate", method = { 
RequestMethod.POST })
+    @ResponseBody
+    public void migrateCube(@PathVariable String cube, @PathVariable String 
project) {
+        CubeInstance cubeInstance = cubeService.getCubeManager().getCube(cube);
+        cubeService.migrateCube(cubeInstance, project);
+    }
+
     public void setCubeService(CubeService cubeService) {
         this.cubeService = cubeService;
     }

http://git-wip-us.apache.org/repos/asf/kylin/blob/a41a7e7d/server-base/src/main/java/org/apache/kylin/rest/service/CubeService.java
----------------------------------------------------------------------
diff --git 
a/server-base/src/main/java/org/apache/kylin/rest/service/CubeService.java 
b/server-base/src/main/java/org/apache/kylin/rest/service/CubeService.java
index a81d189..154354d 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/service/CubeService.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/service/CubeService.java
@@ -30,6 +30,7 @@ import java.util.Set;
 import org.apache.commons.lang.StringUtils;
 import org.apache.kylin.common.KylinConfig;
 import org.apache.kylin.common.persistence.RootPersistentEntity;
+import org.apache.kylin.common.util.CliCommandExecutor;
 import org.apache.kylin.cube.CubeInstance;
 import org.apache.kylin.cube.CubeManager;
 import org.apache.kylin.cube.CubeSegment;
@@ -41,6 +42,7 @@ import org.apache.kylin.cube.model.CubeDesc;
 import org.apache.kylin.engine.EngineFactory;
 import org.apache.kylin.engine.mr.CubingJob;
 import org.apache.kylin.engine.mr.common.CuboidRecommenderUtil;
+import org.apache.kylin.job.common.PatternedLogger;
 import org.apache.kylin.job.exception.JobException;
 import org.apache.kylin.job.execution.DefaultChainedExecutable;
 import org.apache.kylin.job.execution.ExecutableState;
@@ -60,6 +62,7 @@ import org.apache.kylin.metadata.realization.RealizationType;
 import org.apache.kylin.rest.constant.Constant;
 import org.apache.kylin.rest.exception.BadRequestException;
 import org.apache.kylin.rest.exception.ForbiddenException;
+import org.apache.kylin.rest.exception.InternalErrorException;
 import org.apache.kylin.rest.msg.Message;
 import org.apache.kylin.rest.msg.MsgPicker;
 import org.apache.kylin.rest.request.MetricsRequest;
@@ -844,4 +847,40 @@ public class CubeService extends BasicService implements 
InitializingBean {
             Map<Long, Map<Long, Long>> rollingUpCountSourceMap) throws 
IOException {
         return CuboidRecommenderUtil.getRecommendCuboidList(cube, 
hitFrequencyMap, rollingUpCountSourceMap);
     }
+
+    @PreAuthorize(Constant.ACCESS_HAS_ROLE_ADMIN + " or hasPermission(#cube, 
'ADMINISTRATION') or hasPermission(#cube, 'MANAGEMENT')")
+    public void migrateCube(CubeInstance cube, String projectName) {
+        KylinConfig config = cube.getConfig();
+        try {
+            if (!config.isAllowAutoMigrateCube()) {
+                throw new InternalErrorException("This cube couldn't one click 
migrate cube, Please contact your ADMIN");
+            }
+
+            for (CubeSegment segment : cube.getSegments()) {
+                if (segment.getStatus() != SegmentStatusEnum.READY) {
+                    throw new InternalErrorException("At least one segment is 
not in READY state. Please check whether there are Running or Error jobs.");
+                }
+            }
+
+            String srcCfgUri = config.getAutoMigrateCubeSrcConfig();
+            String dstCfgUri = config.getAutoMigrateCubeDestConfig();
+
+            String stringBuilder = ("%s/bin/kylin.sh 
org.apache.kylin.tool.CubeMigrationCLI %s %s %s %s %s %s true true");
+            String cmd = String.format(stringBuilder, 
KylinConfig.getKylinHome(), srcCfgUri, dstCfgUri, cube.getName(),
+                    projectName, config.isAutoMigrateCubeCopyAcl(), 
config.isAutoMigrateCubePurge());
+
+            logger.info("cmd: " + cmd);
+
+            CliCommandExecutor exec = new CliCommandExecutor();
+            PatternedLogger patternedLogger = new PatternedLogger(logger);
+
+            try {
+                exec.execute(cmd, patternedLogger);
+            } catch (IOException e) {
+                throw new InternalErrorException("Migrating cube fails, Please 
contact your ADMIN");
+            }
+        } catch (Throwable e) {
+            throw new InternalErrorException(e.getMessage());
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/kylin/blob/a41a7e7d/webapp/app/js/controllers/cubes.js
----------------------------------------------------------------------
diff --git a/webapp/app/js/controllers/cubes.js 
b/webapp/app/js/controllers/cubes.js
index c123f1c..7094ff8 100644
--- a/webapp/app/js/controllers/cubes.js
+++ b/webapp/app/js/controllers/cubes.js
@@ -293,6 +293,35 @@ KylinApp.controller('CubesCtrl', function ($scope, $q, 
$routeParams, $location,
       });
     };
 
+    $scope.isAutoMigrateCubeEnabled = function(){
+      return kylinConfig.isAutoMigrateCubeEnabled();
+    };
+
+    $scope.migrateCube = function (cube) {
+      SweetAlert.swal({
+        title: '',
+        text: "The cube will overwrite the same cube in prod env" +
+        "\nMigrating cube will elapse a couple of minutes." +
+        "\nPlease wait.",
+        type: '',
+        showCancelButton: true,
+        confirmButtonColor: '#DD6B55',
+        confirmButtonText: "Yes",
+        closeOnConfirm: true
+      }, function(isConfirm) {
+        if(isConfirm){
+          loadingRequest.show();
+          CubeService.autoMigrate({cubeId: cube.name, propName: 
$scope.projectModel.selectedProject}, {}, function (result) {
+            loadingRequest.hide();
+            SweetAlert.swal('Success!', cube.name + ' migrate successfully!', 
'success');
+          },function(e){
+            loadingRequest.hide();
+            SweetAlert.swal('Migrate failed!', "Please contact your ADMIN.", 
'error');
+          });
+        }
+      });
+    };
+
     $scope.startJobSubmit = function (cube) {
 
       $scope.loadDetail(cube).then(function () {
@@ -464,8 +493,6 @@ KylinApp.controller('CubesCtrl', function ($scope, $q, 
$routeParams, $location,
         });
       });
     }
-
-
     $scope.cubeEdit = function (cube) {
       $location.path("cubes/edit/" + cube.name);
     }
@@ -494,6 +521,8 @@ KylinApp.controller('CubesCtrl', function ($scope, $q, 
$routeParams, $location,
         });
       })
     }
+
+
   });
 
 

http://git-wip-us.apache.org/repos/asf/kylin/blob/a41a7e7d/webapp/app/js/services/cubes.js
----------------------------------------------------------------------
diff --git a/webapp/app/js/services/cubes.js b/webapp/app/js/services/cubes.js
index 150d932..30c2a3f 100644
--- a/webapp/app/js/services/cubes.js
+++ b/webapp/app/js/services/cubes.js
@@ -77,6 +77,7 @@ KylinApp.factory('CubeService', ['$resource', function 
($resource, config) {
         }
       }
     },
-    optimize: {method: 'PUT', params: {action: 'optimize'}, isArray: false}
+    optimize: {method: 'PUT', params: {action: 'optimize'}, isArray: false},
+    autoMigrate: {method: 'POST', params: {action: 'migrate'}, isArray: false}
   });
 }]);

http://git-wip-us.apache.org/repos/asf/kylin/blob/a41a7e7d/webapp/app/js/services/kylinProperties.js
----------------------------------------------------------------------
diff --git a/webapp/app/js/services/kylinProperties.js 
b/webapp/app/js/services/kylinProperties.js
index dc9b94d..ec23397 100644
--- a/webapp/app/js/services/kylinProperties.js
+++ b/webapp/app/js/services/kylinProperties.js
@@ -114,7 +114,7 @@ KylinApp.service('kylinConfig', function (AdminService, 
$log) {
     }
     return true;
   }
-  
+
   this.isAdminExportAllowed = function(){
     var status = this.getProperty("kylin.web.export-allow-admin").trim();
     if(status!=='false'){
@@ -130,12 +130,13 @@ KylinApp.service('kylinConfig', function (AdminService, 
$log) {
     }
     return false;
   }
-  
+
   this.getHiddenMeasures = function() {
     var hide_measures = 
this.getProperty("kylin.web.hide-measures").replace(/\s/g,"").toUpperCase();
     return hide_measures.split(",")
   }
 
+
   this.getQueryTimeout = function () {
     var queryTimeout = parseInt(this.getProperty("kylin.web.query-timeout"));
     if (isNaN(queryTimeout)) {
@@ -147,5 +148,14 @@ KylinApp.service('kylinConfig', function (AdminService, 
$log) {
   this.isInitialized = function() {
     return angular.isString(_config);
   }
+
+  this.isAutoMigrateCubeEnabled = function(){
+    var status = 
this.getProperty("kylin.tool.auto-migrate-cube.enabled").trim();
+    if(status && status =='true'){
+      return true;
+    }
+    return false;
+  }
+
 });
 

http://git-wip-us.apache.org/repos/asf/kylin/blob/a41a7e7d/webapp/app/partials/cubes/cubes.html
----------------------------------------------------------------------
diff --git a/webapp/app/partials/cubes/cubes.html 
b/webapp/app/partials/cubes/cubes.html
index 94dc3a6..fb98fe3 100644
--- a/webapp/app/partials/cubes/cubes.html
+++ b/webapp/app/partials/cubes/cubes.html
@@ -99,6 +99,7 @@
                         <li ng-if="cube.status=='DISABLED' && 
(userService.hasRole('ROLE_ADMIN') || hasPermission('cube',cube, 
permissions.ADMINISTRATION.mask, permissions.MANAGEMENT.mask))"><a 
ng-click="enable(cube)">Enable</a></li>
                         <li ng-if="cube.status=='DISABLED' && 
(userService.hasRole('ROLE_ADMIN') || hasPermission('cube',cube, 
permissions.ADMINISTRATION.mask, permissions.MANAGEMENT.mask))"><a 
ng-click="purge(cube)">Purge</a></li>
                         <li ng-if="cube.status!='DESCBROKEN' && 
(userService.hasRole('ROLE_ADMIN') || hasPermission('cube',cube, 
permissions.ADMINISTRATION.mask, permissions.MANAGEMENT.mask))"><a 
ng-click="cloneCube(cube)">Clone</a></li>
+                        <li ng-if="cube.status=='READY' && 
isAutoMigrateCubeEnabled() && (userService.hasRole('ROLE_ADMIN') || 
hasPermission('cube',cube, permissions.ADMINISTRATION.mask, 
permissions.MANAGEMENT.mask)) "><a ng-click="migrateCube(cube)">Migrate</a></li>
 
                     </ul>
                     <ul ng-if="!(userService.hasRole('ROLE_ADMIN') || 
hasPermission('cube',cube, permissions.ADMINISTRATION.mask, 
permissions.MANAGEMENT.mask, permissions.OPERATION.mask))" 
class="dropdown-menu" role="menu">

Reply via email to