Repository: kylin
Updated Branches:
  refs/heads/KYLIN-1356 5f5bc29d5 -> 16dd4070a


KYLIN-1340


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

Branch: refs/heads/KYLIN-1356
Commit: c7b2adb5beaa2697cfa2521a3c817d007b15a930
Parents: 5f5bc29
Author: honma <ho...@ebay.com>
Authored: Fri Jan 22 15:31:44 2016 +0800
Committer: honma <ho...@ebay.com>
Committed: Fri Jan 22 15:31:44 2016 +0800

----------------------------------------------------------------------
 .../kylin/common/persistence/ResourceTool.java  |  11 +
 .../org/apache/kylin/cube/CubeDescManager.java  |   2 +-
 .../org/apache/kylin/cube/model/CubeDesc.java   |   4 +-
 .../org/apache/kylin/job/dao/ExecutableDao.java |   4 +-
 .../storage/hbase/util/CubeMetaExtractor.java   | 284 +++++++++++++++++++
 5 files changed, 300 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/kylin/blob/c7b2adb5/core-common/src/main/java/org/apache/kylin/common/persistence/ResourceTool.java
----------------------------------------------------------------------
diff --git 
a/core-common/src/main/java/org/apache/kylin/common/persistence/ResourceTool.java
 
b/core-common/src/main/java/org/apache/kylin/common/persistence/ResourceTool.java
index 4a23ba3..8faeadf 100644
--- 
a/core-common/src/main/java/org/apache/kylin/common/persistence/ResourceTool.java
+++ 
b/core-common/src/main/java/org/apache/kylin/common/persistence/ResourceTool.java
@@ -20,7 +20,10 @@ package org.apache.kylin.common.persistence;
 
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Callable;
 
+import com.google.common.base.Function;
 import org.apache.kylin.common.KylinConfig;
 import org.apache.kylin.common.util.StringUtil;
 
@@ -76,6 +79,14 @@ public class ResourceTool {
         System.out.println("" + result);
     }
 
+    public static void copy(KylinConfig srcConfig, KylinConfig dstConfig, 
List<String> paths) throws IOException {
+        ResourceStore src = ResourceStore.getStore(srcConfig);
+        ResourceStore dst = ResourceStore.getStore(dstConfig);
+        for (String path : paths) {
+            copyR(src, dst, path);
+        }
+    }
+
     public static void copy(KylinConfig srcConfig, KylinConfig dstConfig) 
throws IOException {
 
         ResourceStore src = ResourceStore.getStore(srcConfig);

http://git-wip-us.apache.org/repos/asf/kylin/blob/c7b2adb5/core-cube/src/main/java/org/apache/kylin/cube/CubeDescManager.java
----------------------------------------------------------------------
diff --git a/core-cube/src/main/java/org/apache/kylin/cube/CubeDescManager.java 
b/core-cube/src/main/java/org/apache/kylin/cube/CubeDescManager.java
index 53cd00f..424fd80 100644
--- a/core-cube/src/main/java/org/apache/kylin/cube/CubeDescManager.java
+++ b/core-cube/src/main/java/org/apache/kylin/cube/CubeDescManager.java
@@ -112,7 +112,7 @@ public class CubeDescManager {
     public CubeDesc reloadCubeDescLocal(String name) throws IOException {
 
         // Save Source
-        String path = CubeDesc.getCubeDescResourcePath(name);
+        String path = CubeDesc.concatResourcePath(name);
 
         // Reload the CubeDesc
         CubeDesc ndesc = loadCubeDesc(path);

http://git-wip-us.apache.org/repos/asf/kylin/blob/c7b2adb5/core-cube/src/main/java/org/apache/kylin/cube/model/CubeDesc.java
----------------------------------------------------------------------
diff --git a/core-cube/src/main/java/org/apache/kylin/cube/model/CubeDesc.java 
b/core-cube/src/main/java/org/apache/kylin/cube/model/CubeDesc.java
index bbc9f90..db05d7e 100644
--- a/core-cube/src/main/java/org/apache/kylin/cube/model/CubeDesc.java
+++ b/core-cube/src/main/java/org/apache/kylin/cube/model/CubeDesc.java
@@ -267,10 +267,10 @@ public class CubeDesc extends RootPersistentEntity {
     }
 
     public String getResourcePath() {
-        return getCubeDescResourcePath(name);
+        return concatResourcePath(name);
     }
 
-    public static String getCubeDescResourcePath(String descName) {
+    public static String concatResourcePath(String descName) {
         return ResourceStore.CUBE_DESC_RESOURCE_ROOT + "/" + descName + 
MetadataConstants.FILE_SURFIX;
     }
 

http://git-wip-us.apache.org/repos/asf/kylin/blob/c7b2adb5/core-job/src/main/java/org/apache/kylin/job/dao/ExecutableDao.java
----------------------------------------------------------------------
diff --git a/core-job/src/main/java/org/apache/kylin/job/dao/ExecutableDao.java 
b/core-job/src/main/java/org/apache/kylin/job/dao/ExecutableDao.java
index 18e36b4..d479dfe 100644
--- a/core-job/src/main/java/org/apache/kylin/job/dao/ExecutableDao.java
+++ b/core-job/src/main/java/org/apache/kylin/job/dao/ExecutableDao.java
@@ -68,11 +68,11 @@ public class ExecutableDao {
         return pathOfJob(job.getUuid());
     }
 
-    private String pathOfJob(String uuid) {
+    public static String pathOfJob(String uuid) {
         return ResourceStore.EXECUTE_RESOURCE_ROOT + "/" + uuid;
     }
 
-    private String pathOfJobOutput(String uuid) {
+    public static String pathOfJobOutput(String uuid) {
         return ResourceStore.EXECUTE_OUTPUT_RESOURCE_ROOT + "/" + uuid;
     }
 

http://git-wip-us.apache.org/repos/asf/kylin/blob/c7b2adb5/storage-hbase/src/main/java/org/apache/kylin/storage/hbase/util/CubeMetaExtractor.java
----------------------------------------------------------------------
diff --git 
a/storage-hbase/src/main/java/org/apache/kylin/storage/hbase/util/CubeMetaExtractor.java
 
b/storage-hbase/src/main/java/org/apache/kylin/storage/hbase/util/CubeMetaExtractor.java
new file mode 100644
index 0000000..680dff8
--- /dev/null
+++ 
b/storage-hbase/src/main/java/org/apache/kylin/storage/hbase/util/CubeMetaExtractor.java
@@ -0,0 +1,284 @@
+/*
+ * 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.
+ */
+
+package org.apache.kylin.storage.hbase.util;
+
+import java.io.IOException;
+import java.util.List;
+
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionBuilder;
+import org.apache.commons.cli.OptionGroup;
+import org.apache.commons.cli.Options;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.kylin.common.KylinConfig;
+import org.apache.kylin.common.persistence.ResourceTool;
+import org.apache.kylin.common.util.AbstractApplication;
+import org.apache.kylin.common.util.OptionsHelper;
+import org.apache.kylin.cube.CubeDescManager;
+import org.apache.kylin.cube.CubeInstance;
+import org.apache.kylin.cube.CubeManager;
+import org.apache.kylin.cube.CubeSegment;
+import org.apache.kylin.cube.model.CubeDesc;
+import org.apache.kylin.invertedindex.IIDescManager;
+import org.apache.kylin.invertedindex.IIInstance;
+import org.apache.kylin.invertedindex.IIManager;
+import org.apache.kylin.job.dao.ExecutableDao;
+import org.apache.kylin.job.dao.ExecutablePO;
+import org.apache.kylin.job.exception.PersistentException;
+import org.apache.kylin.metadata.MetadataManager;
+import org.apache.kylin.metadata.model.DataModelDesc;
+import org.apache.kylin.metadata.model.TableDesc;
+import org.apache.kylin.metadata.project.ProjectInstance;
+import org.apache.kylin.metadata.project.ProjectManager;
+import org.apache.kylin.metadata.project.RealizationEntry;
+import org.apache.kylin.metadata.realization.IRealization;
+import org.apache.kylin.metadata.realization.RealizationRegistry;
+import org.apache.kylin.storage.hybrid.HybridInstance;
+import org.apache.kylin.storage.hybrid.HybridManager;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.Lists;
+
+/**
+ * extract cube related info for debugging/distributing purpose
+ * TODO: deal with II case, deal with Streaming case
+ */
+public class CubeMetaExtractor extends AbstractApplication {
+
+    private static final Logger logger = 
LoggerFactory.getLogger(CubeMetaExtractor.class);
+
+    @SuppressWarnings("static-access")
+    private static final Option OPTION_CUBE = 
OptionBuilder.withArgName("cube").hasArg().isRequired(false).withDescription("Specify
 which cube to extract").create("cube");
+    @SuppressWarnings("static-access")
+    private static final Option OPTION_HYBRID = 
OptionBuilder.withArgName("hybrid").hasArg().isRequired(false).withDescription("Specify
 which hybrid to extract").create("hybrid");
+    @SuppressWarnings("static-access")
+    private static final Option OPTION_PROJECT = 
OptionBuilder.withArgName("project").hasArg().isRequired(false).withDescription("Specify
 realizations in which project to extract").create("project");
+
+    @SuppressWarnings("static-access")
+    private static final Option OPTION_INCLUDE_SEGMENTS = 
OptionBuilder.withArgName("includeSegments").hasArg().isRequired(false).withDescription("set
 this to true if want extract the segments info, related dicts, 
etc.").create("includeSegments");
+    @SuppressWarnings("static-access")
+    private static final Option OPTION_INCLUDE_JOB = 
OptionBuilder.withArgName("includeJobs").hasArg().isRequired(false).withDescription("set
 this to true if want to extract job info/outputs too").create("includeJobs");
+
+    @SuppressWarnings("static-access")
+    private static final Option OPTION_DEST = 
OptionBuilder.withArgName("destDir").hasArg().isRequired(false).withDescription("specify
 the dest dir to save the related metadata").create("destDir");
+
+    private Options options = null;
+    private KylinConfig kylinConfig;
+    private MetadataManager metadataManager;
+    private ProjectManager projectManager;
+    private HybridManager hybridManager;
+    private CubeManager cubeManager;
+    private CubeDescManager cubeDescManager;
+    private IIManager iiManager;
+    private IIDescManager iiDescManager;
+    private ExecutableDao executableDao;
+    RealizationRegistry realizationRegistry;
+
+    public CubeMetaExtractor() {
+        options = new Options();
+
+        OptionGroup realizationOrProject = new OptionGroup();
+        realizationOrProject.addOption(OPTION_CUBE);
+        realizationOrProject.addOption(OPTION_PROJECT);
+        realizationOrProject.addOption(OPTION_HYBRID);
+        realizationOrProject.setRequired(true);
+
+        options.addOptionGroup(realizationOrProject);
+        options.addOption(OPTION_INCLUDE_SEGMENTS);
+        options.addOption(OPTION_INCLUDE_JOB);
+        options.addOption(OPTION_DEST);
+
+    }
+
+    @Override
+    protected Options getOptions() {
+        return options;
+    }
+
+    @Override
+    protected void execute(OptionsHelper optionsHelper) throws Exception {
+        boolean includeSegments = 
optionsHelper.hasOption(OPTION_INCLUDE_SEGMENTS) ? 
Boolean.valueOf(optionsHelper.getOptionValue(OPTION_INCLUDE_SEGMENTS)) : true;
+        boolean includeJobs = optionsHelper.hasOption(OPTION_INCLUDE_JOB) ? 
Boolean.valueOf(optionsHelper.getOptionValue(OPTION_INCLUDE_JOB)) : true;
+        String dest = null;
+        if (optionsHelper.hasOption(OPTION_DEST)) {
+            dest = optionsHelper.getOptionValue(OPTION_DEST);
+        }
+
+        if (!includeSegments) {
+            throw new RuntimeException("Does not support skip segments for 
now");
+        }
+
+        kylinConfig = KylinConfig.getInstanceFromEnv();
+        metadataManager = MetadataManager.getInstance(kylinConfig);
+        projectManager = ProjectManager.getInstance(kylinConfig);
+        hybridManager = HybridManager.getInstance(kylinConfig);
+        cubeManager = CubeManager.getInstance(kylinConfig);
+        cubeDescManager = CubeDescManager.getInstance(kylinConfig);
+        iiManager = IIManager.getInstance(kylinConfig);
+        iiDescManager = IIDescManager.getInstance(kylinConfig);
+        executableDao = ExecutableDao.getInstance(kylinConfig);
+        realizationRegistry = RealizationRegistry.getInstance(kylinConfig);
+
+        List<String> requiredResources = Lists.newArrayList();
+        List<String> optionalResources = Lists.newArrayList();
+
+        if (optionsHelper.hasOption(OPTION_PROJECT)) {
+            ProjectInstance projectInstance = 
projectManager.getProject(optionsHelper.getOptionValue(OPTION_PROJECT));
+            if (projectInstance == null) {
+                throw new IllegalArgumentException("Project " + 
optionsHelper.getOptionValue(OPTION_PROJECT) + " does not exist");
+            }
+            addRequired(requiredResources, 
ProjectInstance.concatResourcePath(projectInstance.getName()));
+            List<RealizationEntry> realizationEntries = 
projectInstance.getRealizationEntries();
+            for (RealizationEntry realizationEntry : realizationEntries) {
+                retrieveResourcePath(getRealization(realizationEntry), 
includeSegments, includeJobs, requiredResources, optionalResources);
+            }
+        } else if (optionsHelper.hasOption(OPTION_CUBE)) {
+            String cubeName = optionsHelper.getOptionValue(OPTION_CUBE);
+            IRealization realization;
+
+            if ((realization = cubeManager.getRealization(cubeName)) != null) {
+                retrieveResourcePath(realization, includeSegments, 
includeJobs, requiredResources, optionalResources);
+            } else {
+                throw new IllegalArgumentException("No cube found with name of 
" + cubeName);
+            }
+        } else if (optionsHelper.hasOption(OPTION_HYBRID)) {
+            String hybridName = optionsHelper.getOptionValue(OPTION_HYBRID);
+            IRealization realization;
+
+            if ((realization = hybridManager.getRealization(hybridName)) != 
null) {
+                retrieveResourcePath(realization, includeSegments, 
includeJobs, requiredResources, optionalResources);
+            } else {
+                throw new IllegalArgumentException("No hybrid found with name 
of" + hybridName);
+            }
+        }
+
+        executeExtraction(requiredResources, optionalResources, dest);
+    }
+
+    private void executeExtraction(List<String> requiredPaths, List<String> 
optionalPaths, String dest) {
+        logger.info("The resource paths going to be extracted:");
+        for (String s : requiredPaths) {
+            logger.info(s + "(required)");
+        }
+        for (String s : optionalPaths) {
+            logger.info(s + "(optional)");
+        }
+
+        if (dest == null) {
+            logger.info("Dest is not set, exit directly without extracting");
+        } else {
+            try {
+                ResourceTool.copy(KylinConfig.getInstanceFromEnv(), 
KylinConfig.createInstanceFromUri(dest));
+            } catch (IOException e) {
+                throw new RuntimeException("IOException", e);
+            }
+        }
+    }
+
+    private IRealization getRealization(RealizationEntry realizationEntry) {
+        return realizationRegistry.getRealization(realizationEntry.getType(), 
realizationEntry.getRealization());
+    }
+
+    private void retrieveResourcePath(IRealization realization, boolean 
includeSegments, boolean includeJobs, List<String> requiredResources, 
List<String> optionalResources) {
+
+        logger.info("Deal with realization {} of type {}", 
realization.getName(), realization.getType());
+
+        if (realization instanceof CubeInstance) {
+            CubeInstance cube = (CubeInstance) realization;
+            String descName = cube.getDescName();
+            CubeDesc cubeDesc = cubeDescManager.getCubeDesc(descName);
+            String modelName = cubeDesc.getModelName();
+            DataModelDesc modelDesc = 
metadataManager.getDataModelDesc(modelName);
+
+            for (String tableName : modelDesc.getAllTables()) {
+                addRequired(requiredResources, 
TableDesc.concatResourcePath(tableName));
+                addOptional(optionalResources, 
TableDesc.concatExdResourcePath(tableName));
+            }
+
+            addRequired(requiredResources, 
DataModelDesc.concatResourcePath(modelDesc.getName()));
+            addRequired(requiredResources, 
CubeDesc.concatResourcePath(cubeDesc.getName()));
+
+            if (includeSegments) {
+                addRequired(requiredResources, 
CubeInstance.concatResourcePath(cube.getName()));
+                for (CubeSegment segment : cube.getSegments()) {
+                    for (String dictPat : segment.getDictionaryPaths()) {
+                        addRequired(requiredResources, dictPat);
+                    }
+                    for (String snapshotPath : segment.getSnapshotPaths()) {
+                        addRequired(requiredResources, snapshotPath);
+                    }
+                    addRequired(requiredResources, 
segment.getStatisticsResourcePath());
+
+                    if (includeJobs) {
+                        String lastJobId = segment.getLastBuildJobID();
+                        if (!StringUtils.isEmpty(lastJobId)) {
+                            logger.warn("No job exist for segment {}", 
segment);
+                        } else {
+                            try {
+                                ExecutablePO executablePO = 
executableDao.getJob(lastJobId);
+                                addRequired(requiredResources, 
ExecutableDao.pathOfJob(lastJobId));
+                                addRequired(requiredResources, 
ExecutableDao.pathOfJobOutput(lastJobId));
+                                for (ExecutablePO task : 
executablePO.getTasks()) {
+                                    addRequired(requiredResources, 
ExecutableDao.pathOfJob(task.getUuid()));
+                                    addRequired(requiredResources, 
ExecutableDao.pathOfJobOutput(task.getUuid()));
+                                }
+                            } catch (PersistentException e) {
+                                throw new 
RuntimeException("PersistentException", e);
+                            }
+                        }
+                    } else {
+                        logger.info("Job info will not be extracted");
+                    }
+                }
+            } else {
+                if (includeJobs) {
+                    logger.warn("It's useless to set includeJobs to true when 
includeSegments is set to false");
+                }
+
+                throw new IllegalStateException("Does not support skip 
segments now");
+            }
+        } else if (realization instanceof HybridInstance) {
+            HybridInstance hybridInstance = (HybridInstance) realization;
+            addRequired(requiredResources, 
HybridInstance.concatResourcePath(hybridInstance.getName()));
+            for (IRealization iRealization : hybridInstance.getRealizations()) 
{
+                retrieveResourcePath(iRealization, includeSegments, 
includeJobs, requiredResources, optionalResources);
+            }
+        } else if (realization instanceof IIInstance) {
+            throw new IllegalStateException("Does not support extract II 
instance or hybrid that contains II");
+        } else {
+            throw new IllegalStateException("Unknown realization type: " + 
realization.getType());
+        }
+    }
+
+    private void addRequired(List<String> resourcePaths, String record) {
+        logger.info("adding required resource {}", record);
+        resourcePaths.add(record);
+    }
+
+    private void addOptional(List<String> optionalPaths, String record) {
+        logger.info("adding optional resource {}", record);
+        optionalPaths.add(record);
+    }
+
+    public static void main(String[] args) {
+        CubeMetaExtractor extractor = new CubeMetaExtractor();
+        extractor.execute(args);
+    }
+}

Reply via email to