KYLIN-1128 clone cube metadata

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

Branch: refs/heads/1.x-HBase1.1.3
Commit: 25ac10a626244786a539c9c49ab85aa48f6bdab0
Parents: b0c5fd3
Author: Zhong <jiazh...@lm-shc-16501192.corp.ebay.com>
Authored: Tue Nov 24 19:15:41 2015 +0800
Committer: jian <jiazh...@apache.org>
Committed: Tue Dec 8 11:03:05 2015 +0800

----------------------------------------------------------------------
 .../kylin/rest/controller/CubeController.java   | 44 ++++++++++++
 webapp/app/js/controllers/cubes.js              | 67 +++++++++++++++++
 webapp/app/js/services/cubes.js                 |  1 +
 webapp/app/less/app.less                        |  6 +-
 webapp/app/partials/cubes/cube_clone.html       | 76 ++++++++++++++++++++
 webapp/app/partials/cubes/cubes.html            |  2 +
 6 files changed, 195 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/kylin/blob/25ac10a6/server/src/main/java/org/apache/kylin/rest/controller/CubeController.java
----------------------------------------------------------------------
diff --git 
a/server/src/main/java/org/apache/kylin/rest/controller/CubeController.java 
b/server/src/main/java/org/apache/kylin/rest/controller/CubeController.java
index b94ded3..a8c28c4 100644
--- a/server/src/main/java/org/apache/kylin/rest/controller/CubeController.java
+++ b/server/src/main/java/org/apache/kylin/rest/controller/CubeController.java
@@ -256,6 +256,50 @@ public class CubeController extends BasicController {
         }
     }
 
+    @RequestMapping(value = "/{cubeName}/clone", method = { RequestMethod.PUT 
})
+    @ResponseBody
+    public CubeInstance cloneCube(@PathVariable String cubeName,@RequestBody 
CubeRequest cubeRequest) {
+        String targetCubeName = cubeRequest.getCubeName();
+        String targetModelName = cubeRequest.getModelDescData();
+        String project = cubeRequest.getProject();
+
+        CubeInstance cube = cubeService.getCubeManager().getCube(cubeName);
+        if (cube == null) {
+            throw new InternalErrorException("Cannot find cube " + cubeName);
+        }
+
+        CubeDesc cubeDesc = cube.getDescriptor();
+
+        String modelName = cubeDesc.getModelName();
+        MetadataManager metaManager = 
MetadataManager.getInstance(KylinConfig.getInstanceFromEnv());
+
+        DataModelDesc modelDesc = metaManager.getDataModelDesc(modelName);
+
+        modelDesc.setName(targetModelName);
+        modelDesc.setLastModified(0);
+        modelDesc.setUuid(UUID.randomUUID().toString());
+        try {
+            metaManager.createDataModelDesc(modelDesc);
+        } catch (IOException e) {
+            throw new InternalErrorException("failed to clone 
DataModelDesc",e);
+        }
+
+        cubeDesc.setName(targetCubeName);
+        cubeDesc.setLastModified(0);
+        cubeDesc.setUuid(UUID.randomUUID().toString());
+        cubeDesc.setModelName(targetModelName);
+        CubeInstance newCube = null;
+        try {
+            newCube = 
cubeService.createCubeAndDesc(targetCubeName,project,cubeDesc);
+        } catch (IOException e) {
+            throw new InternalErrorException("failed to clone 
DataModelDesc",e);
+        }
+
+        return newCube;
+
+    }
+
+
     @RequestMapping(value = "/{cubeName}/enable", method = { RequestMethod.PUT 
})
     @ResponseBody
     public CubeInstance enableCube(@PathVariable String cubeName) {

http://git-wip-us.apache.org/repos/asf/kylin/blob/25ac10a6/webapp/app/js/controllers/cubes.js
----------------------------------------------------------------------
diff --git a/webapp/app/js/controllers/cubes.js 
b/webapp/app/js/controllers/cubes.js
index 75bcb6d..9f538b0 100755
--- a/webapp/app/js/controllers/cubes.js
+++ b/webapp/app/js/controllers/cubes.js
@@ -354,6 +354,21 @@ KylinApp
 
     };
 
+    $scope.cloneCube = function(cube){
+      $scope.loadDetail(cube).then(function () {
+        $modal.open({
+          templateUrl: 'cubeClone.html',
+          controller: cubeCloneCtrl,
+          windowClass:"clone-cube-window",
+          resolve: {
+            cube: function () {
+              return cube;
+            }
+          }
+        });
+      });
+    }
+
     $scope.cubeEdit = function (cube) {
       $location.path("cubes/edit/" + cube.name);
     }
@@ -376,6 +391,58 @@ KylinApp
     }
   });
 
+var cubeCloneCtrl = function ($scope, $modalInstance, CubeService, 
MessageService, $location, cube, MetaModel, SweetAlert,ProjectModel, 
loadingRequest) {
+  $scope.projectModel = ProjectModel;
+
+  $scope.targetObj={
+    cubeName:cube.descriptor+"_clone",
+    modelName:cube.model.name+"_clone"
+  }
+
+  $scope.cancel = function () {
+    $modalInstance.dismiss('cancel');
+  };
+
+  $scope.cloneCube = function(){
+
+    $scope.cubeRequest = {
+      cubeName:$scope.targetObj.cubeName,
+      modelDescData:$scope.targetObj.modelName,
+      project:$scope.projectModel.selectedProject
+    }
+
+    SweetAlert.swal({
+      title: '',
+      text: 'Are you sure to clone the cube? ',
+      type: '',
+      showCancelButton: true,
+      confirmButtonColor: '#DD6B55',
+      confirmButtonText: "Yes",
+      closeOnConfirm: true
+    }, function (isConfirm) {
+      if (isConfirm) {
+
+        loadingRequest.show();
+        CubeService.clone({cubeId: cube.name}, $scope.cubeRequest, function 
(result) {
+          loadingRequest.hide();
+          SweetAlert.swal('Success!', 'Clone cube successfully', 'success');
+          location.reload();
+        }, 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');
+          }
+        });
+      }
+    });
+  }
+
+}
+
 var jobSubmitCtrl = function ($scope, $modalInstance, CubeService, 
MessageService, $location, cube, MetaModel, buildType, SweetAlert, 
loadingRequest) {
   $scope.cube = cube;
   $scope.metaModel = {

http://git-wip-us.apache.org/repos/asf/kylin/blob/25ac10a6/webapp/app/js/services/cubes.js
----------------------------------------------------------------------
diff --git a/webapp/app/js/services/cubes.js b/webapp/app/js/services/cubes.js
index 3dfd2c5..a18736f 100644
--- a/webapp/app/js/services/cubes.js
+++ b/webapp/app/js/services/cubes.js
@@ -28,6 +28,7 @@ KylinApp.factory('CubeService', ['$resource', function 
($resource, config) {
     disable: {method: 'PUT', params: {action: 'disable'}, isArray: false},
     enable: {method: 'PUT', params: {action: 'enable'}, isArray: false},
     purge: {method: 'PUT', params: {action: 'purge'}, isArray: false},
+    clone: {method: 'PUT', params: {action: 'clone'}, isArray: false},
     drop: {method: 'DELETE', params: {}, isArray: false},
     save: {method: 'POST', params: {}, isArray: false},
     update: {method: 'PUT', params: {}, isArray: false},

http://git-wip-us.apache.org/repos/asf/kylin/blob/25ac10a6/webapp/app/less/app.less
----------------------------------------------------------------------
diff --git a/webapp/app/less/app.less b/webapp/app/less/app.less
index 4edf83c..6243f6f 100644
--- a/webapp/app/less/app.less
+++ b/webapp/app/less/app.less
@@ -312,6 +312,10 @@ body .modal-dialog {
   margin-right:auto;
 }
 
+.clone-cube-window .modal-dialog {
+  width: 600px; /* desired relative width */
+}
+
 pre {
   width: inherit;
   height: 350px;
@@ -621,4 +625,4 @@ ul.messenger .messenger-message-inner ,.ngCellText{
 .text-muted {
   color: #777;
 }
-.tick line {display: none;}
\ No newline at end of file
+.tick line {display: none;}

http://git-wip-us.apache.org/repos/asf/kylin/blob/25ac10a6/webapp/app/partials/cubes/cube_clone.html
----------------------------------------------------------------------
diff --git a/webapp/app/partials/cubes/cube_clone.html 
b/webapp/app/partials/cubes/cube_clone.html
new file mode 100644
index 0000000..a20555b
--- /dev/null
+++ b/webapp/app/partials/cubes/cube_clone.html
@@ -0,0 +1,76 @@
+<!--
+* 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.
+-->
+
+<script type="text/ng-template" id="cubeClone.html">
+  <div class="modal-header">
+    <h4 tooltip="submit">CUBE CLONE</h4>
+  </div>
+  <div class="modal-body" style="background-color: white">
+
+    <div class="row">
+      <div class="col-md-2"></div>
+      <div class="col-md-8">
+        <div class="row">
+          <div class="form-group">
+            <b>Target Project is:</b>
+            <br/>
+            <select ng-required="projectModel.projects.length" chosen 
ng-model="projectModel.selectedProject"
+                    ng-init="newAccess.permission=permissions.READ.value;"
+                    ng-options="project as project for project in 
projectModel.projects "
+                    style="width: 100% !important;"
+                    data-placeholder="select a project"
+                    class="chosen-select">
+              <option value=""></option>
+            </select>
+          </div>
+        </div>
+      </div>
+      <div class="col-md-2"></div>
+    </div>
+    <div class="row">
+      <div class="col-md-2"></div>
+      <div class="col-md-8">
+        <div class="row">
+          <div class="form-group">
+            <b>New Cube Name:</b>
+            <br/>
+            <input type="text" class="form-control" 
ng-model="targetObj.cubeName"/>
+          </div>
+        </div>
+      </div>
+      <div class="col-md-2"></div>
+    </div>
+    <div class="row">
+      <div class="col-md-2"></div>
+      <div class="col-md-8">
+        <div class="row">
+          <div class="form-group">
+            <b>New Model Name:</b>
+            <br/>
+            <input type="text" class="form-control" 
ng-model="targetObj.modelName"/>
+          </div>
+        </div>
+      </div>
+      <div class="col-md-2"></div>
+    </div>
+  </div>
+  <div class="modal-footer">
+    <button class="btn btn-success" ng-click="cloneCube()">Submit</button>
+    <button class="btn btn-primary" ng-click="cancel()">Close</button>
+  </div>
+</script>

http://git-wip-us.apache.org/repos/asf/kylin/blob/25ac10a6/webapp/app/partials/cubes/cubes.html
----------------------------------------------------------------------
diff --git a/webapp/app/partials/cubes/cubes.html 
b/webapp/app/partials/cubes/cubes.html
index 618dbce..74fba5c 100644
--- a/webapp/app/partials/cubes/cubes.html
+++ b/webapp/app/partials/cubes/cubes.html
@@ -121,6 +121,7 @@
                         <li ng-if="cube.status!='DISABLED'"><a 
ng-click="disable(cube)">Disable</a></li>
                         <li ng-if="cube.status=='DISABLED'"><a 
ng-click="enable(cube)">Enable</a></li>
                         <li ng-if="cube.status=='DISABLED'"><a 
ng-click="purge(cube)">Purge</a></li>
+                        <li><a ng-click="cloneCube(cube)">Clone</a></li>
 
                     </ul>
                 </div>
@@ -157,6 +158,7 @@
     <strong>Storage: {{getTotalSize(cubeList.cubes)}}</strong>
 </div>
 
+<div ng-include="'partials/cubes/cube_clone.html'"></div>
 <div ng-include="'partials/jobs/job_submit.html'"></div>
 <div ng-include="'partials/jobs/job_refresh.html'"></div>
 <div ng-include="'partials/jobs/job_merge.html'"></div>

Reply via email to