You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kylin.apache.org by li...@apache.org on 2017/06/29 05:48:08 UTC
[01/50] kylin git commit: minor, add prepare toggle
Repository: kylin
Updated Branches:
refs/heads/master 2f084601b -> 69532cd5f
minor, add prepare toggle
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/b172e0c1
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/b172e0c1
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/b172e0c1
Branch: refs/heads/master
Commit: b172e0c15802d2e2e085b74f62011f13f55a225a
Parents: fa6d1b3
Author: Li Yang <li...@apache.org>
Authored: Wed Jun 14 20:44:08 2017 +0800
Committer: Hongbin Ma <ma...@kyligence.io>
Committed: Wed Jun 14 21:10:24 2017 +0800
----------------------------------------------------------------------
.../kylin/common/debug/BackdoorToggles.java | 14 ++++++++
.../apache/kylin/query/ITKylinQueryTest.java | 15 ++++++++
.../org/apache/kylin/query/KylinTestBase.java | 5 ++-
.../kylin/query/enumerator/OLAPQuery.java | 36 ++++++++++++++++++--
4 files changed, 66 insertions(+), 4 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/b172e0c1/core-common/src/main/java/org/apache/kylin/common/debug/BackdoorToggles.java
----------------------------------------------------------------------
diff --git a/core-common/src/main/java/org/apache/kylin/common/debug/BackdoorToggles.java b/core-common/src/main/java/org/apache/kylin/common/debug/BackdoorToggles.java
index 95d5d62..8cb48b6 100644
--- a/core-common/src/main/java/org/apache/kylin/common/debug/BackdoorToggles.java
+++ b/core-common/src/main/java/org/apache/kylin/common/debug/BackdoorToggles.java
@@ -106,6 +106,10 @@ public class BackdoorToggles {
return Integer.valueOf(v);
}
+ public static boolean getPrepareOnly() {
+ return getBoolean(DEBUG_TOGGLE_PREPARE_ONLY);
+ }
+
private static String getString(String key) {
Map<String, String> toggles = _backdoorToggles.get();
if (toggles == null) {
@@ -230,6 +234,16 @@ public class BackdoorToggles {
*/
public final static String DEBUG_TOGGLE_DUMPED_PARTITION_DIR = "DEBUG_TOGGLE_DUMPED_PARTITION_DIR";
+ /**
+ * set DEBUG_TOGGLE_PREPARE_ONLY="true" to prepare the sql statement and get its result set metadata
+ *
+ example:(put it into request body)
+ "backdoorToggles": {
+ "DEBUG_TOGGLE_PREPARE_ONLY": "true"
+ }
+ */
+ public final static String DEBUG_TOGGLE_PREPARE_ONLY = "DEBUG_TOGGLE_PREPARE_ONLY";
+
// properties on statement may go with this "channel" too
/**
* set ATTR_STATEMENT_MAX_ROWS="maxRows" to statement's max rows property
http://git-wip-us.apache.org/repos/asf/kylin/blob/b172e0c1/kylin-it/src/test/java/org/apache/kylin/query/ITKylinQueryTest.java
----------------------------------------------------------------------
diff --git a/kylin-it/src/test/java/org/apache/kylin/query/ITKylinQueryTest.java b/kylin-it/src/test/java/org/apache/kylin/query/ITKylinQueryTest.java
index 55041e3..4ea4497 100644
--- a/kylin-it/src/test/java/org/apache/kylin/query/ITKylinQueryTest.java
+++ b/kylin-it/src/test/java/org/apache/kylin/query/ITKylinQueryTest.java
@@ -200,6 +200,21 @@ public class ITKylinQueryTest extends KylinTestBase {
}
@Test
+ public void testVerifyCountQueryWithPrepare() throws Exception {
+ try {
+ Map<String, String> toggles = Maps.newHashMap();
+ toggles.put(BackdoorToggles.DEBUG_TOGGLE_PREPARE_ONLY, "true");
+ BackdoorToggles.setToggles(toggles);
+
+ verifyResultRowColCount(getQueryFolderPrefix() + "src/test/resources/query/sql_verifyCount");
+
+ } finally {
+ BackdoorToggles.cleanToggles();
+
+ }
+ }
+
+ @Test
public void testVerifyContentQuery() throws Exception {
verifyResultContent(getQueryFolderPrefix() + "src/test/resources/query/sql_verifyContent");
}
http://git-wip-us.apache.org/repos/asf/kylin/blob/b172e0c1/kylin-it/src/test/java/org/apache/kylin/query/KylinTestBase.java
----------------------------------------------------------------------
diff --git a/kylin-it/src/test/java/org/apache/kylin/query/KylinTestBase.java b/kylin-it/src/test/java/org/apache/kylin/query/KylinTestBase.java
index 0db5388..a05d0c3 100644
--- a/kylin-it/src/test/java/org/apache/kylin/query/KylinTestBase.java
+++ b/kylin-it/src/test/java/org/apache/kylin/query/KylinTestBase.java
@@ -44,6 +44,7 @@ import java.util.logging.LogManager;
import org.apache.commons.lang3.StringUtils;
import org.apache.kylin.common.KylinConfig;
+import org.apache.kylin.common.debug.BackdoorToggles;
import org.apache.kylin.common.util.HBaseMetadataTestCase;
import org.apache.kylin.common.util.Pair;
import org.apache.kylin.metadata.project.ProjectInstance;
@@ -365,7 +366,9 @@ public class KylinTestBase {
ITable kylinTable = executeQuery(kylinConn, queryName, sql, false);
// compare the result
- if (expectRowCount >= 0)
+ if (BackdoorToggles.getPrepareOnly())
+ Assert.assertEquals(queryName, 0, kylinTable.getRowCount());
+ else if (expectRowCount >= 0)
Assert.assertEquals(queryName, expectRowCount, kylinTable.getRowCount());
if (expectColCount >= 0)
http://git-wip-us.apache.org/repos/asf/kylin/blob/b172e0c1/query/src/main/java/org/apache/kylin/query/enumerator/OLAPQuery.java
----------------------------------------------------------------------
diff --git a/query/src/main/java/org/apache/kylin/query/enumerator/OLAPQuery.java b/query/src/main/java/org/apache/kylin/query/enumerator/OLAPQuery.java
index 8318a07..debc125 100644
--- a/query/src/main/java/org/apache/kylin/query/enumerator/OLAPQuery.java
+++ b/query/src/main/java/org/apache/kylin/query/enumerator/OLAPQuery.java
@@ -22,12 +22,17 @@ import org.apache.calcite.DataContext;
import org.apache.calcite.linq4j.AbstractEnumerable;
import org.apache.calcite.linq4j.Enumerable;
import org.apache.calcite.linq4j.Enumerator;
+import org.apache.kylin.common.debug.BackdoorToggles;
import org.apache.kylin.query.relnode.OLAPContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
*/
public class OLAPQuery extends AbstractEnumerable<Object[]> implements Enumerable<Object[]> {
+ private static final Logger logger = LoggerFactory.getLogger(OLAPQuery.class);
+
public enum EnumeratorTypeEnum {
OLAP, //finish query with Cube or II, or a combination of both
LOOKUP_TABLE, //using a snapshot of lookup table
@@ -52,13 +57,38 @@ public class OLAPQuery extends AbstractEnumerable<Object[]> implements Enumerabl
OLAPContext olapContext = OLAPContext.getThreadLocalContextById(contextId);
switch (type) {
case OLAP:
- return new OLAPEnumerator(olapContext, optiqContext);
+ return BackdoorToggles.getPrepareOnly() ? new EmptyEnumerator() : new OLAPEnumerator(olapContext, optiqContext);
case LOOKUP_TABLE:
- return new LookupTableEnumerator(olapContext);
+ return BackdoorToggles.getPrepareOnly() ? new EmptyEnumerator() : new LookupTableEnumerator(olapContext);
case HIVE:
- return new HiveEnumerator(olapContext);
+ return BackdoorToggles.getPrepareOnly() ? new EmptyEnumerator() : new HiveEnumerator(olapContext);
default:
throw new IllegalArgumentException("Wrong type " + type + "!");
}
}
+
+ private static class EmptyEnumerator implements Enumerator<Object[]> {
+
+ EmptyEnumerator() {
+ logger.debug("Using empty enumerator");
+ }
+
+ @Override
+ public void close() {
+ }
+
+ @Override
+ public Object[] current() {
+ return null;
+ }
+
+ @Override
+ public boolean moveNext() {
+ return false;
+ }
+
+ @Override
+ public void reset() {
+ }
+ }
}
[04/50] kylin git commit: minor, odbc only cache success request
Posted by li...@apache.org.
minor, odbc only cache success request
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/1b583730
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/1b583730
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/1b583730
Branch: refs/heads/master
Commit: 1b5837305e9343a3624b50ec460cb88f883236ce
Parents: 27dfdbc
Author: Roger Shi <ro...@hotmail.com>
Authored: Thu Jun 15 17:37:38 2017 +0800
Committer: Dong Li <li...@apache.org>
Committed: Thu Jun 15 17:43:44 2017 +0800
----------------------------------------------------------------------
odbc/Common/QueryCache.cpp | 9 ++++++---
odbc/Common/REST.cpp | 5 ++++-
2 files changed, 10 insertions(+), 4 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/1b583730/odbc/Common/QueryCache.cpp
----------------------------------------------------------------------
diff --git a/odbc/Common/QueryCache.cpp b/odbc/Common/QueryCache.cpp
index 6b49273..5c08d7e 100644
--- a/odbc/Common/QueryCache.cpp
+++ b/odbc/Common/QueryCache.cpp
@@ -42,7 +42,8 @@ const wchar_t* loadCache ( const wchar_t* query )
wstring queryString = wstring(query);
queryString.erase(remove_if(queryString.begin(), queryString.end(), ::isspace), queryString.end());
map<wstring, wstring>::iterator it = queryMap.find(queryString);
- if (it != queryMap.end()) {
+ if (it != queryMap.end())
+ {
return it->second.c_str();
}
return NULL;
@@ -55,11 +56,13 @@ void storeCache (const wchar_t* query, const wchar_t* result)
queryString.erase(remove_if(queryString.begin(), queryString.end(), ::isspace), queryString.end());
map<wstring, wstring>::iterator it = queryMap.find(queryString);
- if (it != queryMap.end()) {
+ if (it != queryMap.end())
+ {
return;
}
- if (queryQueue.size() >= cacheSize) {
+ if (queryQueue.size() >= cacheSize)
+ {
wstring head = queryQueue.front();
queryQueue.pop();
queryMap.erase(head);
http://git-wip-us.apache.org/repos/asf/kylin/blob/1b583730/odbc/Common/REST.cpp
----------------------------------------------------------------------
diff --git a/odbc/Common/REST.cpp b/odbc/Common/REST.cpp
index 2111aca..858ecd4 100644
--- a/odbc/Common/REST.cpp
+++ b/odbc/Common/REST.cpp
@@ -444,7 +444,10 @@ wstring requestQuery ( wchar_t* rawSql, char* serverAddr, long port, char* usern
wstring ret = getBodyString ( response );
- storeCache(rawSql, ret.c_str());
+ if (*statusFlag == 1)
+ {
+ storeCache(rawSql, ret.c_str());
+ }
return ret;
}
[48/50] kylin git commit: minor,
add parserTimeStampField to KafkaConfig (#1405)
Posted by li...@apache.org.
minor, add parserTimeStampField to KafkaConfig (#1405)
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/b2fc2c22
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/b2fc2c22
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/b2fc2c22
Branch: refs/heads/master
Commit: b2fc2c220ba66482447a7631f90363382bcaa422
Parents: 1acd066
Author: 成 <ch...@kyligence.io>
Authored: Wed Jun 28 11:23:51 2017 +0800
Committer: Billy(Yiming) Liu <li...@gmail.com>
Committed: Wed Jun 28 11:23:51 2017 +0800
----------------------------------------------------------------------
.../apache/kylin/source/kafka/KafkaMRInput.java | 2 +-
.../kylin/source/kafka/config/KafkaConfig.java | 22 ++++++++++++++++++++
2 files changed, 23 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/b2fc2c22/source-kafka/src/main/java/org/apache/kylin/source/kafka/KafkaMRInput.java
----------------------------------------------------------------------
diff --git a/source-kafka/src/main/java/org/apache/kylin/source/kafka/KafkaMRInput.java b/source-kafka/src/main/java/org/apache/kylin/source/kafka/KafkaMRInput.java
index 3323afb..5bce4e7 100644
--- a/source-kafka/src/main/java/org/apache/kylin/source/kafka/KafkaMRInput.java
+++ b/source-kafka/src/main/java/org/apache/kylin/source/kafka/KafkaMRInput.java
@@ -103,7 +103,7 @@ public class KafkaMRInput implements IMRInput {
this.cubeSegment = cubeSegment;
this.conf = conf;
try {
- streamingParser = StreamingParser.getStreamingParser(kafkaConfig.getParserName(), kafkaConfig.getParserProperties(), columns);
+ streamingParser = StreamingParser.getStreamingParser(kafkaConfig.getParserName(), kafkaConfig.getAllParserProperties(), columns);
} catch (ReflectiveOperationException e) {
throw new IllegalArgumentException(e);
}
http://git-wip-us.apache.org/repos/asf/kylin/blob/b2fc2c22/source-kafka/src/main/java/org/apache/kylin/source/kafka/config/KafkaConfig.java
----------------------------------------------------------------------
diff --git a/source-kafka/src/main/java/org/apache/kylin/source/kafka/config/KafkaConfig.java b/source-kafka/src/main/java/org/apache/kylin/source/kafka/config/KafkaConfig.java
index a096344..547e738 100644
--- a/source-kafka/src/main/java/org/apache/kylin/source/kafka/config/KafkaConfig.java
+++ b/source-kafka/src/main/java/org/apache/kylin/source/kafka/config/KafkaConfig.java
@@ -58,6 +58,9 @@ public class KafkaConfig extends RootPersistentEntity {
@JsonProperty("parserName")
private String parserName;
+ @JsonProperty("parserTimeStampField")
+ private String parserTimeStampField;
+
@Deprecated
@JsonProperty("margin")
private long margin;
@@ -120,6 +123,14 @@ public class KafkaConfig extends RootPersistentEntity {
this.margin = margin;
}
+ public void setParserTimeStampField(String parserTimeStampField) {
+ this.parserTimeStampField = parserTimeStampField;
+ }
+
+ public String getParserTimeStampField() {
+ return this.parserTimeStampField;
+ }
+
public String getParserProperties() {
return parserProperties;
}
@@ -128,6 +139,17 @@ public class KafkaConfig extends RootPersistentEntity {
this.parserProperties = parserProperties;
}
+ public String getAllParserProperties() {
+ StringBuilder sb = new StringBuilder();
+ if (parserProperties != null)
+ sb.append(parserProperties);
+ if (parserTimeStampField != null) {
+ sb.append(";");
+ sb.append(parserTimeStampField);
+ }
+ return sb.toString();
+ }
+
@Override
public KafkaConfig clone() {
try {
[25/50] kylin git commit: minor, move csrf conf to right place
Posted by li...@apache.org.
minor, move csrf conf to right place
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/1e386948
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/1e386948
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/1e386948
Branch: refs/heads/master
Commit: 1e386948ad7381c86891233193a95837b3a47c8b
Parents: 7661ad7
Author: Roger Shi <ro...@hotmail.com>
Authored: Tue Jun 20 21:10:13 2017 +0800
Committer: Dong Li <li...@apache.org>
Committed: Tue Jun 20 21:16:21 2017 +0800
----------------------------------------------------------------------
server/src/main/resources/kylinSecurity.xml | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/1e386948/server/src/main/resources/kylinSecurity.xml
----------------------------------------------------------------------
diff --git a/server/src/main/resources/kylinSecurity.xml b/server/src/main/resources/kylinSecurity.xml
index 506b2f1..039bded 100644
--- a/server/src/main/resources/kylinSecurity.xml
+++ b/server/src/main/resources/kylinSecurity.xml
@@ -29,7 +29,6 @@
<scr:expression-handler ref="expressionHandler"/>
</scr:global-method-security>
- <scr:csrf disabled="true"/>
<!-- acl config -->
<bean id="aclPermissionFactory" class="org.apache.kylin.rest.security.AclPermissionFactory"/>
@@ -229,6 +228,7 @@
<beans profile="testing,ldap">
<scr:http auto-config="true" use-expressions="true">
+ <scr:csrf disabled="true"/>
<scr:http-basic entry-point-ref="unauthorisedEntryPoint"/>
<scr:intercept-url pattern="/api/user/authentication*/**" access="permitAll"/>
@@ -270,6 +270,7 @@
<!-- Secured Rest API urls with LDAP basic authentication -->
<scr:http pattern="/api/**" use-expressions="true"
authentication-manager-ref="apiAccessAuthenticationManager">
+ <scr:csrf disabled="true"/>
<scr:http-basic entry-point-ref="unauthorisedEntryPoint"/>
<scr:intercept-url pattern="/api/user/authentication*/**" access="permitAll"/>
@@ -294,6 +295,7 @@
<!-- Secured non-api urls with SAML SSO -->
<scr:http auto-config="true" entry-point-ref="samlEntryPoint" use-expressions="false"
authentication-manager-ref="webAccessAuthenticationManager">
+ <scr:csrf disabled="true"/>
<scr:intercept-url pattern="/**" access="IS_AUTHENTICATED_FULLY"/>
<scr:custom-filter before="FIRST" ref="metadataGeneratorFilter"/>
<scr:custom-filter after="BASIC_AUTH_FILTER" ref="samlFilter"/>
[17/50] kylin git commit: fix sample cube model
Posted by li...@apache.org.
fix sample cube model
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/d67bf453
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/d67bf453
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/d67bf453
Branch: refs/heads/master
Commit: d67bf453aa791f90edd89f1f7a40e8ce6a399312
Parents: 3beef26
Author: Li Yang <li...@apache.org>
Authored: Mon Jun 19 14:11:15 2017 +0800
Committer: Luwei-Chen <ch...@apache.org>
Committed: Mon Jun 19 15:38:01 2017 +0800
----------------------------------------------------------------------
examples/sample_cube/template/model_desc/kylin_sales_model.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/d67bf453/examples/sample_cube/template/model_desc/kylin_sales_model.json
----------------------------------------------------------------------
diff --git a/examples/sample_cube/template/model_desc/kylin_sales_model.json b/examples/sample_cube/template/model_desc/kylin_sales_model.json
index 50864fc..bcfc1ec 100644
--- a/examples/sample_cube/template/model_desc/kylin_sales_model.json
+++ b/examples/sample_cube/template/model_desc/kylin_sales_model.json
@@ -58,7 +58,7 @@
"columns" : [ "TRANS_ID", "SELLER_ID", "BUYER_ID", "PART_DT", "LEAF_CATEG_ID", "LSTG_FORMAT_NAME", "LSTG_SITE_ID", "OPS_USER_ID", "OPS_REGION" ]
}, {
"table" : "KYLIN_CAL_DT",
- "columns" : ["CAL_DT", "WEEK_BEG_DT"]
+ "columns" : [ "CAL_DT", "WEEK_BEG_DT", "MONTH_BEG_DT", "YEAR_BEG_DT" ]
}, {
"table" : "KYLIN_CATEGORY_GROUPINGS",
"columns" : [ "USER_DEFINED_FIELD1", "USER_DEFINED_FIELD3", "META_CATEG_NAME", "CATEG_LVL2_NAME", "CATEG_LVL3_NAME", "LEAF_CATEG_ID", "SITE_ID" ]
[36/50] kylin git commit: #1345 Refine MetaStoreService due to change
of Copy
Posted by li...@apache.org.
#1345 Refine MetaStoreService due to change of Copy
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/22d8faea
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/22d8faea
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/22d8faea
Branch: refs/heads/master
Commit: 22d8faeacdd43d65550e23ce9b8d2bbbb0fd6f96
Parents: e6f58d1
Author: auphyroc99 <45...@qq.com>
Authored: Fri Jun 23 13:07:14 2017 +0800
Committer: Hongbin Ma <ma...@kyligence.io>
Committed: Fri Jun 23 19:29:08 2017 +0800
----------------------------------------------------------------------
tool/src/main/java/org/apache/kylin/tool/CubeMetaExtractor.java | 2 ++
1 file changed, 2 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/22d8faea/tool/src/main/java/org/apache/kylin/tool/CubeMetaExtractor.java
----------------------------------------------------------------------
diff --git a/tool/src/main/java/org/apache/kylin/tool/CubeMetaExtractor.java b/tool/src/main/java/org/apache/kylin/tool/CubeMetaExtractor.java
index bc8f34f..ce4ebfa 100644
--- a/tool/src/main/java/org/apache/kylin/tool/CubeMetaExtractor.java
+++ b/tool/src/main/java/org/apache/kylin/tool/CubeMetaExtractor.java
@@ -164,6 +164,8 @@ public class CubeMetaExtractor extends AbstractInfoExtractor {
executableDao = ExecutableDao.getInstance(kylinConfig);
realizationRegistry = RealizationRegistry.getInstance(kylinConfig);
badQueryHistoryManager = BadQueryHistoryManager.getInstance(kylinConfig);
+
+ addRequired(ResourceStore.METASTORE_UUID_TAG);
if (optionsHelper.hasOption(OPTION_All_PROJECT)) {
for (ProjectInstance projectInstance : projectManager.listAllProjects()) {
[16/50] kylin git commit: #1089 Clone raw table and scheduler with
cube
Posted by li...@apache.org.
#1089 Clone raw table and scheduler with cube
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/3beef268
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/3beef268
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/3beef268
Branch: refs/heads/master
Commit: 3beef268dd06fb3f275b4accc92836b44d99b175
Parents: 66dc541
Author: Roger Shi <ro...@hotmail.com>
Authored: Mon Jun 19 12:02:35 2017 +0800
Committer: Hongbin Ma <ma...@kyligence.io>
Committed: Mon Jun 19 13:30:35 2017 +0800
----------------------------------------------------------------------
.../kylin/rest/controller/CubeController.java | 4 +-
.../rest/controller2/CubeControllerV2.java | 41 --------------------
.../apache/kylin/rest/service/CubeService.java | 4 +-
3 files changed, 4 insertions(+), 45 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/3beef268/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 14c80a0..6916dd8 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
@@ -18,6 +18,8 @@
package org.apache.kylin.rest.controller;
+import static org.apache.kylin.rest.service.CubeService.VALID_CUBENAME;
+
import java.io.IOException;
import java.net.UnknownHostException;
import java.util.ArrayList;
@@ -83,8 +85,6 @@ import com.google.common.collect.Maps;
public class CubeController extends BasicController {
private static final Logger logger = LoggerFactory.getLogger(CubeController.class);
- private static final char[] VALID_CUBENAME = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_".toCharArray();
-
@Autowired
@Qualifier("cubeMgmtService")
private CubeService cubeService;
http://git-wip-us.apache.org/repos/asf/kylin/blob/3beef268/server-base/src/main/java/org/apache/kylin/rest/controller2/CubeControllerV2.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/controller2/CubeControllerV2.java b/server-base/src/main/java/org/apache/kylin/rest/controller2/CubeControllerV2.java
index 720cf76..93c4d4e 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/controller2/CubeControllerV2.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/controller2/CubeControllerV2.java
@@ -25,7 +25,6 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import org.apache.commons.lang.StringUtils;
import org.apache.kylin.cube.CubeInstance;
import org.apache.kylin.cube.CubeManager;
import org.apache.kylin.cube.CubeSegment;
@@ -43,7 +42,6 @@ import org.apache.kylin.rest.controller.BasicController;
import org.apache.kylin.rest.exception.BadRequestException;
import org.apache.kylin.rest.msg.Message;
import org.apache.kylin.rest.msg.MsgPicker;
-import org.apache.kylin.rest.request.CubeRequest;
import org.apache.kylin.rest.request.JobBuildRequest;
import org.apache.kylin.rest.request.JobBuildRequest2;
import org.apache.kylin.rest.response.CubeInstanceResponse;
@@ -80,9 +78,6 @@ import com.google.common.collect.Lists;
public class CubeControllerV2 extends BasicController {
private static final Logger logger = LoggerFactory.getLogger(CubeControllerV2.class);
- public static final char[] VALID_CUBENAME = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_"
- .toCharArray();
-
@Autowired
@Qualifier("cubeMgmtService")
private CubeService cubeService;
@@ -437,42 +432,6 @@ public class CubeControllerV2 extends BasicController {
return new EnvelopeResponse(ResponseCode.CODE_SUCCESS, cubeService.purgeCube(cube), "");
}
- @RequestMapping(value = "/{cubeName}/clone", method = { RequestMethod.PUT }, produces = {
- "application/vnd.apache.kylin-v2+json" })
- @ResponseBody
- public EnvelopeResponse cloneCubeV2(@PathVariable String cubeName, @RequestBody CubeRequest cubeRequest)
- throws IOException {
- Message msg = MsgPicker.getMsg();
-
- String newCubeName = cubeRequest.getCubeName();
- String project = cubeRequest.getProject();
-
- CubeInstance cube = cubeService.getCubeManager().getCube(cubeName);
- if (cube == null) {
- throw new BadRequestException(String.format(msg.getCUBE_NOT_FOUND(), cubeName));
- }
- if (cube.getStatus() == RealizationStatusEnum.DESCBROKEN) {
- throw new BadRequestException(String.format(msg.getCLONE_BROKEN_CUBE(), cubeName));
- }
- if (!StringUtils.containsOnly(newCubeName, VALID_CUBENAME)) {
- logger.info("Invalid Cube name {}, only letters, numbers and underline supported.", newCubeName);
- throw new BadRequestException(String.format(msg.getINVALID_CUBE_NAME(), cubeName));
- }
-
- CubeDesc cubeDesc = cube.getDescriptor();
- CubeDesc newCubeDesc = CubeDesc.getCopyOf(cubeDesc);
-
- newCubeDesc.setName(newCubeName);
-
- CubeInstance newCube;
- newCube = cubeService.createCubeAndDesc(newCubeName, project, newCubeDesc);
-
- //reload to avoid shallow clone
- cubeService.getCubeDescManager().reloadCubeDescLocal(newCubeName);
-
- return new EnvelopeResponse(ResponseCode.CODE_SUCCESS, newCube, "");
- }
-
@RequestMapping(value = "/{cubeName}/enable", method = { RequestMethod.PUT }, produces = {
"application/vnd.apache.kylin-v2+json" })
@ResponseBody
http://git-wip-us.apache.org/repos/asf/kylin/blob/3beef268/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 7f09612..f6de877 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
@@ -18,8 +18,6 @@
package org.apache.kylin.rest.service;
-import static org.apache.kylin.rest.controller2.CubeControllerV2.VALID_CUBENAME;
-
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
@@ -82,6 +80,8 @@ public class CubeService extends BasicService {
private static final Logger logger = LoggerFactory.getLogger(CubeService.class);
+ public static final char[] VALID_CUBENAME = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_".toCharArray();
+
private WeakHashMap<String, HBaseResponse> htableInfoCache = new WeakHashMap<>();
@Autowired
[02/50] kylin git commit: KYLIN-2632 update get saved queries api
(#1172)
Posted by li...@apache.org.
KYLIN-2632 update get saved queries api (#1172)
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/3dbdbf54
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/3dbdbf54
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/3dbdbf54
Branch: refs/heads/master
Commit: 3dbdbf544be012b47d4735a3f5aae0254e97b153
Parents: b172e0c
Author: Luwei-Chen <ch...@apache.org>
Authored: Thu Jun 15 12:22:28 2017 +0800
Committer: luguosheng1314 <55...@qq.com>
Committed: Thu Jun 15 12:22:28 2017 +0800
----------------------------------------------------------------------
.../org/apache/kylin/rest/controller2/QueryControllerV2.java | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/3dbdbf54/server-base/src/main/java/org/apache/kylin/rest/controller2/QueryControllerV2.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/controller2/QueryControllerV2.java b/server-base/src/main/java/org/apache/kylin/rest/controller2/QueryControllerV2.java
index ab4741d..a641a53 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/controller2/QueryControllerV2.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/controller2/QueryControllerV2.java
@@ -109,10 +109,10 @@ public class QueryControllerV2 extends BasicController {
queryService.removeQuery(creator, id);
}
- @RequestMapping(value = "/saved_queries/{project}", method = RequestMethod.GET, produces = {
+ @RequestMapping(value = "/saved_queries", method = RequestMethod.GET, produces = {
"application/vnd.apache.kylin-v2+json" })
@ResponseBody
- public EnvelopeResponse getQueriesV2(@PathVariable String project,
+ public EnvelopeResponse getQueriesV2(@RequestParam(value = "project", required = false) String project,
@RequestParam(value = "pageOffset", required = false, defaultValue = "0") Integer pageOffset,
@RequestParam(value = "pageSize", required = false, defaultValue = "10") Integer pageSize)
throws IOException {
@@ -121,7 +121,7 @@ public class QueryControllerV2 extends BasicController {
String creator = SecurityContextHolder.getContext().getAuthentication().getName();
List<Query> queries = new ArrayList<Query>();
for (Query query : queryService.getQueries(creator)) {
- if (query.getProject().equals(project))
+ if (project == null || query.getProject().equals(project))
queries.add(query);
}
[03/50] kylin git commit: minor, add cache in ODBC
Posted by li...@apache.org.
minor, add cache in ODBC
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/27dfdbc6
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/27dfdbc6
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/27dfdbc6
Branch: refs/heads/master
Commit: 27dfdbc65fa68609a8c9fd26c75067d1df4b6753
Parents: 3dbdbf5
Author: Roger Shi <ro...@hotmail.com>
Authored: Thu Jun 15 15:12:15 2017 +0800
Committer: Dong Li <li...@apache.org>
Committed: Thu Jun 15 16:49:07 2017 +0800
----------------------------------------------------------------------
odbc/Common/QueryCache.cpp | 84 +++++++++++++++--------------------------
odbc/Common/QueryCache.h | 1 +
odbc/Common/REST.cpp | 14 +------
3 files changed, 32 insertions(+), 67 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/27dfdbc6/odbc/Common/QueryCache.cpp
----------------------------------------------------------------------
diff --git a/odbc/Common/QueryCache.cpp b/odbc/Common/QueryCache.cpp
index 48c187e..6b49273 100644
--- a/odbc/Common/QueryCache.cpp
+++ b/odbc/Common/QueryCache.cpp
@@ -23,72 +23,48 @@
#include <cpprest/json.h>
#include <cpprest/uri.h>
#include <regex>
+#include <map>
+#include <queue>
+#include <mutex>
#include "Dump.h"
#include "JsonConverter.h"
+using namespace std;
-const wchar_t* alwaysFailQueries[7] = {
- L"(\\s)*CREATE(\\s)*LOCAL(\\s)*TEMPORARY(\\s)*TABLE(\\s)*\"XTableau_B_Connect\"(\\s)*\\((\\s)*\"COL\"(\\s)*INTEGER(\\s)*\\)(\\s)*ON(\\s)*COMMIT(\\s)*PRESERVE(\\s)*ROWS(\\s)*",
- L"(\\s)*DROP(\\s)*TABLE(\\s)*\"XTableau_B_Connect\"(\\s)*",
- L"(\\s)*SELECT(\\s)*TOP(\\s)*1(\\s)*\"COL\"(\\s)*FROM(\\s)*\\(SELECT(\\s)*1(\\s)*AS(\\s)*\"COL\"(\\s)*\\)(\\s)*AS(\\s)*\"CHECKTOP\"(\\s)*",
- L"(\\s)*SELECT(\\s)*\"SUBCOL\"(\\s)*AS(\\s)*\"COL\"(\\s)*FROM(\\s)*\\((\\s)*SELECT(\\s)*1(\\s)*AS(\\s)*\"SUBCOL\"(\\s)*\\)(\\s)*\"SUBQUERY\"(\\s)*GROUP(\\s)*BY(\\s)*1(\\s)*",
- L"(\\s)*SELECT(\\s)*\"SUBCOL\"(\\s)*AS(\\s)*\"COL\"(\\s)*FROM(\\s)*\\((\\s)*SELECT(\\s)*1(\\s)*AS(\\s)*\"SUBCOL\"(\\s)*\\)(\\s)*\"SUBQUERY\"(\\s)*GROUP(\\s)*BY(\\s)*\"COL\"(\\s)*",
- L"(\\s)*INSERT(\\s)*INTO(\\s)*\"XTableau_C_Connect\"(\\s)*SELECT(\\s)*\\*(\\s)*FROM(\\s)*\\(SELECT(\\s)*1(\\s)*AS(\\s)*COL(\\s)*\\)(\\s)*AS(\\s)*CHECKTEMP(\\s)*LIMIT(\\s)*1(\\s)*",
- L"(\\s)*DROP(\\s)*TABLE(\\s)*\"XTableau_C_Connect\"(\\s)*"
-};
+map<wstring, wstring> queryMap;
+queue<wstring> queryQueue;
+const int cacheSize = 20;
+mutex cacheMutex;
-const wchar_t* alwaysSuccessQueries[3] = {
- L"(\\s)*SELECT(\\s)*1(\\s)*",
- L"(\\s)*SELECT(\\s)*\"COL\"(\\s)*FROM(\\s)*\\(SELECT(\\s)*1(\\s)*AS(\\s)*\"COL\"\\)(\\s)*AS(\\s)*\"SUBQUERY\"(\\s)*",
- L"(\\s)*SELECT(\\s)*\"COL\"(\\s)*FROM(\\s)*\\(SELECT(\\s)*1(\\s)*AS(\\s)*\"COL\"\\)(\\s)*AS(\\s)*\"CHECKTOP\"(\\s)*LIMIT(\\s)*1(\\s)*"
-};
-
-const wchar_t* alwaysSuccessResults[3] = {
- L"{\"columnMetas\":[{\"isNullable\":2,\"displaySize\":11,\"label\":\"COL\",\"name\":\"COL\",\"schemaName\":\"\",\"catelogName\":\"\",\"tableName\":\"\",\"precision\":10,\"scale\":0,\"columnType\":4,\"columnTypeName\":\"int4\",\"writable\":true,\"caseSensitive\":false,\"autoIncrement\":false,\"searchable\":true,\"currency\":false,\"signed\":true,\"definitelyWritable\":false,\"readOnly\":false}],\"results\":[[\"1\"]],\"isResultsFlatten\":false,\"flattenResult\":null,\"flattenResultOriginalSize\":0,\"cubes\":null,\"affectedRowCount\":0,\"isException\":false,\"exceptionMessage\":null,\"duration\":0.002,\"partial\":false}",
- L"{\"columnMetas\":[{\"isNullable\":2,\"displaySize\":11,\"label\":\"COL\",\"name\":\"COL\",\"schemaName\":\"\",\"catelogName\":\"\",\"tableName\":\"\",\"precision\":10,\"scale\":0,\"columnType\":4,\"columnTypeName\":\"int4\",\"writable\":true,\"caseSensitive\":false,\"autoIncrement\":false,\"searchable\":true,\"currency\":false,\"signed\":true,\"definitelyWritable\":false,\"readOnly\":false}],\"results\":[[\"1\"]],\"isResultsFlatten\":false,\"flattenResult\":null,\"flattenResultOriginalSize\":0,\"cubes\":null,\"affectedRowCount\":0,\"isException\":false,\"exceptionMessage\":null,\"duration\":0.002,\"partial\":false}",
- L"{\"columnMetas\":[{\"isNullable\":2,\"displaySize\":11,\"label\":\"COL\",\"name\":\"COL\",\"schemaName\":\"\",\"catelogName\":\"\",\"tableName\":\"\",\"precision\":10,\"scale\":0,\"columnType\":4,\"columnTypeName\":\"int4\",\"writable\":true,\"caseSensitive\":false,\"autoIncrement\":false,\"searchable\":true,\"currency\":false,\"signed\":true,\"definitelyWritable\":false,\"readOnly\":false}],\"results\":[[\"1\"]],\"isResultsFlatten\":false,\"flattenResult\":null,\"flattenResultOriginalSize\":0,\"cubes\":null,\"affectedRowCount\":0,\"isException\":false,\"exceptionMessage\":null,\"duration\":0.002,\"partial\":false}"
-};
-
-int findQuery ( const wchar_t* sql, const wchar_t** regexs, int size )
+const wchar_t* loadCache ( const wchar_t* query )
{
- for ( int i = 0; i < size; ++i )
- {
- std::tr1::wregex rgx ( regexs[i], regex_constants::icase );
- bool match = std::tr1::regex_search ( sql, rgx );
-
- if ( match )
- {
- return i;
- }
+ lock_guard<mutex> lock(cacheMutex);
+ wstring queryString = wstring(query);
+ queryString.erase(remove_if(queryString.begin(), queryString.end(), ::isspace), queryString.end());
+ map<wstring, wstring>::iterator it = queryMap.find(queryString);
+ if (it != queryMap.end()) {
+ return it->second.c_str();
}
-
- return -1;
-}
-
-int findInAlwaysSuccessQuery ( const wchar_t* sql )
-{
- return findQuery ( sql, alwaysSuccessQueries, sizeof ( alwaysSuccessQueries ) / sizeof ( wchar_t*) );
-}
-
-int findInAlwaysFailQuery ( const wchar_t* sql )
-{
- return findQuery ( sql, alwaysFailQueries, sizeof ( alwaysFailQueries ) / sizeof ( wchar_t*) );
+ return NULL;
}
-const wchar_t* loadCache ( const wchar_t* query )
+void storeCache (const wchar_t* query, const wchar_t* result)
{
- int index = 0;
-
- if ( findInAlwaysFailQuery ( query ) >= 0 )
- {
- throw exception ( "Unsupported SQL" );
+ lock_guard<mutex> lock(cacheMutex);
+ wstring queryString = wstring(query);
+ queryString.erase(remove_if(queryString.begin(), queryString.end(), ::isspace), queryString.end());
+
+ map<wstring, wstring>::iterator it = queryMap.find(queryString);
+ if (it != queryMap.end()) {
+ return;
}
- else if ( ( index = findInAlwaysSuccessQuery ( query ) ) >= 0 )
- {
- return alwaysSuccessResults[index];
+ if (queryQueue.size() >= cacheSize) {
+ wstring head = queryQueue.front();
+ queryQueue.pop();
+ queryMap.erase(head);
}
- return NULL;
+ queryQueue.push(queryString);
+ queryMap[queryString] = result;
}
-
http://git-wip-us.apache.org/repos/asf/kylin/blob/27dfdbc6/odbc/Common/QueryCache.h
----------------------------------------------------------------------
diff --git a/odbc/Common/QueryCache.h b/odbc/Common/QueryCache.h
index 1ce6dbd..f06a7ae 100644
--- a/odbc/Common/QueryCache.h
+++ b/odbc/Common/QueryCache.h
@@ -22,4 +22,5 @@
#include "MsgTypes.h"
const wchar_t* loadCache ( const wchar_t* query );
+void storeCache (const wchar_t* query, const wchar_t* result);
http://git-wip-us.apache.org/repos/asf/kylin/blob/27dfdbc6/odbc/Common/REST.cpp
----------------------------------------------------------------------
diff --git a/odbc/Common/REST.cpp b/odbc/Common/REST.cpp
index 8fe62d5..2111aca 100644
--- a/odbc/Common/REST.cpp
+++ b/odbc/Common/REST.cpp
@@ -45,19 +45,6 @@ using namespace concurrency::streams;
using namespace web;
using namespace web::json;
-void printLog ( const char* msg )
-{
- time_t now = time ( 0 );
- struct tm tstruct;
- char buffer[100];
- tstruct = *localtime ( &now );
- strftime ( buffer, 100, "%Y-%m-%d.%X", &tstruct );
- printf ( buffer );
- printf ( "\n" );
- printf ( msg );
- printf ( "\n" );
-}
-
/// <summary>
/// Find the longest length
/// </summary>
@@ -457,6 +444,7 @@ wstring requestQuery ( wchar_t* rawSql, char* serverAddr, long port, char* usern
wstring ret = getBodyString ( response );
+ storeCache(rawSql, ret.c_str());
return ret;
}
[41/50] kylin git commit: minor, fix agg combination calcuation
Posted by li...@apache.org.
minor, fix agg combination calcuation
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/ac725cbd
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/ac725cbd
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/ac725cbd
Branch: refs/heads/master
Commit: ac725cbd90976652970d7ce41029e7b9d8cc1852
Parents: 0f8c21b
Author: Roger Shi <ro...@hotmail.com>
Authored: Mon Jun 26 16:42:13 2017 +0800
Committer: Hongbin Ma <ma...@kyligence.io>
Committed: Mon Jun 26 17:24:29 2017 +0800
----------------------------------------------------------------------
.../main/java/org/apache/kylin/cube/model/AggregationGroup.java | 3 +++
.../java/org/apache/kylin/cube/AggregationGroupRuleTest.java | 5 +++--
2 files changed, 6 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/ac725cbd/core-cube/src/main/java/org/apache/kylin/cube/model/AggregationGroup.java
----------------------------------------------------------------------
diff --git a/core-cube/src/main/java/org/apache/kylin/cube/model/AggregationGroup.java b/core-cube/src/main/java/org/apache/kylin/cube/model/AggregationGroup.java
index be719be..064d657 100644
--- a/core-cube/src/main/java/org/apache/kylin/cube/model/AggregationGroup.java
+++ b/core-cube/src/main/java/org/apache/kylin/cube/model/AggregationGroup.java
@@ -320,6 +320,9 @@ public class AggregationGroup implements Serializable {
normalDims.removeAll(jointDims);
combination = combination * (1L << normalDims.size());
+ if (cubeDesc.getConfig().getCubeAggrGroupIsMandatoryOnlyValid()) {
+ combination += 1;
+ }
combination -= 1; // not include cuboid 0
}
http://git-wip-us.apache.org/repos/asf/kylin/blob/ac725cbd/core-cube/src/test/java/org/apache/kylin/cube/AggregationGroupRuleTest.java
----------------------------------------------------------------------
diff --git a/core-cube/src/test/java/org/apache/kylin/cube/AggregationGroupRuleTest.java b/core-cube/src/test/java/org/apache/kylin/cube/AggregationGroupRuleTest.java
index d81d366..ccc3a98 100644
--- a/core-cube/src/test/java/org/apache/kylin/cube/AggregationGroupRuleTest.java
+++ b/core-cube/src/test/java/org/apache/kylin/cube/AggregationGroupRuleTest.java
@@ -58,6 +58,7 @@ public class AggregationGroupRuleTest extends LocalFileMetadataTestCase {
continue;
}
CubeDesc desc = JsonUtil.readValue(new FileInputStream(f), CubeDesc.class);
+ desc.init(getTestConfig());
ValidateContext vContext = new ValidateContext();
rule.validate(desc, vContext);
vContext.print(System.out);
@@ -101,7 +102,7 @@ public class AggregationGroupRuleTest extends LocalFileMetadataTestCase {
IValidatorRule<CubeDesc> rule = getAggregationGroupRule();
rule.validate(desc, vContext);
vContext.print(System.out);
- assertEquals(0, vContext.getResults().length);
+ assertEquals(1, vContext.getResults().length);
}
@Test
@@ -130,7 +131,7 @@ public class AggregationGroupRuleTest extends LocalFileMetadataTestCase {
IValidatorRule<CubeDesc> rule = getAggregationGroupRule();
rule.validate(desc, vContext);
vContext.print(System.out);
- assertEquals(1, vContext.getResults().length);
+ assertEquals(2, vContext.getResults().length);
assertEquals("Aggregation group 0 joint dimensions has overlap with more than 1 dimensions in same hierarchy: [CATEG_LVL2_NAME, META_CATEG_NAME]", (vContext.getResults()[0].getMessage()));
}
[50/50] kylin git commit: Merge commit
'2f084601b938d6051c0fe02a9fc075be549547f0' into mergekylin
Posted by li...@apache.org.
Merge commit '2f084601b938d6051c0fe02a9fc075be549547f0' into mergekylin
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/69532cd5
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/69532cd5
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/69532cd5
Branch: refs/heads/master
Commit: 69532cd5ff3dc7da9a4670795f1230faa489c389
Parents: a0b7e74 2f08460
Author: Hongbin Ma <ma...@apache.org>
Authored: Thu Jun 29 13:43:13 2017 +0800
Committer: Hongbin Ma <ma...@apache.org>
Committed: Thu Jun 29 13:43:13 2017 +0800
----------------------------------------------------------------------
.../java/org/apache/kylin/job/DeployUtil.java | 118 +++----
.../apache/kylin/common/KylinConfigBase.java | 28 ++
.../java/org/apache/kylin/cube/CubeManager.java | 21 +-
.../kylin/cube/cli/DictionaryGeneratorCLI.java | 10 +-
.../InMemCubeBuilderInputConverter.java | 5 +
.../org/apache/kylin/cube/model/CubeDesc.java | 2 +-
.../apache/kylin/cube/model/RowKeyColDesc.java | 9 +-
.../org/apache/kylin/job/JoinedFlatTable.java | 52 +++-
.../kylin/metadata/model/ISourceAware.java | 1 +
.../kylin/source/ISampleDataDeployer.java | 47 +++
.../java/org/apache/kylin/source/ISource.java | 6 +
.../source/datagen/ModelDataGenerator.java | 7 +-
.../engine/spark/KylinKryoRegistrator.java | 1 +
.../org/apache/kylin/jdbc/KylinConnection.java | 4 +-
.../java/org/apache/kylin/jdbc/DriverTest.java | 10 +
.../kylin/provision/BuildCubeWithEngine.java | 14 +-
.../kylin/source/hive/BeelineHiveClient.java | 2 +-
.../apache/kylin/source/hive/DBConnConf.java | 86 ++++++
.../kylin/source/hive/HiveClientFactory.java | 1 +
.../apache/kylin/source/hive/HiveMRInput.java | 41 ++-
.../kylin/source/hive/HiveMetadataExplorer.java | 78 ++++-
.../apache/kylin/source/hive/HiveSource.java | 17 ++
.../apache/kylin/source/hive/IHiveClient.java | 7 +-
.../org/apache/kylin/source/jdbc/CmdStep.java | 69 +++++
.../apache/kylin/source/jdbc/HiveCmdStep.java | 77 +++++
.../apache/kylin/source/jdbc/JdbcExplorer.java | 305 +++++++++++++++++++
.../kylin/source/jdbc/JdbcHiveMRInput.java | 93 ++++++
.../apache/kylin/source/jdbc/JdbcSource.java | 66 ++++
.../org/apache/kylin/source/jdbc/JdbcTable.java | 67 ++++
.../kylin/source/jdbc/JdbcTableReader.java | 107 +++++++
.../org/apache/kylin/source/jdbc/SqlUtil.java | 107 +++++++
.../apache/kylin/source/kafka/KafkaSource.java | 8 +-
.../kylin/storage/hbase/HBaseResourceStore.java | 7 +-
.../apache/kylin/tool/KylinConfigCLITest.java | 12 +-
webapp/app/js/controllers/modelEdit.js | 5 +-
webapp/app/js/controllers/modelMeasures.js | 33 +-
webapp/app/js/controllers/page.js | 5 +
webapp/app/js/controllers/projects.js | 38 +--
webapp/app/js/controllers/sourceMeta.js | 9 +
webapp/app/js/filters/filter.js | 17 ++
.../cubeDesigner/advanced_settings.html | 2 +-
webapp/app/partials/cubeDesigner/measures.html | 2 +-
webapp/app/partials/cubes/cubes.html | 10 +-
.../app/partials/modelDesigner/data_model.html | 2 +-
.../partials/modelDesigner/model_measures.html | 2 +-
webapp/app/partials/models/model_json_edit.html | 44 +++
webapp/app/partials/models/model_schema.html | 4 +-
webapp/app/partials/models/models_tree.html | 2 +
.../app/partials/projects/project_detail.html | 29 ++
webapp/app/routes.json | 8 +
50 files changed, 1499 insertions(+), 198 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/69532cd5/core-common/src/main/java/org/apache/kylin/common/KylinConfigBase.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/69532cd5/core-cube/src/main/java/org/apache/kylin/cube/CubeManager.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/69532cd5/core-cube/src/main/java/org/apache/kylin/cube/model/CubeDesc.java
----------------------------------------------------------------------
[10/50] kylin git commit: minor, enable job page search by job name
Posted by li...@apache.org.
minor, enable job page search by job name
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/61825893
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/61825893
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/61825893
Branch: refs/heads/master
Commit: 6182589362b0675db28fa494a0664efd4942e6c3
Parents: 1c3329a
Author: Roger Shi <ro...@hotmail.com>
Authored: Fri Jun 16 17:28:27 2017 +0800
Committer: Hongbin Ma <ma...@kyligence.io>
Committed: Fri Jun 16 18:08:41 2017 +0800
----------------------------------------------------------------------
.../kylin/rest/controller/JobController.java | 9 ++-
.../kylin/rest/controller2/JobControllerV2.java | 6 +-
.../apache/kylin/rest/service/CubeService.java | 8 +--
.../apache/kylin/rest/service/JobService.java | 60 +++++++++++++++-----
4 files changed, 58 insertions(+), 25 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/61825893/server-base/src/main/java/org/apache/kylin/rest/controller/JobController.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/controller/JobController.java b/server-base/src/main/java/org/apache/kylin/rest/controller/JobController.java
index 7c9c40d..749c872 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/controller/JobController.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/controller/JobController.java
@@ -72,7 +72,8 @@ public class JobController extends BasicController {
JobTimeFilterEnum timeFilter = JobTimeFilterEnum.getByCode(jobRequest.getTimeFilter());
try {
- jobInstanceList = jobService.searchJobs(jobRequest.getCubeName(), jobRequest.getProjectName(), statusList, jobRequest.getLimit(), jobRequest.getOffset(), timeFilter);
+ jobInstanceList = jobService.searchJobs(jobRequest.getCubeName(), jobRequest.getProjectName(), statusList,
+ jobRequest.getLimit(), jobRequest.getOffset(), timeFilter);
} catch (Exception e) {
logger.error(e.getLocalizedMessage(), e);
throw new InternalErrorException(e);
@@ -106,7 +107,8 @@ public class JobController extends BasicController {
* @return
* @throws IOException
*/
- @RequestMapping(value = "/{jobId}/steps/{stepId}/output", method = { RequestMethod.GET }, produces = { "application/json" })
+ @RequestMapping(value = "/{jobId}/steps/{stepId}/output", method = { RequestMethod.GET }, produces = {
+ "application/json" })
@ResponseBody
public Map<String, String> getStepOutput(@PathVariable String jobId, @PathVariable String stepId) {
Map<String, String> result = new HashMap<String, String>();
@@ -180,7 +182,8 @@ public class JobController extends BasicController {
* @return
* @throws IOException
*/
- @RequestMapping(value = "/{jobId}/steps/{stepId}/rollback", method = { RequestMethod.PUT }, produces = { "application/json" })
+ @RequestMapping(value = "/{jobId}/steps/{stepId}/rollback", method = { RequestMethod.PUT }, produces = {
+ "application/json" })
@ResponseBody
public JobInstance rollback(@PathVariable String jobId, @PathVariable String stepId) {
try {
http://git-wip-us.apache.org/repos/asf/kylin/blob/61825893/server-base/src/main/java/org/apache/kylin/rest/controller2/JobControllerV2.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/controller2/JobControllerV2.java b/server-base/src/main/java/org/apache/kylin/rest/controller2/JobControllerV2.java
index 5554852..f9db6d8 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/controller2/JobControllerV2.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/controller2/JobControllerV2.java
@@ -107,8 +107,8 @@ public class JobControllerV2 extends BasicController {
@RequestMapping(value = "", method = { RequestMethod.GET }, produces = { "application/vnd.apache.kylin-v2+json" })
@ResponseBody
public EnvelopeResponse listV2(@RequestParam(value = "status", required = false) Integer[] status, //
- @RequestParam(value = "timeFilter", required = true) Integer timeFilter, //
- @RequestParam(value = "cubeName", required = false) String cubeName, //
+ @RequestParam(value = "timeFilter") Integer timeFilter, //
+ @RequestParam(value = "jobName", required = false) String jobName, //
@RequestParam(value = "projectName", required = false) String projectName, //
@RequestParam(value = "pageOffset", required = false, defaultValue = "0") Integer pageOffset, //
@RequestParam(value = "pageSize", required = false, defaultValue = "10") Integer pageSize, //
@@ -124,7 +124,7 @@ public class JobControllerV2 extends BasicController {
}
}
- List<JobInstance> jobInstanceList = jobService.searchJobs(cubeName, projectName, statusList,
+ List<JobInstance> jobInstanceList = jobService.searchJobsByJobName(jobName, projectName, statusList,
JobTimeFilterEnum.getByCode(timeFilter));
if (sortby.equals("last_modify")) {
http://git-wip-us.apache.org/repos/asf/kylin/blob/61825893/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 74d8578..7f09612 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
@@ -234,7 +234,7 @@ public class CubeService extends BasicService {
throws IOException {
Message msg = MsgPicker.getMsg();
- final List<CubingJob> cubingJobs = jobService.listAllCubingJobs(cube.getName(), null,
+ final List<CubingJob> cubingJobs = jobService.listJobsByRealizationName(cube.getName(), null,
EnumSet.of(ExecutableState.READY, ExecutableState.RUNNING));
if (!cubingJobs.isEmpty()) {
throw new BadRequestException(String.format(msg.getDISCARD_JOB_FIRST(), cube.getName()));
@@ -266,7 +266,7 @@ public class CubeService extends BasicService {
public void deleteCube(CubeInstance cube) throws IOException {
Message msg = MsgPicker.getMsg();
- final List<CubingJob> cubingJobs = jobService.listAllCubingJobs(cube.getName(), null,
+ final List<CubingJob> cubingJobs = jobService.listJobsByRealizationName(cube.getName(), null,
EnumSet.of(ExecutableState.READY, ExecutableState.RUNNING, ExecutableState.ERROR));
if (!cubingJobs.isEmpty()) {
throw new BadRequestException(String.format(msg.getDISCARD_JOB_FIRST(), cube.getName()));
@@ -361,7 +361,7 @@ public class CubeService extends BasicService {
throw new BadRequestException(String.format(msg.getNO_READY_SEGMENT(), cubeName));
}
- final List<CubingJob> cubingJobs = jobService.listAllCubingJobs(cube.getName(), null,
+ final List<CubingJob> cubingJobs = jobService.listJobsByRealizationName(cube.getName(), null,
EnumSet.of(ExecutableState.READY, ExecutableState.RUNNING));
if (!cubingJobs.isEmpty()) {
throw new BadRequestException(msg.getENABLE_WITH_RUNNING_JOB());
@@ -482,7 +482,7 @@ public class CubeService extends BasicService {
}
protected void releaseAllJobs(CubeInstance cube) {
- final List<CubingJob> cubingJobs = jobService.listAllCubingJobs(cube.getName(), null);
+ final List<CubingJob> cubingJobs = jobService.listJobsByRealizationName(cube.getName(), null);
for (CubingJob cubingJob : cubingJobs) {
final ExecutableState status = cubingJob.getStatus();
if (status != ExecutableState.SUCCEED && status != ExecutableState.DISCARDED) {
http://git-wip-us.apache.org/repos/asf/kylin/blob/61825893/server-base/src/main/java/org/apache/kylin/rest/service/JobService.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/service/JobService.java b/server-base/src/main/java/org/apache/kylin/rest/service/JobService.java
index 3db7fb6..7eb1292 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/service/JobService.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/service/JobService.java
@@ -28,7 +28,10 @@ import java.util.Map;
import java.util.Set;
import java.util.TimeZone;
+import javax.annotation.Nullable;
+
import org.apache.commons.lang3.StringUtils;
+import org.apache.directory.api.util.Strings;
import org.apache.kylin.common.KylinConfig;
import org.apache.kylin.common.util.ClassUtil;
import org.apache.kylin.cube.CubeInstance;
@@ -368,7 +371,7 @@ public class JobService extends BasicService implements InitializingBean {
final JobTimeFilterEnum timeFilter) {
Integer limit = (null == limitValue) ? 30 : limitValue;
Integer offset = (null == offsetValue) ? 0 : offsetValue;
- List<JobInstance> jobs = searchJobs(cubeNameSubstring, projectName, statusList, timeFilter);
+ List<JobInstance> jobs = searchJobsByCubeName(cubeNameSubstring, projectName, statusList, timeFilter);
Collections.sort(jobs);
if (jobs.size() <= offset) {
@@ -382,20 +385,31 @@ public class JobService extends BasicService implements InitializingBean {
return jobs.subList(offset, offset + limit);
}
- public List<JobInstance> searchJobs(final String cubeNameSubstring, final String projectName,
+ public List<JobInstance> searchJobsByCubeName(final String cubeNameSubstring, final String projectName,
+ final List<JobStatusEnum> statusList, final JobTimeFilterEnum timeFilter) {
+ return innerSearchCubingJobs(cubeNameSubstring, null, projectName, statusList, timeFilter);
+ }
+
+ public List<JobInstance> searchJobsByJobName(final String jobName, final String projectName,
final List<JobStatusEnum> statusList, final JobTimeFilterEnum timeFilter) {
+ return innerSearchCubingJobs(null, jobName, projectName, statusList, timeFilter);
+ }
+
+ public List<JobInstance> innerSearchCubingJobs(final String cubeName, final String jobName,
+ final String projectName, final List<JobStatusEnum> statusList, final JobTimeFilterEnum timeFilter) {
+ // prepare time range
Calendar calendar = Calendar.getInstance();
calendar.setTime(new Date());
long timeStartInMillis = getTimeStartInMillis(calendar, timeFilter);
-
long timeEndInMillis = Long.MAX_VALUE;
Set<ExecutableState> states = convertStatusEnumToStates(statusList);
final Map<String, Output> allOutputs = getExecutableManager().getAllOutputs(timeStartInMillis, timeEndInMillis);
+
return Lists
.newArrayList(
FluentIterable
- .from(searchCubingJobs(cubeNameSubstring, projectName, states, timeStartInMillis,
- timeEndInMillis, allOutputs, false))
+ .from(innerSearchCubingJobs(cubeName, jobName, states, timeStartInMillis,
+ timeEndInMillis, allOutputs, false, projectName))
.transform(new Function<CubingJob, JobInstance>() {
@Override
public JobInstance apply(CubingJob cubingJob) {
@@ -404,9 +418,9 @@ public class JobService extends BasicService implements InitializingBean {
}));
}
- public List<CubingJob> searchCubingJobs(final String cubeName, final String projectName,
+ public List<CubingJob> innerSearchCubingJobs(final String cubeName, final String jobName,
final Set<ExecutableState> statusList, long timeStartInMillis, long timeEndInMillis,
- final Map<String, Output> allOutputs, final boolean cubeNameExactMatch) {
+ final Map<String, Output> allOutputs, final boolean nameExactMatch, final String projectName) {
List<CubingJob> results = Lists.newArrayList(FluentIterable.from(
getExecutableManager().getAllAbstractExecutables(timeStartInMillis, timeEndInMillis, CubingJob.class))
.filter(new Predicate<AbstractExecutable>() {
@@ -419,8 +433,8 @@ public class JobService extends BasicService implements InitializingBean {
String executableCubeName = CubingExecutableUtil.getCubeName(executable.getParams());
if (executableCubeName == null)
return true;
- if (cubeNameExactMatch)
- return executableCubeName.equalsIgnoreCase(cubeName);
+ if (nameExactMatch)
+ return executableCubeName.toLowerCase().equals(cubeName);
else
return executableCubeName.toLowerCase().contains(cubeName.toLowerCase());
} else {
@@ -453,19 +467,35 @@ public class JobService extends BasicService implements InitializingBean {
throw e;
}
}
+ }, new Predicate<CubingJob>() {
+ @Override
+ public boolean apply(@Nullable CubingJob cubeJob) {
+ if (cubeJob == null) {
+ return false;
+ }
+
+ if (Strings.isEmpty(jobName)) {
+ return true;
+ }
+
+ if (nameExactMatch) {
+ return cubeJob.getName().toLowerCase().equals(jobName);
+ } else {
+ return cubeJob.getName().toLowerCase().contains(jobName);
+ }
+ }
})));
return results;
}
- public List<CubingJob> listAllCubingJobs(final String cubeName, final String projectName,
+ public List<CubingJob> listJobsByRealizationName(final String realizationName, final String projectName,
final Set<ExecutableState> statusList) {
- return searchCubingJobs(cubeName, projectName, statusList, 0L, Long.MAX_VALUE,
- getExecutableManager().getAllOutputs(), true);
+ return innerSearchCubingJobs(realizationName, null, statusList, 0L, Long.MAX_VALUE,
+ getExecutableManager().getAllOutputs(), true, projectName);
}
- public List<CubingJob> listAllCubingJobs(final String cubeName, final String projectName) {
- return searchCubingJobs(cubeName, projectName, EnumSet.allOf(ExecutableState.class), 0L, Long.MAX_VALUE,
- getExecutableManager().getAllOutputs(), true);
+ public List<CubingJob> listJobsByRealizationName(final String realizationName, final String projectName) {
+ return listJobsByRealizationName(realizationName, projectName, EnumSet.allOf(ExecutableState.class));
}
}
[42/50] kylin git commit: minor, make MODELER ROLE as a group
Posted by li...@apache.org.
minor, make MODELER ROLE as a group
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/f79fa389
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/f79fa389
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/f79fa389
Branch: refs/heads/master
Commit: f79fa389cc4530950a26a2280811c5929d8956e2
Parents: ac725cb
Author: Roger Shi <ro...@hotmail.com>
Authored: Mon Jun 26 20:07:57 2017 +0800
Committer: Hongbin Ma <ma...@kyligence.io>
Committed: Mon Jun 26 20:23:10 2017 +0800
----------------------------------------------------------------------
.../src/main/java/org/apache/kylin/rest/constant/Constant.java | 2 +-
.../src/main/java/org/apache/kylin/rest/service/CubeService.java | 2 +-
.../main/java/org/apache/kylin/rest/service/HybridService.java | 2 +-
.../main/java/org/apache/kylin/rest/service/TableService.java | 4 ++--
4 files changed, 5 insertions(+), 5 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/f79fa389/server-base/src/main/java/org/apache/kylin/rest/constant/Constant.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/constant/Constant.java b/server-base/src/main/java/org/apache/kylin/rest/constant/Constant.java
index f068e5f..5d326e9 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/constant/Constant.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/constant/Constant.java
@@ -35,7 +35,7 @@ public class Constant {
public final static String ROLE_ANALYST = "ROLE_ANALYST";
public final static String ACCESS_HAS_ROLE_ADMIN = "hasRole('ROLE_ADMIN')";
- public final static String ACCESS_HAS_ROLE_MODELER = "hasRole('ROLE_MODELER')";
+// public final static String ACCESS_HAS_ROLE_MODELER = "hasRole('ROLE_MODELER')";
public final static String ACCESS_POST_FILTER_READ = "hasRole('ROLE_ADMIN') or hasPermission(filterObject, 'READ') or hasPermission(filterObject, 'MANAGEMENT') " + "or hasPermission(filterObject, 'OPERATION') or hasPermission(filterObject, 'ADMINISTRATION')";
http://git-wip-us.apache.org/repos/asf/kylin/blob/f79fa389/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 ea5378f..a5fc36a 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
@@ -153,7 +153,7 @@ public class CubeService extends BasicService {
return getCubeManager().updateCube(cubeBuilder);
}
- @PreAuthorize(Constant.ACCESS_HAS_ROLE_ADMIN + " or " + Constant.ACCESS_HAS_ROLE_MODELER)
+ @PreAuthorize(Constant.ACCESS_HAS_ROLE_ADMIN)
public CubeInstance createCubeAndDesc(String cubeName, String projectName, CubeDesc desc) throws IOException {
Message msg = MsgPicker.getMsg();
http://git-wip-us.apache.org/repos/asf/kylin/blob/f79fa389/server-base/src/main/java/org/apache/kylin/rest/service/HybridService.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/service/HybridService.java b/server-base/src/main/java/org/apache/kylin/rest/service/HybridService.java
index acb82b5..b718edf 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/service/HybridService.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/service/HybridService.java
@@ -41,7 +41,7 @@ public class HybridService extends BasicService {
private static final Logger logger = LoggerFactory.getLogger(HybridService.class);
- @PreAuthorize(Constant.ACCESS_HAS_ROLE_ADMIN + " or " + Constant.ACCESS_HAS_ROLE_MODELER)
+ @PreAuthorize(Constant.ACCESS_HAS_ROLE_ADMIN)
public HybridInstance createHybridCube(String hybridName, String projectName, String modelName, String[] cubeNames) {
List<String> args = new ArrayList<String>();
args.add("-name");
http://git-wip-us.apache.org/repos/asf/kylin/blob/f79fa389/server-base/src/main/java/org/apache/kylin/rest/service/TableService.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/service/TableService.java b/server-base/src/main/java/org/apache/kylin/rest/service/TableService.java
index 5cbdb76..915a9be 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/service/TableService.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/service/TableService.java
@@ -353,7 +353,7 @@ public class TableService extends BasicService {
return descs;
}
- @PreAuthorize(Constant.ACCESS_HAS_ROLE_MODELER + " or " + Constant.ACCESS_HAS_ROLE_ADMIN)
+ @PreAuthorize(Constant.ACCESS_HAS_ROLE_ADMIN)
public void calculateCardinalityIfNotPresent(String[] tables, String submitter) throws Exception {
MetadataManager metaMgr = getMetadataManager();
ExecutableManager exeMgt = ExecutableManager.getInstance(getConfig());
@@ -372,7 +372,7 @@ public class TableService extends BasicService {
*
* @param tableName
*/
- @PreAuthorize(Constant.ACCESS_HAS_ROLE_MODELER + " or " + Constant.ACCESS_HAS_ROLE_ADMIN)
+ @PreAuthorize(Constant.ACCESS_HAS_ROLE_ADMIN)
public void calculateCardinality(String tableName, String submitter) throws Exception {
Message msg = MsgPicker.getMsg();
[39/50] kylin git commit: #1358 disable and enable rawtable in cube
controller
Posted by li...@apache.org.
#1358 disable and enable rawtable in cube controller
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/81ff9a48
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/81ff9a48
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/81ff9a48
Branch: refs/heads/master
Commit: 81ff9a488cd94e54d605c74f66a8613010e967fa
Parents: ba7bfd6
Author: Roger Shi <ro...@hotmail.com>
Authored: Fri Jun 23 20:38:55 2017 +0800
Committer: Hongbin Ma <ma...@kyligence.io>
Committed: Fri Jun 23 21:31:32 2017 +0800
----------------------------------------------------------------------
.../rest/controller2/CubeControllerV2.java | 30 --------------------
1 file changed, 30 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/81ff9a48/server-base/src/main/java/org/apache/kylin/rest/controller2/CubeControllerV2.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/controller2/CubeControllerV2.java b/server-base/src/main/java/org/apache/kylin/rest/controller2/CubeControllerV2.java
index 63f2d8e..9ffc062 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/controller2/CubeControllerV2.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/controller2/CubeControllerV2.java
@@ -402,22 +402,6 @@ public class CubeControllerV2 extends BasicController {
submitter);
}
- @RequestMapping(value = "/{cubeName}/disable", method = { RequestMethod.PUT }, produces = {
- "application/vnd.apache.kylin-v2+json" })
- @ResponseBody
- public EnvelopeResponse disableCubeV2(@PathVariable String cubeName) throws IOException {
- Message msg = MsgPicker.getMsg();
-
- CubeInstance cube = cubeService.getCubeManager().getCube(cubeName);
-
- if (cube == null) {
- throw new BadRequestException(String.format(msg.getCUBE_NOT_FOUND(), cubeName));
- }
-
- return new EnvelopeResponse(ResponseCode.CODE_SUCCESS, cubeService.disableCube(cube), "");
-
- }
-
@RequestMapping(value = "/{cubeName}/purge", method = { RequestMethod.PUT }, produces = {
"application/vnd.apache.kylin-v2+json" })
@ResponseBody
@@ -432,20 +416,6 @@ public class CubeControllerV2 extends BasicController {
return new EnvelopeResponse(ResponseCode.CODE_SUCCESS, cubeService.purgeCube(cube), "");
}
- @RequestMapping(value = "/{cubeName}/enable", method = { RequestMethod.PUT }, produces = {
- "application/vnd.apache.kylin-v2+json" })
- @ResponseBody
- public EnvelopeResponse enableCubeV2(@PathVariable String cubeName) throws IOException {
- Message msg = MsgPicker.getMsg();
-
- CubeInstance cube = cubeService.getCubeManager().getCube(cubeName);
- if (cube == null) {
- throw new BadRequestException(String.format(msg.getCUBE_NOT_FOUND(), cubeName));
- }
-
- return new EnvelopeResponse(ResponseCode.CODE_SUCCESS, cubeService.enableCube(cube), "");
- }
-
/**
* get Hbase Info
*
[34/50] kylin git commit: minor, cube draft provides fuzzy search
Posted by li...@apache.org.
minor, cube draft provides fuzzy search
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/c6ade2f0
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/c6ade2f0
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/c6ade2f0
Branch: refs/heads/master
Commit: c6ade2f0385f69bd1be90fd57de5e31cffde5f16
Parents: 3f9d158
Author: Roger Shi <ro...@hotmail.com>
Authored: Thu Jun 22 13:44:00 2017 +0800
Committer: Hongbin Ma <ma...@kyligence.io>
Committed: Fri Jun 23 19:14:31 2017 +0800
----------------------------------------------------------------------
.../apache/kylin/rest/controller2/CubeControllerV2.java | 2 +-
.../kylin/rest/controller2/ProjectControllerV2.java | 2 +-
.../java/org/apache/kylin/rest/service/CubeService.java | 10 ++++++----
3 files changed, 8 insertions(+), 6 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/c6ade2f0/server-base/src/main/java/org/apache/kylin/rest/controller2/CubeControllerV2.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/controller2/CubeControllerV2.java b/server-base/src/main/java/org/apache/kylin/rest/controller2/CubeControllerV2.java
index 93c4d4e..63f2d8e 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/controller2/CubeControllerV2.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/controller2/CubeControllerV2.java
@@ -113,7 +113,7 @@ public class CubeControllerV2 extends BasicController {
}
// draft cubes
- for (Draft d : cubeService.listCubeDrafts(cubeName, modelName, projectName)) {
+ for (Draft d : cubeService.listCubeDrafts(cubeName, modelName, projectName, exactMatch)) {
CubeDesc c = (CubeDesc) d.getEntity();
if (contains(response, c.getName()) == false) {
CubeInstanceResponse r = createCubeInstanceResponseFromDraft(d);
http://git-wip-us.apache.org/repos/asf/kylin/blob/c6ade2f0/server-base/src/main/java/org/apache/kylin/rest/controller2/ProjectControllerV2.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/controller2/ProjectControllerV2.java b/server-base/src/main/java/org/apache/kylin/rest/controller2/ProjectControllerV2.java
index 5a34807..6dea4e3 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/controller2/ProjectControllerV2.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/controller2/ProjectControllerV2.java
@@ -168,7 +168,7 @@ public class ProjectControllerV2 extends BasicController {
private boolean isProjectEmpty(String projectName) throws IOException {
return cubeService.listAllCubes(projectName).isEmpty()
- && cubeService.listCubeDrafts(null, null, projectName).isEmpty()
+ && cubeService.listCubeDrafts(null, null, projectName, true).isEmpty()
&& modelService.listAllModels(null, projectName, false).isEmpty()
&& modelService.listModelDrafts(null, projectName).isEmpty();
}
http://git-wip-us.apache.org/repos/asf/kylin/blob/c6ade2f0/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 f6de877..ea5378f 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
@@ -649,21 +649,23 @@ public class CubeService extends BasicService {
}
public Draft getCubeDraft(String cubeName) throws IOException {
- for (Draft d : listCubeDrafts(cubeName, null, null)) {
+ for (Draft d : listCubeDrafts(cubeName, null, null, true)) {
return d;
}
return null;
}
- public List<Draft> listCubeDrafts(String cubeName, String modelName, String project) throws IOException {
+ public List<Draft> listCubeDrafts(String cubeName, String modelName, String project, boolean exactMatch)
+ throws IOException {
List<Draft> result = new ArrayList<>();
for (Draft d : getDraftManager().list(project)) {
RootPersistentEntity e = d.getEntity();
if (e instanceof CubeDesc) {
CubeDesc c = (CubeDesc) e;
- if ((cubeName == null || cubeName.equals(c.getName()))
- && (modelName == null || modelName.equals(c.getModelName()))) {
+ if ((cubeName == null || (exactMatch && cubeName.toLowerCase().equals(c.getName().toLowerCase()))
+ || (!exactMatch && c.getName().toLowerCase().contains(cubeName.toLowerCase())))
+ && (modelName == null || modelName.toLowerCase().equals(c.getModelName().toLowerCase()))) {
result.add(d);
}
}
[14/50] kylin git commit: minor,
fix empty values of SQLPrepare in odbc driver
Posted by li...@apache.org.
minor, fix empty values of SQLPrepare in odbc driver
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/ea06950a
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/ea06950a
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/ea06950a
Branch: refs/heads/master
Commit: ea06950ae7078ad5c20d334cb14b075868f763b1
Parents: 0ab915d
Author: lidongsjtu <li...@apache.org>
Authored: Sat Jun 17 10:04:57 2017 +0800
Committer: Hongbin Ma <ma...@kyligence.io>
Committed: Mon Jun 19 13:19:29 2017 +0800
----------------------------------------------------------------------
odbc/Common/REST.cpp | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/ea06950a/odbc/Common/REST.cpp
----------------------------------------------------------------------
diff --git a/odbc/Common/REST.cpp b/odbc/Common/REST.cpp
index 8f0c7bb..94e4344 100644
--- a/odbc/Common/REST.cpp
+++ b/odbc/Common/REST.cpp
@@ -133,8 +133,15 @@ void overwrite ( SQLResponse* res )
case ODBCTypes::ODBC_Type_Time :
case ODBCTypes::ODBC_Type_Timestamp :
length = ScanForLength ( res -> results, i );
- meta -> displaySize = length;
- meta -> precision = length;
+ if (length > meta -> displaySize)
+ {
+ meta -> displaySize = length;
+ }
+
+ if (length > meta -> precision)
+ {
+ meta -> precision = length;
+ }
break;
default :
[12/50] kylin git commit: KYLIN-2515 Fix sql convert issue if has the
sql has sub-query
Posted by li...@apache.org.
KYLIN-2515 Fix sql convert issue if has the sql has sub-query
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/70ad90c2
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/70ad90c2
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/70ad90c2
Branch: refs/heads/master
Commit: 70ad90c2d5ee643b2febde1857a55c150eb3d9cf
Parents: 81d2637
Author: nichunen <ch...@kyligence.io>
Authored: Fri Jun 16 21:05:40 2017 +0800
Committer: 成 <ch...@kyligence.io>
Committed: Fri Jun 16 21:26:56 2017 +0800
----------------------------------------------------------------------
.../source/adhocquery/HiveAdhocConverter.java | 84 +++++++++++++++++---
.../adhocquery/HiveAdhocConverterTest.java | 39 ++++++---
2 files changed, 99 insertions(+), 24 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/70ad90c2/core-metadata/src/main/java/org/apache/kylin/source/adhocquery/HiveAdhocConverter.java
----------------------------------------------------------------------
diff --git a/core-metadata/src/main/java/org/apache/kylin/source/adhocquery/HiveAdhocConverter.java b/core-metadata/src/main/java/org/apache/kylin/source/adhocquery/HiveAdhocConverter.java
index 97d77bf..89b2f7a 100644
--- a/core-metadata/src/main/java/org/apache/kylin/source/adhocquery/HiveAdhocConverter.java
+++ b/core-metadata/src/main/java/org/apache/kylin/source/adhocquery/HiveAdhocConverter.java
@@ -26,16 +26,48 @@ import java.util.regex.Pattern;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.google.common.collect.ImmutableSet;
+
//TODO: Some workaround ways to make sql readable by hive parser, should replaced it with a more well-designed way
public class HiveAdhocConverter implements IAdHocConverter {
@SuppressWarnings("unused")
private static final Logger logger = LoggerFactory.getLogger(HiveAdhocConverter.class);
- private static final Pattern EXTRACT_PATTERN = Pattern.compile("\\s+extract\\s*(\\()\\s*(.*?)\\s*from(\\s+)", Pattern.CASE_INSENSITIVE);
- private static final Pattern FROM_PATTERN = Pattern.compile("\\s+from\\s+(\\()\\s*select\\s", Pattern.CASE_INSENSITIVE);
- private static final Pattern CAST_PATTERN = Pattern.compile("CAST\\((.*?) (?i)AS\\s*(.*?)\\s*\\)", Pattern.CASE_INSENSITIVE);
- private static final Pattern CONCAT_PATTERN = Pattern.compile("(['_a-z0-9A-Z]+)\\|\\|(['_a-z0-9A-Z]+)", Pattern.CASE_INSENSITIVE);
+ private static final Pattern EXTRACT_PATTERN = Pattern.compile("extract\\s*(\\()\\s*(.*?)\\s*from(\\s+)",
+ Pattern.CASE_INSENSITIVE);
+ private static final Pattern FROM_PATTERN = Pattern.compile("\\s+from\\s+(\\()\\s*select\\s",
+ Pattern.CASE_INSENSITIVE);
+ private static final Pattern ALIAS_PATTERN = Pattern.compile("\\s+([`'_a-z0-9A-Z]+)", Pattern.CASE_INSENSITIVE);
+ private static final Pattern CAST_PATTERN = Pattern.compile("CAST\\((.*?) (?i)AS\\s*(.*?)\\s*\\)",
+ Pattern.CASE_INSENSITIVE);
+ private static final Pattern CONCAT_PATTERN = Pattern.compile("(['_a-z0-9A-Z]+)\\|\\|(['_a-z0-9A-Z]+)",
+ Pattern.CASE_INSENSITIVE);
+ private static final Pattern TIMESTAMPADD_PATTERN = Pattern.compile("timestampadd\\s*\\(\\s*(.*?)\\s*,",
+ Pattern.CASE_INSENSITIVE);
+ private static final ImmutableSet<String> sqlKeyWordsExceptAS = ImmutableSet.of("ABSOLUTE", "ACTION", "ADD", "ALL",
+ "ALLOCATE", "ALTER", "AND", "ANY", "ARE", "ASC", "ASSERTION", "AT", "AUTHORIZATION", "AVG", "BEGIN",
+ "BETWEEN", "BIT", "BIT_LENGTH", "BOTH", "BY", "CASCADE", "CASCADED", "CASE", "CAST", "CATALOG", "CHAR",
+ "CHARACTER", "CHARACTER_LENGTH", "CHAR_LENGTH", "CHECK", "CLOSE", "COALESCE", "COLLATE", "COLLATION",
+ "COLUMN", "COMMIT", "CONNECT", "CONNECTION", "CONSTRAINT", "CONSTRAINTS", "CONTINUE", "CONVERT",
+ "CORRESPONDING", "COUNT", "CREATE", "CROSS", "CURRENT", "CURRENT_DATE", "CURRENT_TIME", "CURRENT_TIMESTAMP",
+ "CURRENT_USER", "CURSOR", "DATE", "DAY", "DEALLOCATE", "DEC", "DECIMAL", "DECLARE", "DEFAULT", "DEFERRABLE",
+ "DEFERRED", "DELETE", "DESC", "DESCRIBE", "DESCRIPTOR", "DIAGNOSTICS", "DISCONNECT", "DISTINCT", "DOMAIN",
+ "DOUBLE", "DROP", "ELSE", "END", "END-EXEC", "ESCAPE", "EXCEPT", "EXCEPTION", "EXEC", "EXECUTE", "EXISTS",
+ "EXTERNAL", "EXTRACT", "FALSE", "FETCH", "FIRST", "FLOAT", "FOR", "FOREIGN", "FOUND", "FROM", "FULL", "GET",
+ "GLOBAL", "GO", "GOTO", "GRANT", "GROUP", "HAVING", "HOUR", "IDENTITY", "IMMEDIATE", "IN", "INDICATOR",
+ "INITIALLY", "INNER", "INADD", "INSENSITIVE", "INSERT", "INT", "INTEGER", "INTERSECT", "INTERVAL", "INTO",
+ "IS", "ISOLATION", "JOIN", "KEY", "LANGUAGE", "LAST", "LEADING", "LEFT", "LEVEL", "LIKE", "LOCAL", "LOWER",
+ "MATCH", "MAX", "MIN", "MINUTE", "MODULE", "MONTH", "NAMES", "NATIONAL", "NATURAL", "NCHAR", "NEXT", "NO",
+ "NOT", "NULL", "NULLIF", "NUMERIC", "OCTET_LENGTH", "OF", "ON", "ONLY", "OPEN", "OPTION", "OR", "ORDER",
+ "OUTER", "OUTADD", "OVERLAPS", "PAD", "PARTIAL", "POSITION", "PRECISION", "PREPARE", "PRESERVE", "PRIMARY",
+ "PRIOR", "PRIVILEGES", "PROCEDURE", "PUBLIC", "READ", "REAL", "REFERENCES", "RELATIVE", "RESTRICT",
+ "REVOKE", "RIGHT", "ROLLBACK", "ROWS", "SCHEMA", "SCROLL", "SECOND", "SECTION", "SELECT", "SESSION",
+ "SESSION_USER", "SET", "SIZE", "SMALLINT", "SOME", "SPACE", "SQL", "SQLCODE", "SQLERROR", "SQLSTATE",
+ "SUBSTRING", "SUM", "SYSTEM_USER", "TABLE", "TEMPORARY", "THEN", "TIME", "TIMESTAMP", "TIMEZONE_HOUR",
+ "TIMEZONE_MINUTE", "TO", "TRAILING", "TRANSACTION", "TRANSLATE", "TRANSLATION", "TRIM", "TRUE", "UNION",
+ "UNIQUE", "UNKNOWN", "UPDATE", "UPPER", "USAGE", "USER", "USING", "VALUE", "VALUES", "VARCHAR", "VARYING",
+ "VIEW", "WHEN", "WHENEVER", "WHERE", "WITH", "WORK", "WRITE", "YEAR", "ZONE");
public static String replaceString(String originString, String fromString, String toString) {
return originString.replace(fromString, toString);
@@ -55,16 +87,17 @@ public class HiveAdhocConverter implements IAdHocConverter {
int startIdx = extractMatcher.end(3);
int endIdx = parenthesesPairs.get(extractMatcher.start(1));
String extractInner = originString.substring(startIdx, endIdx);
- int originStart = extractMatcher.start(0) + 1;
+ int originStart = extractMatcher.start(0);
int originEnd = endIdx + 1;
- replacedString = replaceString(replacedString, originString.substring(originStart, originEnd), functionStr + "(" + extractInner + ")");
+ replacedString = replaceString(replacedString, originString.substring(originStart, originEnd),
+ functionStr + "(" + extractInner + ")");
}
return replacedString;
}
- public static String castRepalce(String originString) {
+ public static String castReplace(String originString) {
Matcher castMatcher = CAST_PATTERN.matcher(originString);
String replacedString = originString;
@@ -95,7 +128,7 @@ public class HiveAdhocConverter implements IAdHocConverter {
return replacedString;
}
- public static String subqueryRepalce(String originString) {
+ public static String subqueryReplace(String originString) {
Matcher subqueryMatcher = FROM_PATTERN.matcher(originString);
String replacedString = originString;
Map<Integer, Integer> parenthesesPairs = null;
@@ -108,7 +141,30 @@ public class HiveAdhocConverter implements IAdHocConverter {
int startIdx = subqueryMatcher.start(1);
int endIdx = parenthesesPairs.get(startIdx) + 1;
- replacedString = replaceString(replacedString, originString.substring(startIdx, endIdx), originString.substring(startIdx, endIdx) + " as alias");
+ Matcher aliasMatcher = ALIAS_PATTERN.matcher(originString.substring(endIdx));
+ if (aliasMatcher.find()) {
+ String aliasCandidate = aliasMatcher.group(1);
+
+ if (aliasCandidate != null && !sqlKeyWordsExceptAS.contains(aliasCandidate.toUpperCase())) {
+ continue;
+ }
+
+ replacedString = replaceString(replacedString, originString.substring(startIdx, endIdx),
+ originString.substring(startIdx, endIdx) + " as alias");
+ }
+ }
+
+ return replacedString;
+ }
+
+ public static String timestampaddReplace(String originString) {
+ Matcher timestampaddMatcher = TIMESTAMPADD_PATTERN.matcher(originString);
+ String replacedString = originString;
+
+ while (timestampaddMatcher.find()) {
+ String interval = timestampaddMatcher.group(1);
+ String timestampaddStr = replaceString(timestampaddMatcher.group(), interval, "'" + interval + "'");
+ replacedString = replaceString(replacedString, timestampaddMatcher.group(), timestampaddStr);
}
return replacedString;
@@ -121,7 +177,8 @@ public class HiveAdhocConverter implements IAdHocConverter {
while (concatMatcher.find()) {
String leftString = concatMatcher.group(1);
String rightString = concatMatcher.group(2);
- replacedString = replaceString(replacedString, leftString + "||" + rightString, "concat(" + leftString + "," + rightString + ")");
+ replacedString = replaceString(replacedString, leftString + "||" + rightString,
+ "concat(" + leftString + "," + rightString + ")");
}
return replacedString;
@@ -135,10 +192,10 @@ public class HiveAdhocConverter implements IAdHocConverter {
convertedSql = extractReplace(convertedSql);
// Step3.Replace cast type string
- convertedSql = castRepalce(convertedSql);
+ convertedSql = castReplace(convertedSql);
// Step4.Replace sub query
- convertedSql = subqueryRepalce(convertedSql);
+ convertedSql = subqueryReplace(convertedSql);
// Step5.Replace char_length with length
convertedSql = replaceString(convertedSql, "char_length", "length");
@@ -146,6 +203,9 @@ public class HiveAdhocConverter implements IAdHocConverter {
// Step6.Replace "||" with concat
convertedSql = concatReplace(convertedSql);
+ // Step7.Add quote for interval in timestampadd
+ convertedSql = timestampaddReplace(convertedSql);
+
return convertedSql;
}
http://git-wip-us.apache.org/repos/asf/kylin/blob/70ad90c2/core-metadata/src/test/java/org/apache/kylin/source/adhocquery/HiveAdhocConverterTest.java
----------------------------------------------------------------------
diff --git a/core-metadata/src/test/java/org/apache/kylin/source/adhocquery/HiveAdhocConverterTest.java b/core-metadata/src/test/java/org/apache/kylin/source/adhocquery/HiveAdhocConverterTest.java
index 85a6d61..cfb0f32 100644
--- a/core-metadata/src/test/java/org/apache/kylin/source/adhocquery/HiveAdhocConverterTest.java
+++ b/core-metadata/src/test/java/org/apache/kylin/source/adhocquery/HiveAdhocConverterTest.java
@@ -22,42 +22,57 @@ import org.junit.Test;
import junit.framework.TestCase;
-
public class HiveAdhocConverterTest extends TestCase {
@Test
- public void testSringReplace() {
+ public void testStringReplace() {
String originString = "select count(*) as cnt from test_kylin_fact where char_length(lstg_format_name) < 10";
- String replacedString = HiveAdhocConverter
- .replaceString(originString, "char_length", "length");
- assertEquals(replacedString, "select count(*) as cnt from test_kylin_fact where length(lstg_format_name) < 10");
+ String replacedString = HiveAdhocConverter.replaceString(originString, "char_length", "length");
+ assertEquals("select count(*) as cnt from test_kylin_fact where length(lstg_format_name) < 10", replacedString);
}
@Test
public void testExtractReplace() {
String originString = "ignore EXTRACT(YEAR FROM KYLIN_CAL_DT.CAL_DT) ignore";
String replacedString = HiveAdhocConverter.extractReplace(originString);
- assertEquals(replacedString, "ignore YEAR(KYLIN_CAL_DT.CAL_DT) ignore");
+ assertEquals("ignore YEAR(KYLIN_CAL_DT.CAL_DT) ignore", replacedString);
}
@Test
public void testCastReplace() {
String originString = "ignore EXTRACT(YEAR FROM CAST(KYLIN_CAL_DT.CAL_DT AS INTEGER)) ignore";
- String replacedString = HiveAdhocConverter.castRepalce(originString);
- assertEquals(replacedString, "ignore EXTRACT(YEAR FROM CAST(KYLIN_CAL_DT.CAL_DT AS int)) ignore");
+ String replacedString = HiveAdhocConverter.castReplace(originString);
+ assertEquals("ignore EXTRACT(YEAR FROM CAST(KYLIN_CAL_DT.CAL_DT AS int)) ignore", replacedString);
}
@Test
- public void testSubqueryReplace() {
+ public void testSubqueryReplace1() {
String originString = "select seller_id,lstg_format_name,sum(price) from (select * from test_kylin_fact where (lstg_format_name='FP-GTC') limit 20) group by seller_id,lstg_format_name";
- String replacedString = HiveAdhocConverter.subqueryRepalce(originString);
- assertEquals(replacedString, "select seller_id,lstg_format_name,sum(price) from (select * from test_kylin_fact where (lstg_format_name='FP-GTC') limit 20) as alias group by seller_id,lstg_format_name");
+ String replacedString = HiveAdhocConverter.subqueryReplace(originString);
+ assertEquals(
+ "select seller_id,lstg_format_name,sum(price) from (select * from test_kylin_fact where (lstg_format_name='FP-GTC') limit 20) as alias group by seller_id,lstg_format_name",
+ replacedString);
+ }
+
+ @Test
+ public void testSubqueryReplace2() {
+ String originString = "select count(*) from ( select test_kylin_fact.lstg_format_name from test_kylin_fact where test_kylin_fact.lstg_format_name='FP-GTC' group by test_kylin_fact.lstg_format_name ) t ";
+ String replacedString = HiveAdhocConverter.subqueryReplace(originString);
+ assertEquals(originString, replacedString);
+ }
+
+ @Test
+ public void testSubqueryReplace3() {
+ String originString = "select fact.lstg_format_name from (select * from test_kylin_fact where cal_dt > date'2010-01-01' ) as fact group by fact.lstg_format_name order by CASE WHEN fact.lstg_format_name IS NULL THEN 'sdf' ELSE fact.lstg_format_name END ";
+ String replacedString = HiveAdhocConverter.subqueryReplace(originString);
+ assertEquals(originString, replacedString);
}
@Test
public void testConcatReplace() {
String originString = "select count(*) as cnt from test_kylin_fact where lstg_format_name||'a'='ABINa'";
String replacedString = HiveAdhocConverter.concatReplace(originString);
- assertEquals(replacedString, "select count(*) as cnt from test_kylin_fact where concat(lstg_format_name,'a')='ABINa'");
+ assertEquals("select count(*) as cnt from test_kylin_fact where concat(lstg_format_name,'a')='ABINa'",
+ replacedString);
}
}
[26/50] kylin git commit: Rename stats intermediate table name and
make them droppable (#1267)
Posted by li...@apache.org.
Rename stats intermediate table name and make them droppable (#1267)
* minor, enhance StorageCleanup tool
* #1100, rename stats intermediate table
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/bf871691
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/bf871691
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/bf871691
Branch: refs/heads/master
Commit: bf8716919aaf6bf3880b12fc347aa04d98c6dc83
Parents: 1e38694
Author: 成 <ch...@kyligence.io>
Authored: Wed Jun 21 12:53:52 2017 +0800
Committer: Billy(Yiming) Liu <li...@gmail.com>
Committed: Wed Jun 21 12:53:52 2017 +0800
----------------------------------------------------------------------
.../kylin/engine/mr/common/BatchConstants.java | 3 +-
.../kylin/rest/job/StorageCleanupJob.java | 63 ++++++++++++--------
2 files changed, 40 insertions(+), 26 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/bf871691/engine-mr/src/main/java/org/apache/kylin/engine/mr/common/BatchConstants.java
----------------------------------------------------------------------
diff --git a/engine-mr/src/main/java/org/apache/kylin/engine/mr/common/BatchConstants.java b/engine-mr/src/main/java/org/apache/kylin/engine/mr/common/BatchConstants.java
index 602b4bb..0cb23ac 100644
--- a/engine-mr/src/main/java/org/apache/kylin/engine/mr/common/BatchConstants.java
+++ b/engine-mr/src/main/java/org/apache/kylin/engine/mr/common/BatchConstants.java
@@ -45,6 +45,8 @@ public interface BatchConstants {
String CFG_REGION_NUMBER_MAX = "region.number.max";
String CFG_REGION_SPLIT_SIZE = "region.split.size";
String CFG_HFILE_SIZE_GB = "hfile.size.gb";
+ String CFG_STATS_JOB_ID = "stats.job.id";
+ String CFG_STATS_JOB_FREQUENCY = "stats.sample.frequency";
String CFG_KYLIN_LOCAL_TEMP_DIR = "/tmp/kylin/";
String CFG_KYLIN_HDFS_TEMP_DIR = "/tmp/kylin/";
@@ -62,7 +64,6 @@ public interface BatchConstants {
String CFG_OUTPUT_STATISTICS = "statistics";
String CFG_OUTPUT_PARTITION = "partition";
-
/**
* command line ARGuments
*/
http://git-wip-us.apache.org/repos/asf/kylin/blob/bf871691/server-base/src/main/java/org/apache/kylin/rest/job/StorageCleanupJob.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/job/StorageCleanupJob.java b/server-base/src/main/java/org/apache/kylin/rest/job/StorageCleanupJob.java
index 448e3c6..9b72788 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/job/StorageCleanupJob.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/job/StorageCleanupJob.java
@@ -60,15 +60,18 @@ import com.google.common.collect.Maps;
public class StorageCleanupJob extends AbstractApplication {
@SuppressWarnings("static-access")
- protected static final Option OPTION_DELETE = OptionBuilder.withArgName("delete").hasArg().isRequired(false).withDescription("Delete the unused storage").create("delete");
- protected static final Option OPTION_FORCE = OptionBuilder.withArgName("force").hasArg().isRequired(false).withDescription("Warning: will delete all kylin intermediate hive tables").create("force");
+ protected static final Option OPTION_DELETE = OptionBuilder.withArgName("delete").hasArg().isRequired(false)
+ .withDescription("Delete the unused storage").create("delete");
+ protected static final Option OPTION_FORCE = OptionBuilder.withArgName("force").hasArg().isRequired(false)
+ .withDescription("Warning: will delete all kylin intermediate hive tables").create("force");
protected static final Logger logger = LoggerFactory.getLogger(StorageCleanupJob.class);
public static final int deleteTimeout = 10; // Unit minute
protected boolean delete = false;
protected boolean force = false;
- protected static ExecutableManager executableManager = ExecutableManager.getInstance(KylinConfig.getInstanceFromEnv());
+ protected static ExecutableManager executableManager = ExecutableManager
+ .getInstance(KylinConfig.getInstanceFromEnv());
protected void cleanUnusedHBaseTables() throws IOException {
KylinConfig config = KylinConfig.getInstanceFromEnv();
@@ -76,7 +79,8 @@ public class StorageCleanupJob extends AbstractApplication {
try {
// use reflection to isolate NoClassDef errors when HBase is not available
Class hbaseCleanUpUtil = Class.forName("org.apache.kylin.rest.job.StorageCleanJobHbaseUtil");
- Method cleanUnusedHBaseTables = hbaseCleanUpUtil.getDeclaredMethod("cleanUnusedHBaseTables", boolean.class, int.class);
+ Method cleanUnusedHBaseTables = hbaseCleanUpUtil.getDeclaredMethod("cleanUnusedHBaseTables",
+ boolean.class, int.class);
cleanUnusedHBaseTables.invoke(hbaseCleanUpUtil, delete, deleteTimeout);
} catch (Throwable e) {
throw new IOException(e);
@@ -132,7 +136,8 @@ public class StorageCleanupJob extends AbstractApplication {
if (!state.isFinalState()) {
String path = JobBuilderSupport.getJobWorkingDir(engineConfig.getHdfsWorkingDirectory(), jobId);
allHdfsPathsNeedToBeDeleted.remove(path);
- logger.info("Skip " + path + " from deletion list, as the path belongs to job " + jobId + " with status " + state);
+ logger.info("Skip " + path + " from deletion list, as the path belongs to job " + jobId
+ + " with status " + state);
}
}
@@ -143,7 +148,8 @@ public class StorageCleanupJob extends AbstractApplication {
if (jobUuid != null && jobUuid.equals("") == false) {
String path = JobBuilderSupport.getJobWorkingDir(engineConfig.getHdfsWorkingDirectory(), jobUuid);
allHdfsPathsNeedToBeDeleted.remove(path);
- logger.info("Skip " + path + " from deletion list, as the path belongs to segment " + seg + " of cube " + cube.getName());
+ logger.info("Skip " + path + " from deletion list, as the path belongs to segment " + seg
+ + " of cube " + cube.getName());
}
}
}
@@ -227,22 +233,25 @@ public class StorageCleanupJob extends AbstractApplication {
boolean isNeedDel = true;
- if (line.length() > preFix.length() + uuidLength) {
- String uuid = line.substring(line.length() - uuidLength, line.length());
- uuid = uuid.replace("_", "-");
- final Pattern UUId_PATTERN = Pattern.compile(uuidPattern);
- if (UUId_PATTERN.matcher(uuid).matches()) {
- //Check whether it's a hive table in use
- if (isTableInUse(uuid, workingJobList)) {
- logger.info("Skip deleting because the table is in use");
- isNeedDel = false;
- }
- } else {
- logger.info("Skip deleting because not match pattern");
- isNeedDel = false;
- }
- } else {
- logger.info("Skip deleting because length not qualified");
+ if (line.length() < preFix.length() + uuidLength) {
+ logger.info("Skip deleting because length is not qualified");
+ continue;
+ }
+
+ String uuid = line.substring(line.length() - uuidLength, line.length());
+ uuid = uuid.replace("_", "-");
+ final Pattern UUID_PATTERN = Pattern.compile(uuidPattern);
+
+ if (!UUID_PATTERN.matcher(uuid).matches()) {
+ logger.info("Skip deleting because pattern doesn't match");
+ continue;
+ }
+
+ //Some intermediate table ends with job's uuid
+ if (allJobs.contains(uuid)) {
+ isNeedDel = !workingJobList.contains(uuid);
+ } else if (isTableInUse(uuid, workingJobList)) {
+ logger.info("Skip deleting because the table is in use");
isNeedDel = false;
}
@@ -270,17 +279,21 @@ public class StorageCleanupJob extends AbstractApplication {
String segmentId = uuid.replace("_", "-");
if (segmentId2JobId.containsKey(segmentId)) {
- String path = JobBuilderSupport.getJobWorkingDir(engineConfig.getHdfsWorkingDirectory(), segmentId2JobId.get(segmentId)) + "/" + tableToDelete;
+ String path = JobBuilderSupport.getJobWorkingDir(engineConfig.getHdfsWorkingDirectory(),
+ segmentId2JobId.get(segmentId)) + "/" + tableToDelete;
Path externalDataPath = new Path(path);
FileSystem fs = HadoopUtil.getWorkingFileSystem();
if (fs.exists(externalDataPath)) {
fs.delete(externalDataPath, true);
logger.info("Hive table {}'s external path {} deleted", tableToDelete, path);
} else {
- logger.info("Hive table {}'s external path {} not exist. It's normal if kylin.source.hive.keep-flat-table set false (By default)", tableToDelete, path);
+ logger.info(
+ "Hive table {}'s external path {} not exist. It's normal if kylin.source.hive.keep-flat-table set false (By default)",
+ tableToDelete, path);
}
} else {
- logger.warn("Hive table {}'s job ID not found, segmentId2JobId: {}", tableToDelete, segmentId2JobId.toString());
+ logger.warn("Hive table {}'s job ID not found, segmentId2JobId: {}", tableToDelete,
+ segmentId2JobId.toString());
}
}
} catch (IOException e) {
[31/50] kylin git commit: #1251 move curator-x-discovery dependency
to ext (out of tomcat classloader)
Posted by li...@apache.org.
#1251 move curator-x-discovery dependency to ext (out of tomcat classloader)
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/401bb0a4
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/401bb0a4
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/401bb0a4
Branch: refs/heads/master
Commit: 401bb0a466cc3618d6801937d076f05b818d31f4
Parents: cf2f27a
Author: Hongbin Ma <ma...@apache.org>
Authored: Thu Jun 22 17:08:11 2017 +0800
Committer: Dong Li <li...@apache.org>
Committed: Thu Jun 22 18:31:21 2017 +0800
----------------------------------------------------------------------
build/script/compress.sh | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/401bb0a4/build/script/compress.sh
----------------------------------------------------------------------
diff --git a/build/script/compress.sh b/build/script/compress.sh
index a72f2f2..cc94f47 100755
--- a/build/script/compress.sh
+++ b/build/script/compress.sh
@@ -34,8 +34,8 @@ package_name=apache-kylin-${version}-bin
cd build/
rm -rf ${package_name}
mkdir ${package_name}
-cp -r lib tool bin conf tomcat spark ../examples/sample_cube commit_SHA1 ${package_name}
-rm -rf lib tomcat spark commit_SHA1
+cp -r ext lib tool bin conf tomcat spark ../examples/sample_cube commit_SHA1 ${package_name}
+rm -rf ext lib tomcat spark commit_SHA1
## comment all default properties, and append them to the user visible kylin.properties
## first 16 lines are license, just skip them
[05/50] kylin git commit: KYLIN-2671 Speed up prepared query execution
Posted by li...@apache.org.
KYLIN-2671 Speed up prepared query execution
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/56e9fb9e
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/56e9fb9e
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/56e9fb9e
Branch: refs/heads/master
Commit: 56e9fb9e9fa45e9bfb93dd1f4fd0a1027b539c7a
Parents: 1b58373
Author: Hongbin Ma <ma...@apache.org>
Authored: Thu Jun 15 17:52:22 2017 +0800
Committer: liyang-gmt8 <li...@apache.org>
Committed: Thu Jun 15 18:18:45 2017 +0800
----------------------------------------------------------------------
.../calcite/prepare/CalcitePrepareImpl.java | 1500 ++++++++++++++++++
.../prepare/OnlyPrepareEarlyAbortException.java | 40 +
.../kylin/rest/controller/QueryController.java | 9 +-
.../apache/kylin/rest/service/QueryService.java | 108 +-
4 files changed, 1623 insertions(+), 34 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/56e9fb9e/atopcalcite/src/main/java/org/apache/calcite/prepare/CalcitePrepareImpl.java
----------------------------------------------------------------------
diff --git a/atopcalcite/src/main/java/org/apache/calcite/prepare/CalcitePrepareImpl.java b/atopcalcite/src/main/java/org/apache/calcite/prepare/CalcitePrepareImpl.java
new file mode 100644
index 0000000..50939b3
--- /dev/null
+++ b/atopcalcite/src/main/java/org/apache/calcite/prepare/CalcitePrepareImpl.java
@@ -0,0 +1,1500 @@
+/*
+ * 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.calcite.prepare;
+
+import org.apache.calcite.DataContext;
+import org.apache.calcite.adapter.enumerable.EnumerableBindable;
+import org.apache.calcite.adapter.enumerable.EnumerableCalc;
+import org.apache.calcite.adapter.enumerable.EnumerableConvention;
+import org.apache.calcite.adapter.enumerable.EnumerableInterpretable;
+import org.apache.calcite.adapter.enumerable.EnumerableInterpreterRule;
+import org.apache.calcite.adapter.enumerable.EnumerableRel;
+import org.apache.calcite.adapter.enumerable.EnumerableRules;
+import org.apache.calcite.adapter.enumerable.RexToLixTranslator;
+import org.apache.calcite.adapter.java.JavaTypeFactory;
+import org.apache.calcite.avatica.AvaticaParameter;
+import org.apache.calcite.avatica.ColumnMetaData;
+import org.apache.calcite.avatica.Meta;
+import org.apache.calcite.config.CalciteConnectionConfig;
+import org.apache.calcite.interpreter.BindableConvention;
+import org.apache.calcite.interpreter.Bindables;
+import org.apache.calcite.interpreter.Interpreters;
+import org.apache.calcite.jdbc.CalcitePrepare;
+import org.apache.calcite.jdbc.CalciteSchema;
+import org.apache.calcite.jdbc.CalciteSchema.LatticeEntry;
+import org.apache.calcite.linq4j.Enumerable;
+import org.apache.calcite.linq4j.Linq4j;
+import org.apache.calcite.linq4j.Ord;
+import org.apache.calcite.linq4j.Queryable;
+import org.apache.calcite.linq4j.function.Function1;
+import org.apache.calcite.linq4j.tree.BinaryExpression;
+import org.apache.calcite.linq4j.tree.BlockStatement;
+import org.apache.calcite.linq4j.tree.Blocks;
+import org.apache.calcite.linq4j.tree.ConstantExpression;
+import org.apache.calcite.linq4j.tree.Expression;
+import org.apache.calcite.linq4j.tree.Expressions;
+import org.apache.calcite.linq4j.tree.MemberExpression;
+import org.apache.calcite.linq4j.tree.MethodCallExpression;
+import org.apache.calcite.linq4j.tree.NewExpression;
+import org.apache.calcite.linq4j.tree.ParameterExpression;
+import org.apache.calcite.materialize.MaterializationService;
+import org.apache.calcite.plan.Contexts;
+import org.apache.calcite.plan.Convention;
+import org.apache.calcite.plan.ConventionTraitDef;
+import org.apache.calcite.plan.RelOptCluster;
+import org.apache.calcite.plan.RelOptCostFactory;
+import org.apache.calcite.plan.RelOptPlanner;
+import org.apache.calcite.plan.RelOptRule;
+import org.apache.calcite.plan.RelOptTable;
+import org.apache.calcite.plan.RelOptUtil;
+import org.apache.calcite.plan.hep.HepPlanner;
+import org.apache.calcite.plan.hep.HepProgramBuilder;
+import org.apache.calcite.plan.volcano.VolcanoPlanner;
+import org.apache.calcite.rel.RelCollation;
+import org.apache.calcite.rel.RelCollationTraitDef;
+import org.apache.calcite.rel.RelCollations;
+import org.apache.calcite.rel.RelNode;
+import org.apache.calcite.rel.RelRoot;
+import org.apache.calcite.rel.core.Filter;
+import org.apache.calcite.rel.core.Project;
+import org.apache.calcite.rel.core.Sort;
+import org.apache.calcite.rel.core.TableScan;
+import org.apache.calcite.rel.rules.AggregateExpandDistinctAggregatesRule;
+import org.apache.calcite.rel.rules.AggregateReduceFunctionsRule;
+import org.apache.calcite.rel.rules.AggregateStarTableRule;
+import org.apache.calcite.rel.rules.AggregateValuesRule;
+import org.apache.calcite.rel.rules.FilterAggregateTransposeRule;
+import org.apache.calcite.rel.rules.FilterJoinRule;
+import org.apache.calcite.rel.rules.FilterProjectTransposeRule;
+import org.apache.calcite.rel.rules.FilterTableScanRule;
+import org.apache.calcite.rel.rules.JoinAssociateRule;
+import org.apache.calcite.rel.rules.JoinCommuteRule;
+import org.apache.calcite.rel.rules.JoinPushExpressionsRule;
+import org.apache.calcite.rel.rules.JoinPushThroughJoinRule;
+import org.apache.calcite.rel.rules.MaterializedViewFilterScanRule;
+import org.apache.calcite.rel.rules.ProjectFilterTransposeRule;
+import org.apache.calcite.rel.rules.ProjectMergeRule;
+import org.apache.calcite.rel.rules.ProjectTableScanRule;
+import org.apache.calcite.rel.rules.ProjectWindowTransposeRule;
+import org.apache.calcite.rel.rules.ReduceExpressionsRule;
+import org.apache.calcite.rel.rules.SortJoinTransposeRule;
+import org.apache.calcite.rel.rules.SortProjectTransposeRule;
+import org.apache.calcite.rel.rules.SortUnionTransposeRule;
+import org.apache.calcite.rel.rules.TableScanRule;
+import org.apache.calcite.rel.rules.ValuesReduceRule;
+import org.apache.calcite.rel.stream.StreamRules;
+import org.apache.calcite.rel.type.RelDataType;
+import org.apache.calcite.rel.type.RelDataTypeFactory;
+import org.apache.calcite.rel.type.RelDataTypeField;
+import org.apache.calcite.rex.RexBuilder;
+import org.apache.calcite.rex.RexInputRef;
+import org.apache.calcite.rex.RexNode;
+import org.apache.calcite.rex.RexProgram;
+import org.apache.calcite.runtime.Bindable;
+import org.apache.calcite.runtime.Hook;
+import org.apache.calcite.runtime.Typed;
+import org.apache.calcite.schema.Schemas;
+import org.apache.calcite.schema.Table;
+import org.apache.calcite.server.CalciteServerStatement;
+import org.apache.calcite.sql.SqlBinaryOperator;
+import org.apache.calcite.sql.SqlExecutableStatement;
+import org.apache.calcite.sql.SqlExplainFormat;
+import org.apache.calcite.sql.SqlExplainLevel;
+import org.apache.calcite.sql.SqlKind;
+import org.apache.calcite.sql.SqlNode;
+import org.apache.calcite.sql.SqlOperator;
+import org.apache.calcite.sql.SqlOperatorTable;
+import org.apache.calcite.sql.SqlUtil;
+import org.apache.calcite.sql.fun.SqlStdOperatorTable;
+import org.apache.calcite.sql.parser.SqlParseException;
+import org.apache.calcite.sql.parser.SqlParser;
+import org.apache.calcite.sql.parser.SqlParserImplFactory;
+import org.apache.calcite.sql.type.SqlTypeName;
+import org.apache.calcite.sql.util.ChainedSqlOperatorTable;
+import org.apache.calcite.sql.validate.SqlConformance;
+import org.apache.calcite.sql.validate.SqlValidator;
+import org.apache.calcite.sql2rel.SqlRexConvertletTable;
+import org.apache.calcite.sql2rel.SqlToRelConverter;
+import org.apache.calcite.sql2rel.StandardConvertletTable;
+import org.apache.calcite.tools.Frameworks;
+import org.apache.calcite.util.ImmutableIntList;
+import org.apache.calcite.util.Pair;
+import org.apache.calcite.util.Util;
+
+import com.google.common.base.Supplier;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Maps;
+
+import java.lang.reflect.Type;
+import java.math.BigDecimal;
+import java.sql.DatabaseMetaData;
+import java.sql.Types;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import static org.apache.calcite.util.Static.RESOURCE;
+
+/*
+ * OVERRIDE POINT:
+ * - grep KYLIN_ONLY_PREPARE
+ */
+/**
+ * Shit just got real.
+ *
+ * <p>This class is public so that projects that create their own JDBC driver
+ * and server can fine-tune preferences. However, this class and its methods are
+ * subject to change without notice.</p>
+ */
+public class CalcitePrepareImpl implements CalcitePrepare {
+
+ public static final ThreadLocal<Boolean> KYLIN_ONLY_PREPARE = new ThreadLocal<>();
+
+ public static final boolean DEBUG = Util.getBooleanProperty("calcite.debug");
+
+ public static final boolean COMMUTE =
+ Util.getBooleanProperty("calcite.enable.join.commute");
+
+ /** Whether to enable the collation trait. Some extra optimizations are
+ * possible if enabled, but queries should work either way. At some point
+ * this will become a preference, or we will run multiple phases: first
+ * disabled, then enabled. */
+ private static final boolean ENABLE_COLLATION_TRAIT = true;
+
+ /** Whether the bindable convention should be the root convention of any
+ * plan. If not, enumerable convention is the default. */
+ public final boolean enableBindable = Hook.ENABLE_BINDABLE.get(false);
+
+ /** Whether the enumerable convention is enabled. */
+ public static final boolean ENABLE_ENUMERABLE = true;
+
+ /** Whether the streaming is enabled. */
+ public static final boolean ENABLE_STREAM = true;
+
+ private static final Set<String> SIMPLE_SQLS =
+ ImmutableSet.of(
+ "SELECT 1",
+ "select 1",
+ "SELECT 1 FROM DUAL",
+ "select 1 from dual",
+ "values 1",
+ "VALUES 1");
+
+ public static final List<RelOptRule> ENUMERABLE_RULES =
+ ImmutableList.of(
+ EnumerableRules.ENUMERABLE_JOIN_RULE,
+ EnumerableRules.ENUMERABLE_MERGE_JOIN_RULE,
+ EnumerableRules.ENUMERABLE_SEMI_JOIN_RULE,
+ EnumerableRules.ENUMERABLE_CORRELATE_RULE,
+ EnumerableRules.ENUMERABLE_PROJECT_RULE,
+ EnumerableRules.ENUMERABLE_FILTER_RULE,
+ EnumerableRules.ENUMERABLE_AGGREGATE_RULE,
+ EnumerableRules.ENUMERABLE_SORT_RULE,
+ EnumerableRules.ENUMERABLE_LIMIT_RULE,
+ EnumerableRules.ENUMERABLE_COLLECT_RULE,
+ EnumerableRules.ENUMERABLE_UNCOLLECT_RULE,
+ EnumerableRules.ENUMERABLE_UNION_RULE,
+ EnumerableRules.ENUMERABLE_INTERSECT_RULE,
+ EnumerableRules.ENUMERABLE_MINUS_RULE,
+ EnumerableRules.ENUMERABLE_TABLE_MODIFICATION_RULE,
+ EnumerableRules.ENUMERABLE_VALUES_RULE,
+ EnumerableRules.ENUMERABLE_WINDOW_RULE,
+ EnumerableRules.ENUMERABLE_TABLE_SCAN_RULE,
+ EnumerableRules.ENUMERABLE_TABLE_FUNCTION_SCAN_RULE);
+
+ private static final List<RelOptRule> DEFAULT_RULES =
+ ImmutableList.of(
+ AggregateStarTableRule.INSTANCE,
+ AggregateStarTableRule.INSTANCE2,
+ TableScanRule.INSTANCE,
+ COMMUTE
+ ? JoinAssociateRule.INSTANCE
+ : ProjectMergeRule.INSTANCE,
+ FilterTableScanRule.INSTANCE,
+ ProjectFilterTransposeRule.INSTANCE,
+ FilterProjectTransposeRule.INSTANCE,
+ FilterJoinRule.FILTER_ON_JOIN,
+ JoinPushExpressionsRule.INSTANCE,
+ AggregateExpandDistinctAggregatesRule.INSTANCE,
+ AggregateReduceFunctionsRule.INSTANCE,
+ FilterAggregateTransposeRule.INSTANCE,
+ ProjectWindowTransposeRule.INSTANCE,
+ JoinCommuteRule.INSTANCE,
+ JoinPushThroughJoinRule.RIGHT,
+ JoinPushThroughJoinRule.LEFT,
+ SortProjectTransposeRule.INSTANCE,
+ SortJoinTransposeRule.INSTANCE,
+ SortUnionTransposeRule.INSTANCE);
+
+ private static final List<RelOptRule> CONSTANT_REDUCTION_RULES =
+ ImmutableList.of(
+ ReduceExpressionsRule.PROJECT_INSTANCE,
+ ReduceExpressionsRule.FILTER_INSTANCE,
+ ReduceExpressionsRule.CALC_INSTANCE,
+ ReduceExpressionsRule.JOIN_INSTANCE,
+ ValuesReduceRule.FILTER_INSTANCE,
+ ValuesReduceRule.PROJECT_FILTER_INSTANCE,
+ ValuesReduceRule.PROJECT_INSTANCE,
+ AggregateValuesRule.INSTANCE);
+
+ public CalcitePrepareImpl() {
+ }
+
+ public ParseResult parse(
+ Context context, String sql) {
+ return parse_(context, sql, false, false, false);
+ }
+
+ public ConvertResult convert(Context context, String sql) {
+ return (ConvertResult) parse_(context, sql, true, false, false);
+ }
+
+ public AnalyzeViewResult analyzeView(Context context, String sql, boolean fail) {
+ return (AnalyzeViewResult) parse_(context, sql, true, true, fail);
+ }
+
+ /** Shared implementation for {@link #parse}, {@link #convert} and
+ * {@link #analyzeView}. */
+ private ParseResult parse_(Context context, String sql, boolean convert,
+ boolean analyze, boolean fail) {
+ final JavaTypeFactory typeFactory = context.getTypeFactory();
+ CalciteCatalogReader catalogReader =
+ new CalciteCatalogReader(
+ context.getRootSchema(),
+ context.config().caseSensitive(),
+ context.getDefaultSchemaPath(),
+ typeFactory);
+ SqlParser parser = createParser(sql);
+ SqlNode sqlNode;
+ try {
+ sqlNode = parser.parseStmt();
+ } catch (SqlParseException e) {
+ throw new RuntimeException("parse failed", e);
+ }
+ final SqlValidator validator = createSqlValidator(context, catalogReader);
+ SqlNode sqlNode1 = validator.validate(sqlNode);
+ if (convert) {
+ return convert_(
+ context, sql, analyze, fail, catalogReader, validator, sqlNode1);
+ }
+ return new ParseResult(this, validator, sql, sqlNode1,
+ validator.getValidatedNodeType(sqlNode1));
+ }
+
+ private ParseResult convert_(Context context, String sql, boolean analyze,
+ boolean fail, CalciteCatalogReader catalogReader, SqlValidator validator,
+ SqlNode sqlNode1) {
+ final JavaTypeFactory typeFactory = context.getTypeFactory();
+ final Convention resultConvention =
+ enableBindable ? BindableConvention.INSTANCE
+ : EnumerableConvention.INSTANCE;
+ final HepPlanner planner = new HepPlanner(new HepProgramBuilder().build());
+ planner.addRelTraitDef(ConventionTraitDef.INSTANCE);
+
+ final SqlToRelConverter.ConfigBuilder configBuilder =
+ SqlToRelConverter.configBuilder().withTrimUnusedFields(true);
+ if (analyze) {
+ configBuilder.withConvertTableAccess(false);
+ }
+
+ final CalcitePreparingStmt preparingStmt =
+ new CalcitePreparingStmt(this, context, catalogReader, typeFactory,
+ context.getRootSchema(), null, planner, resultConvention,
+ createConvertletTable());
+ final SqlToRelConverter converter =
+ preparingStmt.getSqlToRelConverter(validator, catalogReader,
+ configBuilder.build());
+
+ final RelRoot root = converter.convertQuery(sqlNode1, false, true);
+ if (analyze) {
+ return analyze_(validator, sql, sqlNode1, root, fail);
+ }
+ return new ConvertResult(this, validator, sql, sqlNode1,
+ validator.getValidatedNodeType(sqlNode1), root);
+ }
+
+ private AnalyzeViewResult analyze_(SqlValidator validator, String sql,
+ SqlNode sqlNode, RelRoot root, boolean fail) {
+ final RexBuilder rexBuilder = root.rel.getCluster().getRexBuilder();
+ RelNode rel = root.rel;
+ final RelNode viewRel = rel;
+ Project project;
+ if (rel instanceof Project) {
+ project = (Project) rel;
+ rel = project.getInput();
+ } else {
+ project = null;
+ }
+ Filter filter;
+ if (rel instanceof Filter) {
+ filter = (Filter) rel;
+ rel = filter.getInput();
+ } else {
+ filter = null;
+ }
+ TableScan scan;
+ if (rel instanceof TableScan) {
+ scan = (TableScan) rel;
+ } else {
+ scan = null;
+ }
+ if (scan == null) {
+ if (fail) {
+ throw validator.newValidationError(sqlNode,
+ RESOURCE.modifiableViewMustBeBasedOnSingleTable());
+ }
+ return new AnalyzeViewResult(this, validator, sql, sqlNode,
+ validator.getValidatedNodeType(sqlNode), root, null, null, null,
+ null, false);
+ }
+ final RelOptTable targetRelTable = scan.getTable();
+ final RelDataType targetRowType = targetRelTable.getRowType();
+ final Table table = targetRelTable.unwrap(Table.class);
+ final List<String> tablePath = targetRelTable.getQualifiedName();
+ assert table != null;
+ List<Integer> columnMapping;
+ final Map<Integer, RexNode> projectMap = new HashMap<>();
+ if (project == null) {
+ columnMapping = ImmutableIntList.range(0, targetRowType.getFieldCount());
+ } else {
+ columnMapping = new ArrayList<>();
+ for (Ord<RexNode> node : Ord.zip(project.getProjects())) {
+ if (node.e instanceof RexInputRef) {
+ RexInputRef rexInputRef = (RexInputRef) node.e;
+ int index = rexInputRef.getIndex();
+ if (projectMap.get(index) != null) {
+ if (fail) {
+ throw validator.newValidationError(sqlNode,
+ RESOURCE.moreThanOneMappedColumn(
+ targetRowType.getFieldList().get(index).getName(),
+ Util.last(tablePath)));
+ }
+ return new AnalyzeViewResult(this, validator, sql, sqlNode,
+ validator.getValidatedNodeType(sqlNode), root, null, null, null,
+ null, false);
+ }
+ projectMap.put(index, rexBuilder.makeInputRef(viewRel, node.i));
+ columnMapping.add(index);
+ } else {
+ columnMapping.add(-1);
+ }
+ }
+ }
+ final RexNode constraint;
+ if (filter != null) {
+ constraint = filter.getCondition();
+ } else {
+ constraint = rexBuilder.makeLiteral(true);
+ }
+ final List<RexNode> filters = new ArrayList<>();
+ // If we put a constraint in projectMap above, then filters will not be empty despite
+ // being a modifiable view.
+ final List<RexNode> filters2 = new ArrayList<>();
+ boolean retry = false;
+ RelOptUtil.inferViewPredicates(projectMap, filters, constraint);
+ if (fail && !filters.isEmpty()) {
+ final Map<Integer, RexNode> projectMap2 = new HashMap<>();
+ RelOptUtil.inferViewPredicates(projectMap2, filters2, constraint);
+ if (!filters2.isEmpty()) {
+ throw validator.newValidationError(sqlNode,
+ RESOURCE.modifiableViewMustHaveOnlyEqualityPredicates());
+ }
+ retry = true;
+ }
+
+ // Check that all columns that are not projected have a constant value
+ for (RelDataTypeField field : targetRowType.getFieldList()) {
+ final int x = columnMapping.indexOf(field.getIndex());
+ if (x >= 0) {
+ assert Util.skip(columnMapping, x + 1).indexOf(field.getIndex()) < 0
+ : "column projected more than once; should have checked above";
+ continue; // target column is projected
+ }
+ if (projectMap.get(field.getIndex()) != null) {
+ continue; // constant expression
+ }
+ if (field.getType().isNullable()) {
+ continue; // don't need expression for nullable columns; NULL suffices
+ }
+ if (fail) {
+ throw validator.newValidationError(sqlNode,
+ RESOURCE.noValueSuppliedForViewColumn(field.getName(),
+ Util.last(tablePath)));
+ }
+ return new AnalyzeViewResult(this, validator, sql, sqlNode,
+ validator.getValidatedNodeType(sqlNode), root, null, null, null,
+ null, false);
+ }
+
+ final boolean modifiable = filters.isEmpty() || retry && filters2.isEmpty();
+ return new AnalyzeViewResult(this, validator, sql, sqlNode,
+ validator.getValidatedNodeType(sqlNode), root, modifiable ? table : null,
+ ImmutableList.copyOf(tablePath),
+ constraint, ImmutableIntList.copyOf(columnMapping),
+ modifiable);
+ }
+
+ @Override public void executeDdl(Context context, SqlNode node) {
+ if (node instanceof SqlExecutableStatement) {
+ SqlExecutableStatement statement = (SqlExecutableStatement) node;
+ statement.execute(context);
+ return;
+ }
+ throw new UnsupportedOperationException();
+ }
+
+ /** Factory method for default SQL parser. */
+ protected SqlParser createParser(String sql) {
+ return createParser(sql, createParserConfig());
+ }
+
+ /** Factory method for SQL parser with a given configuration. */
+ protected SqlParser createParser(String sql,
+ SqlParser.ConfigBuilder parserConfig) {
+ return SqlParser.create(sql, parserConfig.build());
+ }
+
+ /** Factory method for SQL parser configuration. */
+ protected SqlParser.ConfigBuilder createParserConfig() {
+ return SqlParser.configBuilder();
+ }
+
+ /** Factory method for default convertlet table. */
+ protected SqlRexConvertletTable createConvertletTable() {
+ return StandardConvertletTable.INSTANCE;
+ }
+
+ /** Factory method for cluster. */
+ protected RelOptCluster createCluster(RelOptPlanner planner,
+ RexBuilder rexBuilder) {
+ return RelOptCluster.create(planner, rexBuilder);
+ }
+
+ /** Creates a collection of planner factories.
+ *
+ * <p>The collection must have at least one factory, and each factory must
+ * create a planner. If the collection has more than one planner, Calcite will
+ * try each planner in turn.</p>
+ *
+ * <p>One of the things you can do with this mechanism is to try a simpler,
+ * faster, planner with a smaller rule set first, then fall back to a more
+ * complex planner for complex and costly queries.</p>
+ *
+ * <p>The default implementation returns a factory that calls
+ * {@link #createPlanner(org.apache.calcite.jdbc.CalcitePrepare.Context)}.</p>
+ */
+ protected List<Function1<Context, RelOptPlanner>> createPlannerFactories() {
+ return Collections.<Function1<Context, RelOptPlanner>>singletonList(
+ new Function1<Context, RelOptPlanner>() {
+ public RelOptPlanner apply(Context context) {
+ return createPlanner(context, null, null);
+ }
+ });
+ }
+
+ /** Creates a query planner and initializes it with a default set of
+ * rules. */
+ protected RelOptPlanner createPlanner(CalcitePrepare.Context prepareContext) {
+ return createPlanner(prepareContext, null, null);
+ }
+
+ /** Creates a query planner and initializes it with a default set of
+ * rules. */
+ protected RelOptPlanner createPlanner(
+ final CalcitePrepare.Context prepareContext,
+ org.apache.calcite.plan.Context externalContext,
+ RelOptCostFactory costFactory) {
+ if (externalContext == null) {
+ externalContext = Contexts.of(prepareContext.config());
+ }
+ final VolcanoPlanner planner =
+ new VolcanoPlanner(costFactory, externalContext);
+ planner.addRelTraitDef(ConventionTraitDef.INSTANCE);
+ if (ENABLE_COLLATION_TRAIT) {
+ planner.addRelTraitDef(RelCollationTraitDef.INSTANCE);
+ planner.registerAbstractRelationalRules();
+ }
+ RelOptUtil.registerAbstractRels(planner);
+ for (RelOptRule rule : DEFAULT_RULES) {
+ planner.addRule(rule);
+ }
+ if (prepareContext.config().materializationsEnabled()) {
+ planner.addRule(MaterializedViewFilterScanRule.INSTANCE);
+ }
+ if (enableBindable) {
+ for (RelOptRule rule : Bindables.RULES) {
+ planner.addRule(rule);
+ }
+ }
+ planner.addRule(Bindables.BINDABLE_TABLE_SCAN_RULE);
+ planner.addRule(ProjectTableScanRule.INSTANCE);
+ planner.addRule(ProjectTableScanRule.INTERPRETER);
+
+ if (ENABLE_ENUMERABLE) {
+ for (RelOptRule rule : ENUMERABLE_RULES) {
+ planner.addRule(rule);
+ }
+ planner.addRule(EnumerableInterpreterRule.INSTANCE);
+ }
+
+ if (enableBindable && ENABLE_ENUMERABLE) {
+ planner.addRule(
+ EnumerableBindable.EnumerableToBindableConverterRule.INSTANCE);
+ }
+
+ if (ENABLE_STREAM) {
+ for (RelOptRule rule : StreamRules.RULES) {
+ planner.addRule(rule);
+ }
+ }
+
+ // Change the below to enable constant-reduction.
+ if (false) {
+ for (RelOptRule rule : CONSTANT_REDUCTION_RULES) {
+ planner.addRule(rule);
+ }
+ }
+
+ final SparkHandler spark = prepareContext.spark();
+ if (spark.enabled()) {
+ spark.registerRules(
+ new SparkHandler.RuleSetBuilder() {
+ public void addRule(RelOptRule rule) {
+ // TODO:
+ }
+
+ public void removeRule(RelOptRule rule) {
+ // TODO:
+ }
+ });
+ }
+
+ Hook.PLANNER.run(planner); // allow test to add or remove rules
+
+ return planner;
+ }
+
+ public <T> CalciteSignature<T> prepareQueryable(
+ Context context,
+ Queryable<T> queryable) {
+ return prepare_(context, Query.of(queryable), queryable.getElementType(),
+ -1);
+ }
+
+ public <T> CalciteSignature<T> prepareSql(
+ Context context,
+ Query<T> query,
+ Type elementType,
+ long maxRowCount) {
+ return prepare_(context, query, elementType, maxRowCount);
+ }
+
+ <T> CalciteSignature<T> prepare_(
+ Context context,
+ Query<T> query,
+ Type elementType,
+ long maxRowCount) {
+ if (SIMPLE_SQLS.contains(query.sql)) {
+ return simplePrepare(context, query.sql);
+ }
+
+ if(KYLIN_ONLY_PREPARE.get() != null && KYLIN_ONLY_PREPARE.get()) {
+ ParseResult parseResult = parse(context, query.sql);
+ Class<OnlyPrepareEarlyAbortException> onlyPrepareEarlyAbortExceptionClass =
+ OnlyPrepareEarlyAbortException.class;
+ throw new OnlyPrepareEarlyAbortException(context, parseResult);
+ }
+
+ final JavaTypeFactory typeFactory = context.getTypeFactory();
+ CalciteCatalogReader catalogReader =
+ new CalciteCatalogReader(
+ context.getRootSchema(),
+ context.config().caseSensitive(),
+ context.getDefaultSchemaPath(),
+ typeFactory);
+ final List<Function1<Context, RelOptPlanner>> plannerFactories =
+ createPlannerFactories();
+ if (plannerFactories.isEmpty()) {
+ throw new AssertionError("no planner factories");
+ }
+ RuntimeException exception = Util.FoundOne.NULL;
+ for (Function1<Context, RelOptPlanner> plannerFactory : plannerFactories) {
+ final RelOptPlanner planner = plannerFactory.apply(context);
+ if (planner == null) {
+ throw new AssertionError("factory returned null planner");
+ }
+ try {
+ return prepare2_(context, query, elementType, maxRowCount,
+ catalogReader, planner);
+ } catch (RelOptPlanner.CannotPlanException e) {
+ exception = e;
+ }
+ }
+ throw exception;
+ }
+
+ /** Quickly prepares a simple SQL statement, circumventing the usual
+ * preparation process. */
+ private <T> CalciteSignature<T> simplePrepare(Context context, String sql) {
+ final JavaTypeFactory typeFactory = context.getTypeFactory();
+ final RelDataType x =
+ typeFactory.builder()
+ .add(SqlUtil.deriveAliasFromOrdinal(0), SqlTypeName.INTEGER)
+ .build();
+ @SuppressWarnings("unchecked")
+ final List<T> list = (List) ImmutableList.of(1);
+ final List<String> origin = null;
+ final List<List<String>> origins =
+ Collections.nCopies(x.getFieldCount(), origin);
+ final List<ColumnMetaData> columns =
+ getColumnMetaDataList(typeFactory, x, x, origins);
+ final Meta.CursorFactory cursorFactory =
+ Meta.CursorFactory.deduce(columns, null);
+ return new CalciteSignature<>(
+ sql,
+ ImmutableList.<AvaticaParameter>of(),
+ ImmutableMap.<String, Object>of(),
+ x,
+ columns,
+ cursorFactory,
+ ImmutableList.<RelCollation>of(),
+ -1,
+ new Bindable<T>() {
+ public Enumerable<T> bind(DataContext dataContext) {
+ return Linq4j.asEnumerable(list);
+ }
+ },
+ Meta.StatementType.SELECT);
+ }
+
+ /**
+ * Deduces the broad type of statement.
+ * Currently returns SELECT for most statement types, but this may change.
+ *
+ * @param kind Kind of statement
+ */
+ private Meta.StatementType getStatementType(SqlKind kind) {
+ switch (kind) {
+ case INSERT:
+ case DELETE:
+ case UPDATE:
+ return Meta.StatementType.IS_DML;
+ default:
+ return Meta.StatementType.SELECT;
+ }
+ }
+
+ /**
+ * Deduces the broad type of statement for a prepare result.
+ * Currently returns SELECT for most statement types, but this may change.
+ *
+ * @param preparedResult Prepare result
+ */
+ private Meta.StatementType getStatementType(Prepare.PreparedResult preparedResult) {
+ if (preparedResult.isDml()) {
+ return Meta.StatementType.IS_DML;
+ } else {
+ return Meta.StatementType.SELECT;
+ }
+ }
+
+ <T> CalciteSignature<T> prepare2_(
+ Context context,
+ Query<T> query,
+ Type elementType,
+ long maxRowCount,
+ CalciteCatalogReader catalogReader,
+ RelOptPlanner planner) {
+ final JavaTypeFactory typeFactory = context.getTypeFactory();
+ final EnumerableRel.Prefer prefer;
+ if (elementType == Object[].class) {
+ prefer = EnumerableRel.Prefer.ARRAY;
+ } else {
+ prefer = EnumerableRel.Prefer.CUSTOM;
+ }
+ final Convention resultConvention =
+ enableBindable ? BindableConvention.INSTANCE
+ : EnumerableConvention.INSTANCE;
+ final CalcitePreparingStmt preparingStmt =
+ new CalcitePreparingStmt(this, context, catalogReader, typeFactory,
+ context.getRootSchema(), prefer, planner, resultConvention,
+ createConvertletTable());
+
+ final RelDataType x;
+ final Prepare.PreparedResult preparedResult;
+ final Meta.StatementType statementType;
+ if (query.sql != null) {
+ final CalciteConnectionConfig config = context.config();
+ final SqlParser.ConfigBuilder parserConfig = createParserConfig()
+ .setQuotedCasing(config.quotedCasing())
+ .setUnquotedCasing(config.unquotedCasing())
+ .setQuoting(config.quoting())
+ .setConformance(config.conformance());
+ final SqlParserImplFactory parserFactory =
+ config.parserFactory(SqlParserImplFactory.class, null);
+ if (parserFactory != null) {
+ parserConfig.setParserFactory(parserFactory);
+ }
+ SqlParser parser = createParser(query.sql, parserConfig);
+ SqlNode sqlNode;
+ try {
+ sqlNode = parser.parseStmt();
+ statementType = getStatementType(sqlNode.getKind());
+ } catch (SqlParseException e) {
+ throw new RuntimeException(
+ "parse failed: " + e.getMessage(), e);
+ }
+
+ Hook.PARSE_TREE.run(new Object[] {query.sql, sqlNode});
+
+ if (sqlNode.getKind().belongsTo(SqlKind.DDL)) {
+ executeDdl(context, sqlNode);
+
+ // Return a dummy signature that contains no rows
+ final Bindable<T> bindable = new Bindable<T>() {
+ public Enumerable<T> bind(DataContext dataContext) {
+ return Linq4j.emptyEnumerable();
+ }
+ };
+ return new CalciteSignature<>(query.sql,
+ ImmutableList.<AvaticaParameter>of(),
+ ImmutableMap.<String, Object>of(), null,
+ ImmutableList.<ColumnMetaData>of(), Meta.CursorFactory.OBJECT,
+ ImmutableList.<RelCollation>of(), -1, bindable);
+ }
+
+ final SqlValidator validator =
+ createSqlValidator(context, catalogReader);
+ validator.setIdentifierExpansion(true);
+ validator.setDefaultNullCollation(config.defaultNullCollation());
+
+ preparedResult = preparingStmt.prepareSql(
+ sqlNode, Object.class, validator, true);
+ switch (sqlNode.getKind()) {
+ case INSERT:
+ case DELETE:
+ case UPDATE:
+ case EXPLAIN:
+ // FIXME: getValidatedNodeType is wrong for DML
+ x = RelOptUtil.createDmlRowType(sqlNode.getKind(), typeFactory);
+ break;
+ default:
+ x = validator.getValidatedNodeType(sqlNode);
+ }
+ } else if (query.queryable != null) {
+ x = context.getTypeFactory().createType(elementType);
+ preparedResult =
+ preparingStmt.prepareQueryable(query.queryable, x);
+ statementType = getStatementType(preparedResult);
+ } else {
+ assert query.rel != null;
+ x = query.rel.getRowType();
+ preparedResult = preparingStmt.prepareRel(query.rel);
+ statementType = getStatementType(preparedResult);
+ }
+
+ final List<AvaticaParameter> parameters = new ArrayList<>();
+ final RelDataType parameterRowType = preparedResult.getParameterRowType();
+ for (RelDataTypeField field : parameterRowType.getFieldList()) {
+ RelDataType type = field.getType();
+ parameters.add(
+ new AvaticaParameter(
+ false,
+ getPrecision(type),
+ getScale(type),
+ getTypeOrdinal(type),
+ getTypeName(type),
+ getClassName(type),
+ field.getName()));
+ }
+
+ RelDataType jdbcType = makeStruct(typeFactory, x);
+ final List<List<String>> originList = preparedResult.getFieldOrigins();
+ final List<ColumnMetaData> columns =
+ getColumnMetaDataList(typeFactory, x, jdbcType, originList);
+ Class resultClazz = null;
+ if (preparedResult instanceof Typed) {
+ resultClazz = (Class) ((Typed) preparedResult).getElementType();
+ }
+ final Meta.CursorFactory cursorFactory =
+ preparingStmt.resultConvention == BindableConvention.INSTANCE
+ ? Meta.CursorFactory.ARRAY
+ : Meta.CursorFactory.deduce(columns, resultClazz);
+ //noinspection unchecked
+ final Bindable<T> bindable = preparedResult.getBindable(cursorFactory);
+ return new CalciteSignature<>(
+ query.sql,
+ parameters,
+ preparingStmt.internalParameters,
+ jdbcType,
+ columns,
+ cursorFactory,
+ preparedResult instanceof Prepare.PreparedResultImpl
+ ? ((Prepare.PreparedResultImpl) preparedResult).collations
+ : ImmutableList.<RelCollation>of(),
+ maxRowCount,
+ bindable,
+ statementType);
+ }
+
+ private SqlValidator createSqlValidator(Context context,
+ CalciteCatalogReader catalogReader) {
+ final SqlOperatorTable opTab0 =
+ context.config().fun(SqlOperatorTable.class,
+ SqlStdOperatorTable.instance());
+ final SqlOperatorTable opTab =
+ ChainedSqlOperatorTable.of(opTab0, catalogReader);
+ final JavaTypeFactory typeFactory = context.getTypeFactory();
+ final SqlConformance conformance = context.config().conformance();
+ return new CalciteSqlValidator(opTab, catalogReader, typeFactory,
+ conformance);
+ }
+
+ private List<ColumnMetaData> getColumnMetaDataList(
+ JavaTypeFactory typeFactory, RelDataType x, RelDataType jdbcType,
+ List<List<String>> originList) {
+ final List<ColumnMetaData> columns = new ArrayList<>();
+ for (Ord<RelDataTypeField> pair : Ord.zip(jdbcType.getFieldList())) {
+ final RelDataTypeField field = pair.e;
+ final RelDataType type = field.getType();
+ final RelDataType fieldType =
+ x.isStruct() ? x.getFieldList().get(pair.i).getType() : type;
+ columns.add(
+ metaData(typeFactory, columns.size(), field.getName(), type,
+ fieldType, originList.get(pair.i)));
+ }
+ return columns;
+ }
+
+ private ColumnMetaData metaData(JavaTypeFactory typeFactory, int ordinal,
+ String fieldName, RelDataType type, RelDataType fieldType,
+ List<String> origins) {
+ final ColumnMetaData.AvaticaType avaticaType =
+ avaticaType(typeFactory, type, fieldType);
+ return new ColumnMetaData(
+ ordinal,
+ false,
+ true,
+ false,
+ false,
+ type.isNullable()
+ ? DatabaseMetaData.columnNullable
+ : DatabaseMetaData.columnNoNulls,
+ true,
+ type.getPrecision(),
+ fieldName,
+ origin(origins, 0),
+ origin(origins, 2),
+ getPrecision(type),
+ getScale(type),
+ origin(origins, 1),
+ null,
+ avaticaType,
+ true,
+ false,
+ false,
+ avaticaType.columnClassName());
+ }
+
+ private ColumnMetaData.AvaticaType avaticaType(JavaTypeFactory typeFactory,
+ RelDataType type, RelDataType fieldType) {
+ final String typeName = getTypeName(type);
+ if (type.getComponentType() != null) {
+ final ColumnMetaData.AvaticaType componentType =
+ avaticaType(typeFactory, type.getComponentType(), null);
+ final Type clazz = typeFactory.getJavaClass(type.getComponentType());
+ final ColumnMetaData.Rep rep = ColumnMetaData.Rep.of(clazz);
+ assert rep != null;
+ return ColumnMetaData.array(componentType, typeName, rep);
+ } else {
+ final int typeOrdinal = getTypeOrdinal(type);
+ switch (typeOrdinal) {
+ case Types.STRUCT:
+ final List<ColumnMetaData> columns = new ArrayList<>();
+ for (RelDataTypeField field : type.getFieldList()) {
+ columns.add(
+ metaData(typeFactory, field.getIndex(), field.getName(),
+ field.getType(), null, null));
+ }
+ return ColumnMetaData.struct(columns);
+ default:
+ final Type clazz =
+ typeFactory.getJavaClass(Util.first(fieldType, type));
+ final ColumnMetaData.Rep rep = ColumnMetaData.Rep.of(clazz);
+ assert rep != null;
+ return ColumnMetaData.scalar(typeOrdinal, typeName, rep);
+ }
+ }
+ }
+
+ private static String origin(List<String> origins, int offsetFromEnd) {
+ return origins == null || offsetFromEnd >= origins.size()
+ ? null
+ : origins.get(origins.size() - 1 - offsetFromEnd);
+ }
+
+ private int getTypeOrdinal(RelDataType type) {
+ return type.getSqlTypeName().getJdbcOrdinal();
+ }
+
+ private static String getClassName(RelDataType type) {
+ return null;
+ }
+
+ private static int getScale(RelDataType type) {
+ return type.getScale() == RelDataType.SCALE_NOT_SPECIFIED
+ ? 0
+ : type.getScale();
+ }
+
+ private static int getPrecision(RelDataType type) {
+ return type.getPrecision() == RelDataType.PRECISION_NOT_SPECIFIED
+ ? 0
+ : type.getPrecision();
+ }
+
+ /** Returns the type name in string form. Does not include precision, scale
+ * or whether nulls are allowed. Example: "DECIMAL" not "DECIMAL(7, 2)";
+ * "INTEGER" not "JavaType(int)". */
+ private static String getTypeName(RelDataType type) {
+ final SqlTypeName sqlTypeName = type.getSqlTypeName();
+ switch (sqlTypeName) {
+ case ARRAY:
+ case MULTISET:
+ case MAP:
+ case ROW:
+ return type.toString(); // e.g. "INTEGER ARRAY"
+ case INTERVAL_YEAR_MONTH:
+ return "INTERVAL_YEAR_TO_MONTH";
+ case INTERVAL_DAY_HOUR:
+ return "INTERVAL_DAY_TO_HOUR";
+ case INTERVAL_DAY_MINUTE:
+ return "INTERVAL_DAY_TO_MINUTE";
+ case INTERVAL_DAY_SECOND:
+ return "INTERVAL_DAY_TO_SECOND";
+ case INTERVAL_HOUR_MINUTE:
+ return "INTERVAL_HOUR_TO_MINUTE";
+ case INTERVAL_HOUR_SECOND:
+ return "INTERVAL_HOUR_TO_SECOND";
+ case INTERVAL_MINUTE_SECOND:
+ return "INTERVAL_MINUTE_TO_SECOND";
+ default:
+ return sqlTypeName.getName(); // e.g. "DECIMAL", "INTERVAL_YEAR_MONTH"
+ }
+ }
+
+ protected void populateMaterializations(Context context,
+ RelOptPlanner planner, Prepare.Materialization materialization) {
+ // REVIEW: initialize queryRel and tableRel inside MaterializationService,
+ // not here?
+ try {
+ final CalciteSchema schema = materialization.materializedTable.schema;
+ CalciteCatalogReader catalogReader =
+ new CalciteCatalogReader(
+ schema.root(),
+ context.config().caseSensitive(),
+ materialization.viewSchemaPath,
+ context.getTypeFactory());
+ final CalciteMaterializer materializer =
+ new CalciteMaterializer(this, context, catalogReader, schema, planner,
+ createConvertletTable());
+ materializer.populate(materialization);
+ } catch (Exception e) {
+ throw new RuntimeException("While populating materialization "
+ + materialization.materializedTable.path(), e);
+ }
+ }
+
+ private static RelDataType makeStruct(
+ RelDataTypeFactory typeFactory,
+ RelDataType type) {
+ if (type.isStruct()) {
+ return type;
+ }
+ return typeFactory.builder().add("$0", type).build();
+ }
+
+ /** Executes a prepare action. */
+ public <R> R perform(CalciteServerStatement statement,
+ Frameworks.PrepareAction<R> action) {
+ final CalcitePrepare.Context prepareContext =
+ statement.createPrepareContext();
+ final JavaTypeFactory typeFactory = prepareContext.getTypeFactory();
+ final CalciteSchema schema =
+ action.getConfig().getDefaultSchema() != null
+ ? CalciteSchema.from(action.getConfig().getDefaultSchema())
+ : prepareContext.getRootSchema();
+ CalciteCatalogReader catalogReader =
+ new CalciteCatalogReader(schema.root(),
+ prepareContext.config().caseSensitive(),
+ schema.path(null),
+ typeFactory);
+ final RexBuilder rexBuilder = new RexBuilder(typeFactory);
+ final RelOptPlanner planner =
+ createPlanner(prepareContext,
+ action.getConfig().getContext(),
+ action.getConfig().getCostFactory());
+ final RelOptCluster cluster = createCluster(planner, rexBuilder);
+ return action.apply(cluster, catalogReader,
+ prepareContext.getRootSchema().plus(), statement);
+ }
+
+ /** Holds state for the process of preparing a SQL statement. */
+ static class CalcitePreparingStmt extends Prepare
+ implements RelOptTable.ViewExpander {
+ protected final RelOptPlanner planner;
+ protected final RexBuilder rexBuilder;
+ protected final CalcitePrepareImpl prepare;
+ protected final CalciteSchema schema;
+ protected final RelDataTypeFactory typeFactory;
+ protected final SqlRexConvertletTable convertletTable;
+ private final EnumerableRel.Prefer prefer;
+ private final Map<String, Object> internalParameters =
+ Maps.newLinkedHashMap();
+ private int expansionDepth;
+ private SqlValidator sqlValidator;
+
+ public CalcitePreparingStmt(CalcitePrepareImpl prepare,
+ Context context,
+ CatalogReader catalogReader,
+ RelDataTypeFactory typeFactory,
+ CalciteSchema schema,
+ EnumerableRel.Prefer prefer,
+ RelOptPlanner planner,
+ Convention resultConvention,
+ SqlRexConvertletTable convertletTable) {
+ super(context, catalogReader, resultConvention);
+ this.prepare = prepare;
+ this.schema = schema;
+ this.prefer = prefer;
+ this.planner = planner;
+ this.typeFactory = typeFactory;
+ this.convertletTable = convertletTable;
+ this.rexBuilder = new RexBuilder(typeFactory);
+ }
+
+ @Override protected void init(Class runtimeContextClass) {
+ }
+
+ public PreparedResult prepareQueryable(
+ final Queryable queryable,
+ RelDataType resultType) {
+ return prepare_(
+ new Supplier<RelNode>() {
+ public RelNode get() {
+ final RelOptCluster cluster =
+ prepare.createCluster(planner, rexBuilder);
+ return new LixToRelTranslator(cluster, CalcitePreparingStmt.this)
+ .translate(queryable);
+ }
+ }, resultType);
+ }
+
+ public PreparedResult prepareRel(final RelNode rel) {
+ return prepare_(
+ new Supplier<RelNode>() {
+ public RelNode get() {
+ return rel;
+ }
+ }, rel.getRowType());
+ }
+
+ private PreparedResult prepare_(Supplier<RelNode> fn,
+ RelDataType resultType) {
+ queryString = null;
+ Class runtimeContextClass = Object.class;
+ init(runtimeContextClass);
+
+ final RelNode rel = fn.get();
+ final RelDataType rowType = rel.getRowType();
+ final List<Pair<Integer, String>> fields =
+ Pair.zip(ImmutableIntList.identity(rowType.getFieldCount()),
+ rowType.getFieldNames());
+ final RelCollation collation =
+ rel instanceof Sort
+ ? ((Sort) rel).collation
+ : RelCollations.EMPTY;
+ RelRoot root = new RelRoot(rel, resultType, SqlKind.SELECT, fields,
+ collation);
+
+ if (timingTracer != null) {
+ timingTracer.traceTime("end sql2rel");
+ }
+
+ final RelDataType jdbcType =
+ makeStruct(rexBuilder.getTypeFactory(), resultType);
+ fieldOrigins = Collections.nCopies(jdbcType.getFieldCount(), null);
+ parameterRowType = rexBuilder.getTypeFactory().builder().build();
+
+ // Structured type flattening, view expansion, and plugging in
+ // physical storage.
+ root = root.withRel(flattenTypes(root.rel, true));
+
+ // Trim unused fields.
+ root = trimUnusedFields(root);
+
+ final List<Materialization> materializations = ImmutableList.of();
+ final List<CalciteSchema.LatticeEntry> lattices = ImmutableList.of();
+ root = optimize(root, materializations, lattices);
+
+ if (timingTracer != null) {
+ timingTracer.traceTime("end optimization");
+ }
+
+ return implement(root);
+ }
+
+ @Override protected SqlToRelConverter getSqlToRelConverter(
+ SqlValidator validator,
+ CatalogReader catalogReader,
+ SqlToRelConverter.Config config) {
+ final RelOptCluster cluster = prepare.createCluster(planner, rexBuilder);
+ SqlToRelConverter sqlToRelConverter =
+ new SqlToRelConverter(this, validator, catalogReader, cluster,
+ convertletTable, config);
+ return sqlToRelConverter;
+ }
+
+ @Override public RelNode flattenTypes(
+ RelNode rootRel,
+ boolean restructure) {
+ final SparkHandler spark = context.spark();
+ if (spark.enabled()) {
+ return spark.flattenTypes(planner, rootRel, restructure);
+ }
+ return rootRel;
+ }
+
+ @Override protected RelNode decorrelate(SqlToRelConverter sqlToRelConverter,
+ SqlNode query, RelNode rootRel) {
+ return sqlToRelConverter.decorrelate(query, rootRel);
+ }
+
+ @Override public RelRoot expandView(RelDataType rowType, String queryString,
+ List<String> schemaPath, List<String> viewPath) {
+ expansionDepth++;
+
+ SqlParser parser = prepare.createParser(queryString);
+ SqlNode sqlNode;
+ try {
+ sqlNode = parser.parseQuery();
+ } catch (SqlParseException e) {
+ throw new RuntimeException("parse failed", e);
+ }
+ // View may have different schema path than current connection.
+ final CatalogReader catalogReader =
+ this.catalogReader.withSchemaPath(schemaPath);
+ SqlValidator validator = createSqlValidator(catalogReader);
+ SqlNode sqlNode1 = validator.validate(sqlNode);
+ final SqlToRelConverter.Config config = SqlToRelConverter.configBuilder()
+ .withTrimUnusedFields(true).build();
+ SqlToRelConverter sqlToRelConverter =
+ getSqlToRelConverter(validator, catalogReader, config);
+ RelRoot root =
+ sqlToRelConverter.convertQuery(sqlNode1, true, false);
+
+ --expansionDepth;
+ return root;
+ }
+
+ protected SqlValidator createSqlValidator(CatalogReader catalogReader) {
+ return prepare.createSqlValidator(context,
+ (CalciteCatalogReader) catalogReader);
+ }
+
+ @Override protected SqlValidator getSqlValidator() {
+ if (sqlValidator == null) {
+ sqlValidator = createSqlValidator(catalogReader);
+ }
+ return sqlValidator;
+ }
+
+ @Override protected PreparedResult createPreparedExplanation(
+ RelDataType resultType,
+ RelDataType parameterRowType,
+ RelRoot root,
+ SqlExplainFormat format,
+ SqlExplainLevel detailLevel) {
+ return new CalcitePreparedExplain(resultType, parameterRowType, root,
+ format, detailLevel);
+ }
+
+ @Override protected PreparedResult implement(RelRoot root) {
+ RelDataType resultType = root.rel.getRowType();
+ boolean isDml = root.kind.belongsTo(SqlKind.DML);
+ final Bindable bindable;
+ if (resultConvention == BindableConvention.INSTANCE) {
+ bindable = Interpreters.bindable(root.rel);
+ } else {
+ EnumerableRel enumerable = (EnumerableRel) root.rel;
+ if (!root.isRefTrivial()) {
+ final List<RexNode> projects = new ArrayList<>();
+ final RexBuilder rexBuilder = enumerable.getCluster().getRexBuilder();
+ for (int field : Pair.left(root.fields)) {
+ projects.add(rexBuilder.makeInputRef(enumerable, field));
+ }
+ RexProgram program = RexProgram.create(enumerable.getRowType(),
+ projects, null, root.validatedRowType, rexBuilder);
+ enumerable = EnumerableCalc.create(enumerable, program);
+ }
+
+ try {
+ CatalogReader.THREAD_LOCAL.set(catalogReader);
+ bindable = EnumerableInterpretable.toBindable(internalParameters,
+ context.spark(), enumerable, prefer);
+ } finally {
+ CatalogReader.THREAD_LOCAL.remove();
+ }
+ }
+
+ if (timingTracer != null) {
+ timingTracer.traceTime("end codegen");
+ }
+
+ if (timingTracer != null) {
+ timingTracer.traceTime("end compilation");
+ }
+
+ return new PreparedResultImpl(
+ resultType,
+ parameterRowType,
+ fieldOrigins,
+ root.collation.getFieldCollations().isEmpty()
+ ? ImmutableList.<RelCollation>of()
+ : ImmutableList.of(root.collation),
+ root.rel,
+ mapTableModOp(isDml, root.kind),
+ isDml) {
+ public String getCode() {
+ throw new UnsupportedOperationException();
+ }
+
+ public Bindable getBindable(Meta.CursorFactory cursorFactory) {
+ return bindable;
+ }
+
+ public Type getElementType() {
+ return ((Typed) bindable).getElementType();
+ }
+ };
+ }
+
+ @Override protected List<Materialization> getMaterializations() {
+ final List<Prepare.Materialization> materializations =
+ context.config().materializationsEnabled()
+ ? MaterializationService.instance().query(schema)
+ : ImmutableList.<Prepare.Materialization>of();
+ for (Prepare.Materialization materialization : materializations) {
+ prepare.populateMaterializations(context, planner, materialization);
+ }
+ return materializations;
+ }
+
+ @Override protected List<LatticeEntry> getLattices() {
+ return Schemas.getLatticeEntries(schema);
+ }
+ }
+
+ /** An {@code EXPLAIN} statement, prepared and ready to execute. */
+ private static class CalcitePreparedExplain extends Prepare.PreparedExplain {
+ public CalcitePreparedExplain(
+ RelDataType resultType,
+ RelDataType parameterRowType,
+ RelRoot root,
+ SqlExplainFormat format,
+ SqlExplainLevel detailLevel) {
+ super(resultType, parameterRowType, root, format, detailLevel);
+ }
+
+ public Bindable getBindable(final Meta.CursorFactory cursorFactory) {
+ final String explanation = getCode();
+ return new Bindable() {
+ public Enumerable bind(DataContext dataContext) {
+ switch (cursorFactory.style) {
+ case ARRAY:
+ return Linq4j.singletonEnumerable(new String[] {explanation});
+ case OBJECT:
+ default:
+ return Linq4j.singletonEnumerable(explanation);
+ }
+ }
+ };
+ }
+ }
+
+ /** Translator from Java AST to {@link RexNode}. */
+ interface ScalarTranslator {
+ RexNode toRex(BlockStatement statement);
+ List<RexNode> toRexList(BlockStatement statement);
+ RexNode toRex(Expression expression);
+ ScalarTranslator bind(List<ParameterExpression> parameterList,
+ List<RexNode> values);
+ }
+
+ /** Basic translator. */
+ static class EmptyScalarTranslator implements ScalarTranslator {
+ private final RexBuilder rexBuilder;
+
+ public EmptyScalarTranslator(RexBuilder rexBuilder) {
+ this.rexBuilder = rexBuilder;
+ }
+
+ public static ScalarTranslator empty(RexBuilder builder) {
+ return new EmptyScalarTranslator(builder);
+ }
+
+ public List<RexNode> toRexList(BlockStatement statement) {
+ final List<Expression> simpleList = simpleList(statement);
+ final List<RexNode> list = new ArrayList<>();
+ for (Expression expression1 : simpleList) {
+ list.add(toRex(expression1));
+ }
+ return list;
+ }
+
+ public RexNode toRex(BlockStatement statement) {
+ return toRex(Blocks.simple(statement));
+ }
+
+ private static List<Expression> simpleList(BlockStatement statement) {
+ Expression simple = Blocks.simple(statement);
+ if (simple instanceof NewExpression) {
+ NewExpression newExpression = (NewExpression) simple;
+ return newExpression.arguments;
+ } else {
+ return Collections.singletonList(simple);
+ }
+ }
+
+ public RexNode toRex(Expression expression) {
+ switch (expression.getNodeType()) {
+ case MemberAccess:
+ // Case-sensitive name match because name was previously resolved.
+ return rexBuilder.makeFieldAccess(
+ toRex(
+ ((MemberExpression) expression).expression),
+ ((MemberExpression) expression).field.getName(),
+ true);
+ case GreaterThan:
+ return binary(expression, SqlStdOperatorTable.GREATER_THAN);
+ case LessThan:
+ return binary(expression, SqlStdOperatorTable.LESS_THAN);
+ case Parameter:
+ return parameter((ParameterExpression) expression);
+ case Call:
+ MethodCallExpression call = (MethodCallExpression) expression;
+ SqlOperator operator =
+ RexToLixTranslator.JAVA_TO_SQL_METHOD_MAP.get(call.method);
+ if (operator != null) {
+ return rexBuilder.makeCall(
+ type(call),
+ operator,
+ toRex(
+ Expressions.<Expression>list()
+ .appendIfNotNull(call.targetExpression)
+ .appendAll(call.expressions)));
+ }
+ throw new RuntimeException(
+ "Could translate call to method " + call.method);
+ case Constant:
+ final ConstantExpression constant =
+ (ConstantExpression) expression;
+ Object value = constant.value;
+ if (value instanceof Number) {
+ Number number = (Number) value;
+ if (value instanceof Double || value instanceof Float) {
+ return rexBuilder.makeApproxLiteral(
+ BigDecimal.valueOf(number.doubleValue()));
+ } else if (value instanceof BigDecimal) {
+ return rexBuilder.makeExactLiteral((BigDecimal) value);
+ } else {
+ return rexBuilder.makeExactLiteral(
+ BigDecimal.valueOf(number.longValue()));
+ }
+ } else if (value instanceof Boolean) {
+ return rexBuilder.makeLiteral((Boolean) value);
+ } else {
+ return rexBuilder.makeLiteral(constant.toString());
+ }
+ default:
+ throw new UnsupportedOperationException(
+ "unknown expression type " + expression.getNodeType() + " "
+ + expression);
+ }
+ }
+
+ private RexNode binary(Expression expression, SqlBinaryOperator op) {
+ BinaryExpression call = (BinaryExpression) expression;
+ return rexBuilder.makeCall(type(call), op,
+ toRex(ImmutableList.of(call.expression0, call.expression1)));
+ }
+
+ private List<RexNode> toRex(List<Expression> expressions) {
+ final List<RexNode> list = new ArrayList<>();
+ for (Expression expression : expressions) {
+ list.add(toRex(expression));
+ }
+ return list;
+ }
+
+ protected RelDataType type(Expression expression) {
+ final Type type = expression.getType();
+ return ((JavaTypeFactory) rexBuilder.getTypeFactory()).createType(type);
+ }
+
+ public ScalarTranslator bind(
+ List<ParameterExpression> parameterList, List<RexNode> values) {
+ return new LambdaScalarTranslator(
+ rexBuilder, parameterList, values);
+ }
+
+ public RexNode parameter(ParameterExpression param) {
+ throw new RuntimeException("unknown parameter " + param);
+ }
+ }
+
+ /** Translator that looks for parameters. */
+ private static class LambdaScalarTranslator extends EmptyScalarTranslator {
+ private final List<ParameterExpression> parameterList;
+ private final List<RexNode> values;
+
+ public LambdaScalarTranslator(
+ RexBuilder rexBuilder,
+ List<ParameterExpression> parameterList,
+ List<RexNode> values) {
+ super(rexBuilder);
+ this.parameterList = parameterList;
+ this.values = values;
+ }
+
+ public RexNode parameter(ParameterExpression param) {
+ int i = parameterList.indexOf(param);
+ if (i >= 0) {
+ return values.get(i);
+ }
+ throw new RuntimeException("unknown parameter " + param);
+ }
+ }
+}
+
+// End CalcitePrepareImpl.java
http://git-wip-us.apache.org/repos/asf/kylin/blob/56e9fb9e/atopcalcite/src/main/java/org/apache/calcite/prepare/OnlyPrepareEarlyAbortException.java
----------------------------------------------------------------------
diff --git a/atopcalcite/src/main/java/org/apache/calcite/prepare/OnlyPrepareEarlyAbortException.java b/atopcalcite/src/main/java/org/apache/calcite/prepare/OnlyPrepareEarlyAbortException.java
new file mode 100644
index 0000000..8493484
--- /dev/null
+++ b/atopcalcite/src/main/java/org/apache/calcite/prepare/OnlyPrepareEarlyAbortException.java
@@ -0,0 +1,40 @@
+/*
+ * 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.calcite.prepare;
+
+import org.apache.calcite.jdbc.CalcitePrepare;
+
+public class OnlyPrepareEarlyAbortException extends RuntimeException {
+
+ private CalcitePrepare.Context context;
+ private org.apache.calcite.jdbc.CalcitePrepare.ParseResult preparedResult;
+
+ public OnlyPrepareEarlyAbortException(CalcitePrepare.Context context,
+ org.apache.calcite.jdbc.CalcitePrepare.ParseResult preparedResult) {
+ this.context = context;
+ this.preparedResult = preparedResult;
+ }
+
+ public CalcitePrepare.Context getContext() {
+ return context;
+ }
+
+ public CalcitePrepare.ParseResult getPreparedResult() {
+ return preparedResult;
+ }
+}
http://git-wip-us.apache.org/repos/asf/kylin/blob/56e9fb9e/server-base/src/main/java/org/apache/kylin/rest/controller/QueryController.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/controller/QueryController.java b/server-base/src/main/java/org/apache/kylin/rest/controller/QueryController.java
index 0da92c7..35dcee4 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/controller/QueryController.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/controller/QueryController.java
@@ -22,10 +22,13 @@ import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
+import java.util.Map;
import javax.servlet.http.HttpServletResponse;
+import com.google.common.collect.Maps;
import org.apache.commons.io.IOUtils;
+import org.apache.kylin.common.debug.BackdoorToggles;
import org.apache.kylin.metadata.querymeta.SelectedColumnMeta;
import org.apache.kylin.metadata.querymeta.TableMeta;
import org.apache.kylin.rest.exception.InternalErrorException;
@@ -76,6 +79,10 @@ public class QueryController extends BasicController {
@RequestMapping(value = "/query/prestate", method = RequestMethod.POST, produces = "application/json")
@ResponseBody
public SQLResponse prepareQuery(@RequestBody PrepareSqlRequest sqlRequest) {
+ Map<String, String> toggles = Maps.newHashMap();
+ toggles.put(BackdoorToggles.DEBUG_TOGGLE_PREPARE_ONLY, "true");
+ BackdoorToggles.addToggles(toggles);
+
return queryService.doQueryWithCache(sqlRequest);
}
@@ -106,7 +113,7 @@ public class QueryController extends BasicController {
@ResponseBody
public void downloadQueryResult(@PathVariable String format, SQLRequest sqlRequest, HttpServletResponse response) {
SQLResponse result = queryService.doQueryWithCache(sqlRequest);
- response.setContentType("text/" + format + ";charset=ansi");
+ response.setContentType("text/" + format + ";charset=utf-8");
response.setHeader("Content-Disposition", "attachment; filename=\"result." + format + "\"");
ICsvListWriter csvWriter = null;
http://git-wip-us.apache.org/repos/asf/kylin/blob/56e9fb9e/server-base/src/main/java/org/apache/kylin/rest/service/QueryService.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/service/QueryService.java b/server-base/src/main/java/org/apache/kylin/rest/service/QueryService.java
index b0ed171..1b118a3 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/service/QueryService.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/service/QueryService.java
@@ -47,6 +47,12 @@ import javax.annotation.PostConstruct;
import javax.sql.DataSource;
import org.apache.calcite.avatica.ColumnMetaData.Rep;
+import org.apache.calcite.config.CalciteConnectionConfig;
+import org.apache.calcite.jdbc.CalcitePrepare;
+import org.apache.calcite.prepare.CalcitePrepareImpl;
+import org.apache.calcite.prepare.OnlyPrepareEarlyAbortException;
+import org.apache.calcite.rel.type.RelDataTypeField;
+import org.apache.calcite.sql.type.BasicSqlType;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.kylin.common.KylinConfig;
@@ -117,12 +123,10 @@ import net.sf.ehcache.Element;
@Component("queryService")
public class QueryService extends BasicService {
- private static final Logger logger = LoggerFactory.getLogger(QueryService.class);
-
public static final String SUCCESS_QUERY_CACHE = "StorageCache";
public static final String EXCEPTION_QUERY_CACHE = "ExceptionQueryCache";
public static final String QUERY_STORE_PATH_PREFIX = "/query/";
-
+ private static final Logger logger = LoggerFactory.getLogger(QueryService.class);
final BadQueryDetector badQueryDetector = new BadQueryDetector();
final ResourceStore queryStore;
@@ -140,16 +144,27 @@ public class QueryService extends BasicService {
@Autowired
private AclUtil aclUtil;
- @PostConstruct
- public void init() throws IOException {
- Preconditions.checkNotNull(cacheManager, "cacheManager is not injected yet");
- }
-
public QueryService() {
queryStore = ResourceStore.getStore(getConfig());
badQueryDetector.start();
}
+ protected static void close(ResultSet resultSet, Statement stat, Connection conn) {
+ OLAPContext.clearParameter();
+ DBUtils.closeQuietly(resultSet);
+ DBUtils.closeQuietly(stat);
+ DBUtils.closeQuietly(conn);
+ }
+
+ private static String getQueryKeyById(String creator) {
+ return QUERY_STORE_PATH_PREFIX + creator;
+ }
+
+ @PostConstruct
+ public void init() throws IOException {
+ Preconditions.checkNotNull(cacheManager, "cacheManager is not injected yet");
+ }
+
public List<TableMeta> getMetadata(String project) throws SQLException {
return getMetadata(getCubeManager(), project, true);
}
@@ -535,6 +550,7 @@ public class QueryService extends BasicService {
return getMetadataV2(getCubeManager(), project, true);
}
+ @SuppressWarnings("checkstyle:methodlength")
protected List<TableMetaWithType> getMetadataV2(CubeManager cubeMgr, String project, boolean cubedOnly) throws SQLException, IOException {
//Message msg = MsgPicker.getMsg();
@@ -695,21 +711,15 @@ public class QueryService extends BasicService {
try {
conn = cacheService.getOLAPDataSource(sqlRequest.getProject()).getConnection();
- if (sqlRequest instanceof PrepareSqlRequest) {
- PreparedStatement preparedState = conn.prepareStatement(correctedSql);
- processStatementAttr(preparedState, sqlRequest);
-
- for (int i = 0; i < ((PrepareSqlRequest) sqlRequest).getParams().length; i++) {
- setParam(preparedState, i + 1, ((PrepareSqlRequest) sqlRequest).getParams()[i]);
- }
-
- resultSet = preparedState.executeQuery();
- } else {
- stat = conn.createStatement();
- processStatementAttr(stat, sqlRequest);
- resultSet = stat.executeQuery(correctedSql);
+ // special case for prepare query.
+ if (BackdoorToggles.getPrepareOnly()) {
+ return getPrepareOnlySqlResponse(correctedSql, conn, isAdHoc, results, columnMetas);
}
+ stat = conn.createStatement();
+ processStatementAttr(stat, sqlRequest);
+ resultSet = stat.executeQuery(correctedSql);
+
ResultSetMetaData metaData = resultSet.getMetaData();
int columnCount = metaData.getColumnCount();
@@ -733,6 +743,50 @@ public class QueryService extends BasicService {
close(resultSet, stat, conn);
}
+ return getSqlResponse(isAdHoc, results, columnMetas);
+ }
+
+ private SQLResponse getPrepareOnlySqlResponse(String correctedSql, Connection conn,
+ Boolean isAdHoc, List<List<String>> results, List<SelectedColumnMeta> columnMetas)
+ throws SQLException {
+
+ CalcitePrepareImpl.KYLIN_ONLY_PREPARE.set(true);
+
+ try {
+ conn.prepareStatement(correctedSql);
+ throw new IllegalStateException("Should have thrown OnlyPrepareEarlyAbortException");
+ } catch (Exception e) {
+ Throwable rootCause = ExceptionUtils.getRootCause(e);
+ if (rootCause != null && rootCause instanceof OnlyPrepareEarlyAbortException) {
+ OnlyPrepareEarlyAbortException abortException = (OnlyPrepareEarlyAbortException) rootCause;
+ CalcitePrepare.Context context = abortException.getContext();
+ CalcitePrepare.ParseResult preparedResult = abortException.getPreparedResult();
+ List<RelDataTypeField> fieldList = preparedResult.rowType.getFieldList();
+
+ CalciteConnectionConfig config = context.config();
+
+ // Fill in selected column meta
+ for (int i = 0; i < fieldList.size(); ++i) {
+
+ RelDataTypeField field = fieldList.get(i);
+ String columnName = field.getKey();
+ BasicSqlType basicSqlType = (BasicSqlType) field.getValue();
+
+ columnMetas.add(new SelectedColumnMeta(false, config.caseSensitive(), false, false, basicSqlType.isNullable() ? 1 : 0, true, basicSqlType.getPrecision(), columnName, columnName, null, null, null, basicSqlType.getPrecision(), basicSqlType.getScale(), basicSqlType.getSqlTypeName().getJdbcOrdinal(), basicSqlType.getSqlTypeName().getName(), true, false, false));
+ }
+
+ } else {
+ throw e;
+ }
+ } finally {
+ CalcitePrepareImpl.KYLIN_ONLY_PREPARE.set(false);
+ }
+
+ return getSqlResponse(isAdHoc, results, columnMetas);
+ }
+
+ private SQLResponse getSqlResponse(Boolean isAdHoc, List<List<String>> results, List<SelectedColumnMeta> columnMetas) {
+
boolean isPartialResult = false;
StringBuilder cubeSb = new StringBuilder();
StringBuilder logSb = new StringBuilder("Processed rows for each storageContext: ");
@@ -753,7 +807,6 @@ public class QueryService extends BasicService {
SQLResponse response = new SQLResponse(columnMetas, results, cubeSb.toString(), 0, false, null, isPartialResult, isAdHoc);
response.setTotalScanCount(QueryContext.current().getScannedRows());
response.setTotalScanBytes(QueryContext.current().getScannedBytes());
-
return response;
}
@@ -839,21 +892,10 @@ public class QueryService extends BasicService {
}
}
- protected static void close(ResultSet resultSet, Statement stat, Connection conn) {
- OLAPContext.clearParameter();
- DBUtils.closeQuietly(resultSet);
- DBUtils.closeQuietly(stat);
- DBUtils.closeQuietly(conn);
- }
-
public void setCacheManager(CacheManager cacheManager) {
this.cacheManager = cacheManager;
}
- private static String getQueryKeyById(String creator) {
- return QUERY_STORE_PATH_PREFIX + creator;
- }
-
private static class QueryRecordSerializer implements Serializer<QueryRecord> {
private static final QueryRecordSerializer serializer = new QueryRecordSerializer();
[27/50] kylin git commit: minor, user and acl jason serializer
Posted by li...@apache.org.
minor, user and acl jason serializer
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/cfac81bf
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/cfac81bf
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/cfac81bf
Branch: refs/heads/master
Commit: cfac81bffc22e1fb320c9fd6efe8c4e4ffd219a5
Parents: bf87169
Author: Roger Shi <ro...@hotmail.com>
Authored: Wed Jun 21 15:45:28 2017 +0800
Committer: Hongbin Ma <ma...@kyligence.io>
Committed: Wed Jun 21 16:27:16 2017 +0800
----------------------------------------------------------------------
.../apache/kylin/rest/service/AclService.java | 45 +++++---------------
.../rest/service/AclTableMigrationTool.java | 7 +--
.../apache/kylin/rest/service/UserService.java | 37 +++-------------
3 files changed, 21 insertions(+), 68 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/cfac81bf/server-base/src/main/java/org/apache/kylin/rest/service/AclService.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/service/AclService.java b/server-base/src/main/java/org/apache/kylin/rest/service/AclService.java
index 6292c00..02b8e9f 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/service/AclService.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/service/AclService.java
@@ -18,8 +18,6 @@
package org.apache.kylin.rest.service;
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.ArrayList;
@@ -29,10 +27,10 @@ import java.util.List;
import java.util.Map;
import org.apache.kylin.common.KylinConfig;
+import org.apache.kylin.common.persistence.JsonSerializer;
import org.apache.kylin.common.persistence.ResourceStore;
import org.apache.kylin.common.persistence.RootPersistentEntity;
import org.apache.kylin.common.persistence.Serializer;
-import org.apache.kylin.common.util.JsonUtil;
import org.apache.kylin.rest.exception.BadRequestException;
import org.apache.kylin.rest.exception.InternalErrorException;
import org.apache.kylin.rest.msg.Message;
@@ -79,6 +77,8 @@ public class AclService implements MutableAclService {
public static final String DIR_PREFIX = "/acl/";
+ public static final Serializer<AclRecord> SERIALIZER = new JsonSerializer<>(AclRecord.class);
+
@Autowired
protected PermissionGrantingStrategy permissionGrantingStrategy;
@@ -107,7 +107,8 @@ public class AclService implements MutableAclService {
public List<ObjectIdentity> findChildren(ObjectIdentity parentIdentity) {
List<ObjectIdentity> oids = new ArrayList<ObjectIdentity>();
try {
- List<AclRecord> allAclRecords = aclStore.getAllResources(String.valueOf(DIR_PREFIX), AclRecord.class, AclRecordSerializer.getInstance());
+ List<AclRecord> allAclRecords = aclStore.getAllResources(String.valueOf(DIR_PREFIX), AclRecord.class,
+ SERIALIZER);
for (AclRecord record : allAclRecords) {
DomainObjectInfo parent = record.getParentDomainObjectInfo();
if (parent != null && parent.getId().equals(String.valueOf(parentIdentity.getIdentifier()))) {
@@ -148,7 +149,8 @@ public class AclService implements MutableAclService {
Map<ObjectIdentity, Acl> aclMaps = new HashMap<ObjectIdentity, Acl>();
try {
for (ObjectIdentity oid : oids) {
- AclRecord record = aclStore.getResource(getQueryKeyById(String.valueOf(oid.getIdentifier())), AclRecord.class, AclRecordSerializer.getInstance());
+ AclRecord record = aclStore.getResource(getQueryKeyById(String.valueOf(oid.getIdentifier())),
+ AclRecord.class, SERIALIZER);
if (record != null) {
SidInfo owner = record.getOwnerInfo();
Sid ownerSid = (null == owner) ? null : (owner.isPrincipal() ? new PrincipalSid(owner.getSid()) : new GrantedAuthoritySid(owner.getSid()));
@@ -191,7 +193,8 @@ public class AclService implements MutableAclService {
PrincipalSid sid = new PrincipalSid(auth);
try {
AclRecord record = new AclRecord(new DomainObjectInfo(objectIdentity), null, new SidInfo(sid), true, null);
- aclStore.putResource(getQueryKeyById(String.valueOf(objectIdentity.getIdentifier())), record, 0, AclRecordSerializer.getInstance());
+ aclStore.putResource(getQueryKeyById(String.valueOf(objectIdentity.getIdentifier())), record, 0,
+ SERIALIZER);
logger.debug("ACL of " + objectIdentity + " created successfully.");
} catch (IOException e) {
throw new InternalErrorException(e);
@@ -228,7 +231,7 @@ public class AclService implements MutableAclService {
try {
String id = getQueryKeyById(String.valueOf(mutableAcl.getObjectIdentity().getIdentifier()));
- AclRecord record = aclStore.getResource(id, AclRecord.class, AclRecordSerializer.getInstance());
+ AclRecord record = aclStore.getResource(id, AclRecord.class, SERIALIZER);
aclStore.deleteResource(id);
if (mutableAcl.getParentAcl() != null) {
record.setParentDomainObjectInfo(new DomainObjectInfo(mutableAcl.getParentAcl().getObjectIdentity()));
@@ -249,7 +252,7 @@ public class AclService implements MutableAclService {
AceInfo aceInfo = new AceInfo(ace);
allAceInfo.put(String.valueOf(aceInfo.getSidInfo().getSid()), aceInfo);
}
- aclStore.putResource(id, record, 0, AclRecordSerializer.getInstance());
+ aclStore.putResource(id, record, 0, SERIALIZER);
logger.debug("ACL of " + mutableAcl.getObjectIdentity() + " updated successfully.");
} catch (IOException e) {
throw new InternalErrorException(e);
@@ -307,32 +310,6 @@ public class AclService implements MutableAclService {
public static String getQueryKeyById(String id) {
return DIR_PREFIX + id;
}
-
- protected static class AclRecordSerializer implements Serializer<AclRecord> {
-
- private static final AclRecordSerializer serializer = new AclRecordSerializer();
-
- AclRecordSerializer() {
-
- }
-
- public static AclRecordSerializer getInstance() {
- return serializer;
- }
-
- @Override
- public void serialize(AclRecord obj, DataOutputStream out) throws IOException {
- String jsonStr = JsonUtil.writeValueAsString(obj);
- out.writeUTF(jsonStr);
- }
-
- @Override
- public AclRecord deserialize(DataInputStream in) throws IOException {
- String jsonStr = in.readUTF();
- return JsonUtil.readValue(jsonStr, AclRecord.class);
- }
- }
-
}
@SuppressWarnings("serial")
http://git-wip-us.apache.org/repos/asf/kylin/blob/cfac81bf/server-base/src/main/java/org/apache/kylin/rest/service/AclTableMigrationTool.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/service/AclTableMigrationTool.java b/server-base/src/main/java/org/apache/kylin/rest/service/AclTableMigrationTool.java
index 428c556..fc50410 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/service/AclTableMigrationTool.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/service/AclTableMigrationTool.java
@@ -128,7 +128,7 @@ public class AclTableMigrationTool {
record.setEntriesInheriting(getInheriting(result));
record.setAllAceInfo(getAllAceInfo(result));
store.deleteResource(AclService.getQueryKeyById(object.getId()));
- store.putResource(AclService.getQueryKeyById(object.getId()), record, 0, AclService.AclRecordSerializer.getInstance());
+ store.putResource(AclService.getQueryKeyById(object.getId()), record, 0, AclService.SERIALIZER);
result = rs.next();
}
}
@@ -147,7 +147,8 @@ public class AclTableMigrationTool {
User user = hbaseRowToUser(result);
UserInfo userInfo = convert(user);
store.deleteResource(UserService.getId(userInfo.getUsername()));
- store.putResource(UserService.getId(userInfo.getUsername()), userInfo, 0, UserService.UserInfoSerializer.getInstance());
+ store.putResource(UserService.getId(userInfo.getUsername()), userInfo, 0,
+ UserService.SERIALIZER);
result = rs.next();
}
}
@@ -190,7 +191,7 @@ public class AclTableMigrationTool {
private DomainObjectInfo getDomainObjectInfoFromRs(Result result) {
String type = String.valueOf(result.getValue(Bytes.toBytes(AclConstant.ACL_INFO_FAMILY), Bytes.toBytes(AclConstant.ACL_INFO_FAMILY_TYPE_COLUMN)));
- String id = String.valueOf(result.getRow());
+ String id = new String(result.getRow());
DomainObjectInfo newInfo = new DomainObjectInfo();
newInfo.setId(id);
newInfo.setType(type);
http://git-wip-us.apache.org/repos/asf/kylin/blob/cfac81bf/server-base/src/main/java/org/apache/kylin/rest/service/UserService.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/service/UserService.java b/server-base/src/main/java/org/apache/kylin/rest/service/UserService.java
index 9adfcb8..e803040 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/service/UserService.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/service/UserService.java
@@ -18,8 +18,6 @@
package org.apache.kylin.rest.service;
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@@ -27,9 +25,9 @@ import java.util.List;
import javax.annotation.PostConstruct;
import org.apache.kylin.common.KylinConfig;
+import org.apache.kylin.common.persistence.JsonSerializer;
import org.apache.kylin.common.persistence.ResourceStore;
import org.apache.kylin.common.persistence.Serializer;
-import org.apache.kylin.common.util.JsonUtil;
import org.apache.kylin.rest.exception.InternalErrorException;
import org.apache.kylin.rest.msg.Message;
import org.apache.kylin.rest.msg.MsgPicker;
@@ -51,6 +49,8 @@ public class UserService implements UserDetailsManager {
public static final String DIR_PREFIX = "/user/";
+ public static final Serializer<UserInfo> SERIALIZER = new JsonSerializer<>(UserInfo.class);
+
protected ResourceStore aclStore;
@PostConstruct
@@ -70,7 +70,7 @@ public class UserService implements UserDetailsManager {
try {
deleteUser(user.getUsername());
String id = getId(user.getUsername());
- aclStore.putResource(id, new UserInfo(user), 0, UserInfoSerializer.getInstance());
+ aclStore.putResource(id, new UserInfo(user), 0, SERIALIZER);
logger.debug("update user : {}", user.getUsername());
} catch (IOException e) {
throw new InternalErrorException(e);
@@ -107,7 +107,7 @@ public class UserService implements UserDetailsManager {
public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {
Message msg = MsgPicker.getMsg();
try {
- UserInfo userInfo = aclStore.getResource(getId(userName), UserInfo.class, UserInfoSerializer.getInstance());
+ UserInfo userInfo = aclStore.getResource(getId(userName), UserInfo.class, SERIALIZER);
if (userInfo == null) {
throw new UsernameNotFoundException(String.format(msg.getUSER_NOT_FOUND(), userName));
}
@@ -132,7 +132,7 @@ public class UserService implements UserDetailsManager {
public List<UserDetails> listUsers() throws IOException {
List<UserDetails> all = new ArrayList<UserDetails>();
- List<UserInfo> userInfos = aclStore.getAllResources(DIR_PREFIX, UserInfo.class, UserInfoSerializer.getInstance());
+ List<UserInfo> userInfos = aclStore.getAllResources(DIR_PREFIX, UserInfo.class, SERIALIZER);
for (UserInfo info : userInfos) {
all.add(wrap(info));
}
@@ -154,29 +154,4 @@ public class UserService implements UserDetailsManager {
return new User(userInfo.getUsername(), userInfo.getPassword(), authorities);
}
- public static class UserInfoSerializer implements Serializer<UserInfo> {
-
- private static final UserInfoSerializer serializer = new UserInfoSerializer();
-
- private UserInfoSerializer() {
-
- }
-
- public static UserInfoSerializer getInstance() {
- return serializer;
- }
-
- @Override
- public void serialize(UserInfo userInfo, DataOutputStream out) throws IOException {
- String json = JsonUtil.writeValueAsString(userInfo);
- out.writeUTF(json);
- }
-
- @Override
- public UserInfo deserialize(DataInputStream in) throws IOException {
- String json = in.readUTF();
- return JsonUtil.readValue(json, UserInfo.class);
- }
- }
-
}
[45/50] kylin git commit: minor,
fix manager inconsistence with thread-local KylinConfig
Posted by li...@apache.org.
minor, fix manager inconsistence with thread-local KylinConfig
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/4f20ba32
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/4f20ba32
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/4f20ba32
Branch: refs/heads/master
Commit: 4f20ba32a8e93c05957d6da8e71b71920828a4f3
Parents: 450845c
Author: lidongsjtu <li...@apache.org>
Authored: Sun Jun 25 18:18:55 2017 +0800
Committer: Hongbin Ma <ma...@kyligence.io>
Committed: Tue Jun 27 18:28:14 2017 +0800
----------------------------------------------------------------------
.../src/main/java/org/apache/kylin/cube/CubeDescManager.java | 5 +++++
.../src/main/java/org/apache/kylin/cube/CubeManager.java | 5 +++++
.../main/java/org/apache/kylin/dict/DictionaryManager.java | 5 +++++
.../org/apache/kylin/job/execution/ExecutableManager.java | 5 +++++
.../main/java/org/apache/kylin/metadata/MetadataManager.java | 5 +++++
.../kylin/metadata/badquery/BadQueryHistoryManager.java | 5 +++++
.../org/apache/kylin/metadata/cachesync/Broadcaster.java | 8 ++++++++
.../java/org/apache/kylin/metadata/draft/DraftManager.java | 5 +++++
.../org/apache/kylin/metadata/project/ProjectManager.java | 5 +++++
.../kylin/metadata/realization/RealizationRegistry.java | 4 ++++
.../java/org/apache/kylin/storage/hybrid/HybridManager.java | 5 +++++
11 files changed, 57 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/4f20ba32/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 4e4daf2..2d44454 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
@@ -94,6 +94,11 @@ public class CubeDescManager {
CACHE.clear();
}
+ public static void clearCache(KylinConfig kylinConfig) {
+ if (kylinConfig != null)
+ CACHE.remove(kylinConfig);
+ }
+
// ============================================================================
private KylinConfig config;
http://git-wip-us.apache.org/repos/asf/kylin/blob/4f20ba32/core-cube/src/main/java/org/apache/kylin/cube/CubeManager.java
----------------------------------------------------------------------
diff --git a/core-cube/src/main/java/org/apache/kylin/cube/CubeManager.java b/core-cube/src/main/java/org/apache/kylin/cube/CubeManager.java
index 32e2316..da3abf1 100644
--- a/core-cube/src/main/java/org/apache/kylin/cube/CubeManager.java
+++ b/core-cube/src/main/java/org/apache/kylin/cube/CubeManager.java
@@ -124,6 +124,11 @@ public class CubeManager implements IRealizationProvider {
CACHE.clear();
}
+ public static void clearCache(KylinConfig kylinConfig) {
+ if (kylinConfig != null)
+ CACHE.remove(kylinConfig);
+ }
+
// ============================================================================
private KylinConfig config;
http://git-wip-us.apache.org/repos/asf/kylin/blob/4f20ba32/core-dictionary/src/main/java/org/apache/kylin/dict/DictionaryManager.java
----------------------------------------------------------------------
diff --git a/core-dictionary/src/main/java/org/apache/kylin/dict/DictionaryManager.java b/core-dictionary/src/main/java/org/apache/kylin/dict/DictionaryManager.java
index 1628f4e..857ee30 100644
--- a/core-dictionary/src/main/java/org/apache/kylin/dict/DictionaryManager.java
+++ b/core-dictionary/src/main/java/org/apache/kylin/dict/DictionaryManager.java
@@ -83,6 +83,11 @@ public class DictionaryManager {
CACHE.clear();
}
+ public static void clearCache(KylinConfig kylinConfig) {
+ if (kylinConfig != null)
+ CACHE.remove(kylinConfig);
+ }
+
// ============================================================================
private KylinConfig config;
http://git-wip-us.apache.org/repos/asf/kylin/blob/4f20ba32/core-job/src/main/java/org/apache/kylin/job/execution/ExecutableManager.java
----------------------------------------------------------------------
diff --git a/core-job/src/main/java/org/apache/kylin/job/execution/ExecutableManager.java b/core-job/src/main/java/org/apache/kylin/job/execution/ExecutableManager.java
index 170a254..f16cfde 100644
--- a/core-job/src/main/java/org/apache/kylin/job/execution/ExecutableManager.java
+++ b/core-job/src/main/java/org/apache/kylin/job/execution/ExecutableManager.java
@@ -83,6 +83,11 @@ public class ExecutableManager {
CACHE.clear();
}
+ public static void clearCache(KylinConfig kylinConfig) {
+ if (kylinConfig != null)
+ CACHE.remove(kylinConfig);
+ }
+
private static ExecutablePO parse(AbstractExecutable executable) {
ExecutablePO result = new ExecutablePO();
result.setName(executable.getName());
http://git-wip-us.apache.org/repos/asf/kylin/blob/4f20ba32/core-metadata/src/main/java/org/apache/kylin/metadata/MetadataManager.java
----------------------------------------------------------------------
diff --git a/core-metadata/src/main/java/org/apache/kylin/metadata/MetadataManager.java b/core-metadata/src/main/java/org/apache/kylin/metadata/MetadataManager.java
index 2a894b9..96ae294 100644
--- a/core-metadata/src/main/java/org/apache/kylin/metadata/MetadataManager.java
+++ b/core-metadata/src/main/java/org/apache/kylin/metadata/MetadataManager.java
@@ -103,6 +103,11 @@ public class MetadataManager {
CACHE.clear();
}
+ public static void clearCache(KylinConfig kylinConfig) {
+ if (kylinConfig != null)
+ CACHE.remove(kylinConfig);
+ }
+
// ============================================================================
private KylinConfig config;
http://git-wip-us.apache.org/repos/asf/kylin/blob/4f20ba32/core-metadata/src/main/java/org/apache/kylin/metadata/badquery/BadQueryHistoryManager.java
----------------------------------------------------------------------
diff --git a/core-metadata/src/main/java/org/apache/kylin/metadata/badquery/BadQueryHistoryManager.java b/core-metadata/src/main/java/org/apache/kylin/metadata/badquery/BadQueryHistoryManager.java
index c7eb133..d7cd425 100644
--- a/core-metadata/src/main/java/org/apache/kylin/metadata/badquery/BadQueryHistoryManager.java
+++ b/core-metadata/src/main/java/org/apache/kylin/metadata/badquery/BadQueryHistoryManager.java
@@ -72,6 +72,11 @@ public class BadQueryHistoryManager {
CACHE.clear();
}
+ public static void clearCache(KylinConfig kylinConfig) {
+ if (kylinConfig != null)
+ CACHE.remove(kylinConfig);
+ }
+
private ResourceStore getStore() {
return ResourceStore.getStore(this.kylinConfig);
}
http://git-wip-us.apache.org/repos/asf/kylin/blob/4f20ba32/core-metadata/src/main/java/org/apache/kylin/metadata/cachesync/Broadcaster.java
----------------------------------------------------------------------
diff --git a/core-metadata/src/main/java/org/apache/kylin/metadata/cachesync/Broadcaster.java b/core-metadata/src/main/java/org/apache/kylin/metadata/cachesync/Broadcaster.java
index c9e1130..4b0ef57 100644
--- a/core-metadata/src/main/java/org/apache/kylin/metadata/cachesync/Broadcaster.java
+++ b/core-metadata/src/main/java/org/apache/kylin/metadata/cachesync/Broadcaster.java
@@ -93,6 +93,14 @@ public class Broadcaster {
}
}
+ public static void clearCache(KylinConfig kylinConfig) {
+ if (kylinConfig != null) {
+ synchronized (CACHE) {
+ CACHE.remove(kylinConfig);
+ }
+ }
+ }
+
// ============================================================================
private KylinConfig config;
http://git-wip-us.apache.org/repos/asf/kylin/blob/4f20ba32/core-metadata/src/main/java/org/apache/kylin/metadata/draft/DraftManager.java
----------------------------------------------------------------------
diff --git a/core-metadata/src/main/java/org/apache/kylin/metadata/draft/DraftManager.java b/core-metadata/src/main/java/org/apache/kylin/metadata/draft/DraftManager.java
index 56ee251..bf3c3c3 100644
--- a/core-metadata/src/main/java/org/apache/kylin/metadata/draft/DraftManager.java
+++ b/core-metadata/src/main/java/org/apache/kylin/metadata/draft/DraftManager.java
@@ -72,6 +72,11 @@ public class DraftManager {
CACHE.clear();
}
+ public static void clearCache(KylinConfig kylinConfig) {
+ if (kylinConfig != null)
+ CACHE.remove(kylinConfig);
+ }
+
// ============================================================================
private KylinConfig config;
http://git-wip-us.apache.org/repos/asf/kylin/blob/4f20ba32/core-metadata/src/main/java/org/apache/kylin/metadata/project/ProjectManager.java
----------------------------------------------------------------------
diff --git a/core-metadata/src/main/java/org/apache/kylin/metadata/project/ProjectManager.java b/core-metadata/src/main/java/org/apache/kylin/metadata/project/ProjectManager.java
index 213b136..ea03c3c 100644
--- a/core-metadata/src/main/java/org/apache/kylin/metadata/project/ProjectManager.java
+++ b/core-metadata/src/main/java/org/apache/kylin/metadata/project/ProjectManager.java
@@ -85,6 +85,11 @@ public class ProjectManager {
CACHE.clear();
}
+ public static void clearCache(KylinConfig kylinConfig) {
+ if (kylinConfig != null)
+ CACHE.remove(kylinConfig);
+ }
+
// ============================================================================
private KylinConfig config;
http://git-wip-us.apache.org/repos/asf/kylin/blob/4f20ba32/core-metadata/src/main/java/org/apache/kylin/metadata/realization/RealizationRegistry.java
----------------------------------------------------------------------
diff --git a/core-metadata/src/main/java/org/apache/kylin/metadata/realization/RealizationRegistry.java b/core-metadata/src/main/java/org/apache/kylin/metadata/realization/RealizationRegistry.java
index 2d1a4a5..2ae4fa1 100644
--- a/core-metadata/src/main/java/org/apache/kylin/metadata/realization/RealizationRegistry.java
+++ b/core-metadata/src/main/java/org/apache/kylin/metadata/realization/RealizationRegistry.java
@@ -68,6 +68,10 @@ public class RealizationRegistry {
CACHE.clear();
}
+ public static void clearCache(KylinConfig kylinConfig) {
+ CACHE.remove(kylinConfig);
+ }
+
// ============================================================================
private Map<RealizationType, IRealizationProvider> providers;
http://git-wip-us.apache.org/repos/asf/kylin/blob/4f20ba32/core-storage/src/main/java/org/apache/kylin/storage/hybrid/HybridManager.java
----------------------------------------------------------------------
diff --git a/core-storage/src/main/java/org/apache/kylin/storage/hybrid/HybridManager.java b/core-storage/src/main/java/org/apache/kylin/storage/hybrid/HybridManager.java
index cf40416..114f2c7 100644
--- a/core-storage/src/main/java/org/apache/kylin/storage/hybrid/HybridManager.java
+++ b/core-storage/src/main/java/org/apache/kylin/storage/hybrid/HybridManager.java
@@ -79,6 +79,11 @@ public class HybridManager implements IRealizationProvider {
CACHE.clear();
}
+ public static void clearCache(KylinConfig kylinConfig) {
+ if (kylinConfig != null)
+ CACHE.remove(kylinConfig);
+ }
+
// ============================================================================
private KylinConfig config;
[29/50] kylin git commit: KYLIN-2676 Allow backup operation copying
UUID
Posted by li...@apache.org.
KYLIN-2676 Allow backup operation copying UUID
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/071f3b92
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/071f3b92
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/071f3b92
Branch: refs/heads/master
Commit: 071f3b92caccf56ed70c15147da32a9ef2538bff
Parents: 57c1d5e
Author: auphyroc99 <45...@qq.com>
Authored: Thu Jun 22 17:10:58 2017 +0800
Committer: Hongbin Ma <ma...@kyligence.io>
Committed: Thu Jun 22 18:05:21 2017 +0800
----------------------------------------------------------------------
.../kylin/common/persistence/ResourceTool.java | 40 ++++++++++++++------
.../apache/kylin/tool/CubeMetaExtractor.java | 4 +-
2 files changed, 31 insertions(+), 13 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/071f3b92/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 6a73e12..2571c91 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
@@ -72,10 +72,10 @@ public class ResourceTool {
list(KylinConfig.getInstanceFromEnv(), args[1]);
break;
case "download":
- copy(KylinConfig.getInstanceFromEnv(), KylinConfig.createInstanceFromUri(args[1]));
+ copy(KylinConfig.getInstanceFromEnv(), KylinConfig.createInstanceFromUri(args[1]), true);
break;
case "fetch":
- copy(KylinConfig.getInstanceFromEnv(), KylinConfig.createInstanceFromUri(args[1]), args[2]);
+ copy(KylinConfig.getInstanceFromEnv(), KylinConfig.createInstanceFromUri(args[1]), args[2], true);
break;
case "upload":
copy(KylinConfig.createInstanceFromUri(args[1]), KylinConfig.getInstanceFromEnv());
@@ -150,37 +150,54 @@ public class ResourceTool {
System.out.println("" + result);
return result;
}
+
+ public static void copy(KylinConfig srcConfig, KylinConfig dstConfig, String path) throws IOException {
+ copy(srcConfig, dstConfig, path, false);
+ }
- public static void copy(KylinConfig srcConfig, KylinConfig dstConfig, String path) throws IOException {
+ //Do NOT invoke this method directly, unless you want to copy and possibly overwrite immutable resources such as UUID.
+ public static void copy(KylinConfig srcConfig, KylinConfig dstConfig, String path, boolean copyImmutableResource) throws IOException {
ResourceStore src = ResourceStore.getStore(srcConfig);
ResourceStore dst = ResourceStore.getStore(dstConfig);
logger.info("Copy from {} to {}", src, dst);
- copyR(src, dst, path);
+ copyR(src, dst, path, copyImmutableResource);
}
- public static void copy(KylinConfig srcConfig, KylinConfig dstConfig, List<String> paths) throws IOException {
+ public static void copy(KylinConfig srcConfig, KylinConfig dstConfig, List<String> paths) throws IOException {
+ copy(srcConfig, dstConfig, paths, false);
+ }
+
+ //Do NOT invoke this method directly, unless you want to copy and possibly overwrite immutable resources such as UUID.
+ public static void copy(KylinConfig srcConfig, KylinConfig dstConfig, List<String> paths, boolean copyImmutableResource) throws IOException {
ResourceStore src = ResourceStore.getStore(srcConfig);
ResourceStore dst = ResourceStore.getStore(dstConfig);
logger.info("Copy from {} to {}", src, dst);
for (String path : paths) {
- copyR(src, dst, path);
+ copyR(src, dst, path, copyImmutableResource);
}
}
+
public static void copy(KylinConfig srcConfig, KylinConfig dstConfig) throws IOException {
- copy(srcConfig, dstConfig, "/");
+ copy(srcConfig, dstConfig, false);
}
-
- public static void copyR(ResourceStore src, ResourceStore dst, String path) throws IOException {
+
+ //Do NOT invoke this method directly, unless you want to copy and possibly overwrite immutable resources such as UUID.
+ public static void copy(KylinConfig srcConfig, KylinConfig dstConfig, boolean copyImmutableResource) throws IOException {
+ copy(srcConfig, dstConfig, "/", copyImmutableResource);
+ }
+
+ public static void copyR(ResourceStore src, ResourceStore dst, String path, boolean copyImmutableResource) throws IOException {
+
NavigableSet<String> children = src.listResources(path);
if (children == null) {
// case of resource (not a folder)
- if (matchFilter(path)) {
+ if (copyImmutableResource || matchFilter(path)) {
try {
RawResource res = src.getResource(path);
if (res != null) {
@@ -197,8 +214,9 @@ public class ResourceTool {
} else {
// case of folder
for (String child : children)
- copyR(src, dst, child);
+ copyR(src, dst, child, copyImmutableResource);
}
+
}
private static boolean matchFilter(String path) {
http://git-wip-us.apache.org/repos/asf/kylin/blob/071f3b92/tool/src/main/java/org/apache/kylin/tool/CubeMetaExtractor.java
----------------------------------------------------------------------
diff --git a/tool/src/main/java/org/apache/kylin/tool/CubeMetaExtractor.java b/tool/src/main/java/org/apache/kylin/tool/CubeMetaExtractor.java
index 30bbb5e..bc8f34f 100644
--- a/tool/src/main/java/org/apache/kylin/tool/CubeMetaExtractor.java
+++ b/tool/src/main/java/org/apache/kylin/tool/CubeMetaExtractor.java
@@ -232,11 +232,11 @@ public class CubeMetaExtractor extends AbstractInfoExtractor {
KylinConfig srcConfig = KylinConfig.getInstanceFromEnv();
KylinConfig dstConfig = KylinConfig.createInstanceFromUri(dest);
- ResourceTool.copy(srcConfig, dstConfig, Lists.newArrayList(requiredResources));
+ ResourceTool.copy(srcConfig, dstConfig, Lists.newArrayList(requiredResources), true);
for (String r : optionalResources) {
try {
- ResourceTool.copy(srcConfig, dstConfig, Lists.newArrayList(r));
+ ResourceTool.copy(srcConfig, dstConfig, Lists.newArrayList(r), true);
} catch (Exception e) {
logger.warn("Exception when copying optional resource {}. May be caused by resource missing. skip it.", r);
}
[19/50] kylin git commit: minor,
disallow empty joint and hierarchy groups
Posted by li...@apache.org.
minor, disallow empty joint and hierarchy groups
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/4d2a548a
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/4d2a548a
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/4d2a548a
Branch: refs/heads/master
Commit: 4d2a548accba5aa70ad7c2bcc405882a44fe9aae
Parents: 361b58d
Author: lidongsjtu <li...@apache.org>
Authored: Mon Jun 19 18:50:56 2017 +0800
Committer: Roger Shi <ro...@gmail.com>
Committed: Mon Jun 19 18:56:33 2017 +0800
----------------------------------------------------------------------
.../java/org/apache/kylin/cube/model/CubeDesc.java | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/4d2a548a/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 4318570..91f985c 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
@@ -707,11 +707,11 @@ public class CubeDesc extends RootPersistentEntity implements IEngineAware {
throw new IllegalStateException("Aggregation group " + index + " hierarchy dimensions overlap with joint dimensions: " + ensureOrder(CollectionUtils.intersection(hierarchyDims, jointDims)));
}
- if (hasSingle(hierarchyDimsList)) {
+ if (hasSingleOrNone(hierarchyDimsList)) {
logger.error("Aggregation group " + index + " require at least 2 dimensions in a hierarchy");
throw new IllegalStateException("Aggregation group " + index + " require at least 2 dimensions in a hierarchy.");
}
- if (hasSingle(jointDimsList)) {
+ if (hasSingleOrNone(jointDimsList)) {
logger.error("Aggregation group " + index + " require at least 2 dimensions in a joint");
throw new IllegalStateException("Aggregation group " + index + " require at least 2 dimensions in a joint");
}
@@ -753,15 +753,15 @@ public class CubeDesc extends RootPersistentEntity implements IEngineAware {
}
}
- private boolean hasSingle(ArrayList<Set<String>> dimsList) {
- boolean hasSingle = false;
+ private boolean hasSingleOrNone(ArrayList<Set<String>> dimsList) {
+ boolean hasSingleOrNone = false;
for (Set<String> dims : dimsList) {
- if (dims.size() == 1) {
- hasSingle = true;
+ if (dims.size() <= 1) {
+ hasSingleOrNone = true;
break;
}
}
- return hasSingle;
+ return hasSingleOrNone;
}
private Pair<Boolean, Set<String>> hasOverlap(ArrayList<Set<String>> dimsList, Set<String> Dims) {
[28/50] kylin git commit: #1203 Move bin/setenv.sh to conf
Posted by li...@apache.org.
#1203 Move bin/setenv.sh to conf
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/57c1d5e0
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/57c1d5e0
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/57c1d5e0
Branch: refs/heads/master
Commit: 57c1d5e03f5cf07ccfb02f7711375c4aa72dd7a6
Parents: cfac81b
Author: Hongbin Ma <ma...@apache.org>
Authored: Thu Jun 22 15:24:20 2017 +0800
Committer: Roger Shi <ro...@gmail.com>
Committed: Thu Jun 22 17:59:14 2017 +0800
----------------------------------------------------------------------
build/bin/kylin.sh | 5 +++++
build/bin/setenv.sh | 57 -----------------------------------------------
build/conf/setenv.sh | 57 +++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 62 insertions(+), 57 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/57c1d5e0/build/bin/kylin.sh
----------------------------------------------------------------------
diff --git a/build/bin/kylin.sh b/build/bin/kylin.sh
index a5808fd..08c9075 100755
--- a/build/bin/kylin.sh
+++ b/build/bin/kylin.sh
@@ -41,8 +41,13 @@ function retrieveDependency() {
#retrive $KYLIN_EXTRA_START_OPTS
if [ -f "${dir}/setenv.sh" ]; then
+ echo "WARNING: ${dir}/setenv.sh is deprecated and ignored, please remove it and use ${KYLIN_HOME}/conf/setenv.sh instead"
source ${dir}/setenv.sh
fi
+
+ if [ -f "${KYLIN_HOME}/conf/setenv.sh" ]; then
+ source ${KYLIN_HOME}/conf/setenv.sh
+ fi
export HBASE_CLASSPATH_PREFIX=${KYLIN_HOME}/conf:${KYLIN_HOME}/lib/*:${KYLIN_HOME}/ext/*:${HBASE_CLASSPATH_PREFIX}
export HBASE_CLASSPATH=${HBASE_CLASSPATH}:${hive_dependency}:${kafka_dependency}:${spark_dependency}
http://git-wip-us.apache.org/repos/asf/kylin/blob/57c1d5e0/build/bin/setenv.sh
----------------------------------------------------------------------
diff --git a/build/bin/setenv.sh b/build/bin/setenv.sh
deleted file mode 100755
index 0e9b185..0000000
--- a/build/bin/setenv.sh
+++ /dev/null
@@ -1,57 +0,0 @@
-#!/bin/bash
-
-#
-# 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.
-#
-
-# source me
-
-# (if your're deploying KYLIN on a powerful server and want to replace the default conservative settings)
-# uncomment following to for it to take effect
-export KYLIN_JVM_SETTINGS="-Xms1024M -Xmx4096M -Xss1024K -XX:MaxPermSize=128M -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:$KYLIN_HOME/logs/kylin.gc.$$ -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=64M"
-# export KYLIN_JVM_SETTINGS="-Xms16g -Xmx16g -XX:MaxPermSize=512m -XX:NewSize=3g -XX:MaxNewSize=3g -XX:SurvivorRatio=4 -XX:+CMSClassUnloadingEnabled -XX:+CMSParallelRemarkEnabled -XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode -XX:CMSInitiatingOccupancyFraction=70 -XX:+UseCMSInitiatingOccupancyOnly -XX:+DisableExplicitGC -XX:+HeapDumpOnOutOfMemoryError"
-
-# uncomment following to for it to take effect(the values need adjusting to fit your env)
-# export KYLIN_DEBUG_SETTINGS="-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false"
-
-# uncomment following to for it to take effect(the values need adjusting to fit your env)
-# export KYLIN_LD_LIBRARY_SETTINGS="-Djava.library.path=/apache/hadoop/lib/native/Linux-amd64-64"
-
-export KYLIN_EXTRA_START_OPTS=""
-
-if [ ! -z "${KYLIN_JVM_SETTINGS}" ]
-then
- verbose "KYLIN_JVM_SETTINGS is ${KYLIN_JVM_SETTINGS}"
- KYLIN_EXTRA_START_OPTS="${KYLIN_JVM_SETTINGS} ${KYLIN_EXTRA_START_OPTS}"
-else
- verbose "KYLIN_JVM_SETTINGS is not set, using default jvm settings: ${KYLIN_JVM_SETTINGS}"
-fi
-
-if [ ! -z "${KYLIN_DEBUG_SETTINGS}" ]
-then
- verbose "KYLIN_DEBUG_SETTINGS is ${KYLIN_DEBUG_SETTINGS}"
- KYLIN_EXTRA_START_OPTS="${KYLIN_DEBUG_SETTINGS} ${KYLIN_EXTRA_START_OPTS}"
-else
- verbose "KYLIN_DEBUG_SETTINGS is not set, will not enable remote debuging"
-fi
-
-if [ ! -z "${KYLIN_LD_LIBRARY_SETTINGS}" ]
-then
- verbose "KYLIN_LD_LIBRARY_SETTINGS is ${KYLIN_LD_LIBRARY_SETTINGS}"
- KYLIN_EXTRA_START_OPTS="${KYLIN_LD_LIBRARY_SETTINGS} ${KYLIN_EXTRA_START_OPTS}"
-else
- verbose "KYLIN_LD_LIBRARY_SETTINGS is not set, it is okay unless you want to specify your own native path"
-fi
http://git-wip-us.apache.org/repos/asf/kylin/blob/57c1d5e0/build/conf/setenv.sh
----------------------------------------------------------------------
diff --git a/build/conf/setenv.sh b/build/conf/setenv.sh
new file mode 100755
index 0000000..0e9b185
--- /dev/null
+++ b/build/conf/setenv.sh
@@ -0,0 +1,57 @@
+#!/bin/bash
+
+#
+# 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.
+#
+
+# source me
+
+# (if your're deploying KYLIN on a powerful server and want to replace the default conservative settings)
+# uncomment following to for it to take effect
+export KYLIN_JVM_SETTINGS="-Xms1024M -Xmx4096M -Xss1024K -XX:MaxPermSize=128M -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:$KYLIN_HOME/logs/kylin.gc.$$ -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=64M"
+# export KYLIN_JVM_SETTINGS="-Xms16g -Xmx16g -XX:MaxPermSize=512m -XX:NewSize=3g -XX:MaxNewSize=3g -XX:SurvivorRatio=4 -XX:+CMSClassUnloadingEnabled -XX:+CMSParallelRemarkEnabled -XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode -XX:CMSInitiatingOccupancyFraction=70 -XX:+UseCMSInitiatingOccupancyOnly -XX:+DisableExplicitGC -XX:+HeapDumpOnOutOfMemoryError"
+
+# uncomment following to for it to take effect(the values need adjusting to fit your env)
+# export KYLIN_DEBUG_SETTINGS="-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false"
+
+# uncomment following to for it to take effect(the values need adjusting to fit your env)
+# export KYLIN_LD_LIBRARY_SETTINGS="-Djava.library.path=/apache/hadoop/lib/native/Linux-amd64-64"
+
+export KYLIN_EXTRA_START_OPTS=""
+
+if [ ! -z "${KYLIN_JVM_SETTINGS}" ]
+then
+ verbose "KYLIN_JVM_SETTINGS is ${KYLIN_JVM_SETTINGS}"
+ KYLIN_EXTRA_START_OPTS="${KYLIN_JVM_SETTINGS} ${KYLIN_EXTRA_START_OPTS}"
+else
+ verbose "KYLIN_JVM_SETTINGS is not set, using default jvm settings: ${KYLIN_JVM_SETTINGS}"
+fi
+
+if [ ! -z "${KYLIN_DEBUG_SETTINGS}" ]
+then
+ verbose "KYLIN_DEBUG_SETTINGS is ${KYLIN_DEBUG_SETTINGS}"
+ KYLIN_EXTRA_START_OPTS="${KYLIN_DEBUG_SETTINGS} ${KYLIN_EXTRA_START_OPTS}"
+else
+ verbose "KYLIN_DEBUG_SETTINGS is not set, will not enable remote debuging"
+fi
+
+if [ ! -z "${KYLIN_LD_LIBRARY_SETTINGS}" ]
+then
+ verbose "KYLIN_LD_LIBRARY_SETTINGS is ${KYLIN_LD_LIBRARY_SETTINGS}"
+ KYLIN_EXTRA_START_OPTS="${KYLIN_LD_LIBRARY_SETTINGS} ${KYLIN_EXTRA_START_OPTS}"
+else
+ verbose "KYLIN_LD_LIBRARY_SETTINGS is not set, it is okay unless you want to specify your own native path"
+fi
[49/50] kylin git commit: KYLIN-2686 The same project's computed
column's definition can not be same
Posted by li...@apache.org.
KYLIN-2686 The same project's computed column's definition can not be same
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/a0b7e74c
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/a0b7e74c
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/a0b7e74c
Branch: refs/heads/master
Commit: a0b7e74c16718bb7bab3eb093d6953c393f3444a
Parents: b2fc2c2
Author: Aron.tao <24...@qq.com>
Authored: Wed Jun 28 12:41:34 2017 +0800
Committer: Hongbin Ma <ma...@kyligence.io>
Committed: Wed Jun 28 14:04:24 2017 +0800
----------------------------------------------------------------------
.../kylin/metadata/model/DataModelDesc.java | 43 ++++++++++++++------
1 file changed, 31 insertions(+), 12 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/a0b7e74c/core-metadata/src/main/java/org/apache/kylin/metadata/model/DataModelDesc.java
----------------------------------------------------------------------
diff --git a/core-metadata/src/main/java/org/apache/kylin/metadata/model/DataModelDesc.java b/core-metadata/src/main/java/org/apache/kylin/metadata/model/DataModelDesc.java
index 7e08f1c..7de955e 100644
--- a/core-metadata/src/main/java/org/apache/kylin/metadata/model/DataModelDesc.java
+++ b/core-metadata/src/main/java/org/apache/kylin/metadata/model/DataModelDesc.java
@@ -471,33 +471,52 @@ public class DataModelDesc extends RootPersistentEntity {
}
private void initComputedColumns(Map<String, CCInfo> ccInfoMap) {
+ if (ccInfoMap == null) {
+ logger.error("cc info map is null");
+ }
+
Set<String> ccSet = Sets.newHashSet();//make sure cc name does not duplicate within this model
- for (ComputedColumnDesc computedColumnDesc : this.computedColumnDescs) {
- computedColumnDesc.init();
+ for (ComputedColumnDesc thisCCDesc : this.computedColumnDescs) {
+ thisCCDesc.init();
+ String thisCCName = thisCCDesc.getFullName();
- if (ccSet.contains(computedColumnDesc.getFullName())) {
- throw new IllegalArgumentException(
- String.format("More than one computed column named %s exist in model %s",
- computedColumnDesc.getFullName(), this.getName()));
+ if (ccSet.contains(thisCCName)) {
+ throw new IllegalArgumentException(String.format(
+ "More than one computed column named %s exist in model %s", thisCCName, this.getName()));
} else {
- ccSet.add(computedColumnDesc.getFullName());
+ ccSet.add(thisCCName);
}
- CCInfo other = ccInfoMap.get(computedColumnDesc.getFullName());
+ CCInfo other = ccInfoMap.get(thisCCName);
if (other == null || (other.getDataModelDescs().size() == 1 && other.getDataModelDescs().contains(this))) {
- ccInfoMap.put(computedColumnDesc.getFullName(),
- new CCInfo(computedColumnDesc, Sets.<DataModelDesc> newHashSet(this)));
- } else if (other.getComputedColumnDesc().equals(computedColumnDesc)) {
+ //check whether two computer columns's definition is the same.
+ for (CCInfo sysCCInfo : ccInfoMap.values()) {
+ String definition0 = thisCCDesc.getExpression();
+ String definition1 = sysCCInfo.getComputedColumnDesc().getExpression();
+ if (isTwoCCDefinitionEquals(definition0, definition1)) {
+ throw new IllegalStateException(String.format(
+ "Computed column %s'definition: %s is already defined in other models: %s. Please change another definition, or try to keep consistent definition",
+ thisCCName, definition0, sysCCInfo.getDataModelDescs()));
+ }
+ }
+ ccInfoMap.put(thisCCName, new CCInfo(thisCCDesc, Sets.<DataModelDesc> newHashSet(this)));
+ } else if (other.getComputedColumnDesc().equals(thisCCDesc)) {
other.getDataModelDescs().add(this);
} else {
throw new IllegalStateException(String.format(
"Computed column named %s is already defined in other models: %s. Please change another name, or try to keep consistent definition", //
- computedColumnDesc.getFullName(), other.getDataModelDescs()));
+ thisCCName, other.getDataModelDescs()));
}
}
}
+ private boolean isTwoCCDefinitionEquals(String definition0, String definition1) {
+ definition0 = definition0.replaceAll("\\s*", "");
+ definition1 = definition1.replaceAll("\\s*", "");
+ return definition0.equalsIgnoreCase(definition1);
+ }
+
private void initJoinColumns() {
for (JoinTableDesc joinTable : joinTables) {
[09/50] kylin git commit: refine stats and cubing job name (#1215)
Posted by li...@apache.org.
refine stats and cubing job name (#1215)
* minor, refine stats job name
* minor, rename CubingJob name
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/1c3329a8
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/1c3329a8
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/1c3329a8
Branch: refs/heads/master
Commit: 1c3329a89894b0825b07d58b7dcbafd983ebc036
Parents: d659bad
Author: 成 <ch...@kyligence.io>
Authored: Fri Jun 16 16:11:45 2017 +0800
Committer: luguosheng1314 <55...@qq.com>
Committed: Fri Jun 16 16:11:45 2017 +0800
----------------------------------------------------------------------
.../org/apache/kylin/engine/mr/CubingJob.java | 27 +++++++++++++-------
1 file changed, 18 insertions(+), 9 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/1c3329a8/engine-mr/src/main/java/org/apache/kylin/engine/mr/CubingJob.java
----------------------------------------------------------------------
diff --git a/engine-mr/src/main/java/org/apache/kylin/engine/mr/CubingJob.java b/engine-mr/src/main/java/org/apache/kylin/engine/mr/CubingJob.java
index 5aa7d72..466f706 100644
--- a/engine-mr/src/main/java/org/apache/kylin/engine/mr/CubingJob.java
+++ b/engine-mr/src/main/java/org/apache/kylin/engine/mr/CubingJob.java
@@ -80,11 +80,13 @@ public class CubingJob extends DefaultChainedExecutable {
private static CubingJob initCubingJob(CubeSegment seg, String jobType, String submitter, JobEngineConfig config) {
KylinConfig kylinConfig = config.getConfig();
CubeInstance cube = seg.getCubeInstance();
- List<ProjectInstance> projList = ProjectManager.getInstance(kylinConfig).findProjects(cube.getType(), cube.getName());
+ List<ProjectInstance> projList = ProjectManager.getInstance(kylinConfig).findProjects(cube.getType(),
+ cube.getName());
if (projList == null || projList.size() == 0) {
throw new RuntimeException("Cannot find the project containing the cube " + cube.getName() + "!!!");
} else if (projList.size() >= 2) {
- String msg = "Find more than one project containing the cube " + cube.getName() + ". It does't meet the uniqueness requirement!!! ";
+ String msg = "Find more than one project containing the cube " + cube.getName()
+ + ". It does't meet the uniqueness requirement!!! ";
if (!config.getConfig().allowCubeAppearInMultipleProjects()) {
throw new RuntimeException(msg);
} else {
@@ -99,7 +101,8 @@ public class CubingJob extends DefaultChainedExecutable {
result.setProjectName(projList.get(0).getName());
CubingExecutableUtil.setCubeName(seg.getCubeInstance().getName(), result.getParams());
CubingExecutableUtil.setSegmentId(seg.getUuid(), result.getParams());
- result.setName(seg.getCubeInstance().getName() + " - " + seg.getName() + " - " + jobType + " - " + format.format(new Date(System.currentTimeMillis())));
+ result.setName(jobType + " CUBE - " + seg.getCubeInstance().getName() + " - " + seg.getName() + " - "
+ + format.format(new Date(System.currentTimeMillis())));
result.setSubmitter(submitter);
result.setNotifyList(seg.getCubeInstance().getDescriptor().getNotifyList());
return result;
@@ -127,11 +130,13 @@ public class CubingJob extends DefaultChainedExecutable {
@Override
protected Pair<String, String> formatNotifications(ExecutableContext context, ExecutableState state) {
- CubeInstance cubeInstance = CubeManager.getInstance(context.getConfig()).getCube(CubingExecutableUtil.getCubeName(this.getParams()));
+ CubeInstance cubeInstance = CubeManager.getInstance(context.getConfig())
+ .getCube(CubingExecutableUtil.getCubeName(this.getParams()));
final Output output = getManager().getOutput(getId());
String logMsg;
state = output.getState();
- if (state != ExecutableState.ERROR && !cubeInstance.getDescriptor().getStatusNeedNotify().contains(state.toString())) {
+ if (state != ExecutableState.ERROR
+ && !cubeInstance.getDescriptor().getStatusNeedNotify().contains(state.toString())) {
logger.info("state:" + state + " no need to notify users");
return null;
}
@@ -160,7 +165,8 @@ public class CubingJob extends DefaultChainedExecutable {
content = content.replaceAll("\\$\\{mr_waiting\\}", getMapReduceWaitTime() / 60000 + "mins");
content = content.replaceAll("\\$\\{last_update_time\\}", new Date(getLastModified()).toString());
content = content.replaceAll("\\$\\{submitter\\}", StringUtil.noBlank(getSubmitter(), "missing submitter"));
- content = content.replaceAll("\\$\\{error_log\\}", Matcher.quoteReplacement(StringUtil.noBlank(logMsg, "no error message")));
+ content = content.replaceAll("\\$\\{error_log\\}",
+ Matcher.quoteReplacement(StringUtil.noBlank(logMsg, "no error message")));
try {
InetAddress inetAddress = InetAddress.getLocalHost();
@@ -169,7 +175,8 @@ public class CubingJob extends DefaultChainedExecutable {
logger.warn(e.getLocalizedMessage(), e);
}
- String title = "[" + state.toString() + "] - [" + getDeployEnvName() + "] - [" + getProjectName() + "] - " + CubingExecutableUtil.getCubeName(this.getParams());
+ String title = "[" + state.toString() + "] - [" + getDeployEnvName() + "] - [" + getProjectName() + "] - "
+ + CubingExecutableUtil.getCubeName(this.getParams());
return Pair.of(title, content);
}
@@ -196,7 +203,8 @@ public class CubingJob extends DefaultChainedExecutable {
*/
@Override
protected void handleMetaDataPersistException(Exception exception) {
- String title = "[ERROR] - [" + getDeployEnvName() + "] - [" + getProjectName() + "] - " + CubingExecutableUtil.getCubeName(this.getParams());
+ String title = "[ERROR] - [" + getDeployEnvName() + "] - [" + getProjectName() + "] - "
+ + CubingExecutableUtil.getCubeName(this.getParams());
String content = ExecutableConstants.NOTIFY_EMAIL_TEMPLATE;
final String UNKNOWN = "UNKNOWN";
String errMsg = null;
@@ -217,7 +225,8 @@ public class CubingJob extends DefaultChainedExecutable {
content = content.replaceAll("\\$\\{mr_waiting\\}", UNKNOWN);
content = content.replaceAll("\\$\\{last_update_time\\}", UNKNOWN);
content = content.replaceAll("\\$\\{submitter\\}", StringUtil.noBlank(getSubmitter(), "missing submitter"));
- content = content.replaceAll("\\$\\{error_log\\}", Matcher.quoteReplacement(StringUtil.noBlank(errMsg, "no error message")));
+ content = content.replaceAll("\\$\\{error_log\\}",
+ Matcher.quoteReplacement(StringUtil.noBlank(errMsg, "no error message")));
try {
InetAddress inetAddress = InetAddress.getLocalHost();
[23/50] kylin git commit: fix AccessService not returning parent obj
ACL
Posted by li...@apache.org.
fix AccessService not returning parent obj ACL
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/73faf991
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/73faf991
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/73faf991
Branch: refs/heads/master
Commit: 73faf9917a788a7875691c019501f623e91c8107
Parents: 73bd033
Author: Li Yang <li...@apache.org>
Authored: Tue Jun 20 17:37:49 2017 +0800
Committer: Roger Shi <ro...@gmail.com>
Committed: Tue Jun 20 17:58:52 2017 +0800
----------------------------------------------------------------------
.../kylin/rest/service/AccessService.java | 20 +++++++++-----------
1 file changed, 9 insertions(+), 11 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/73faf991/server-base/src/main/java/org/apache/kylin/rest/service/AccessService.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/service/AccessService.java b/server-base/src/main/java/org/apache/kylin/rest/service/AccessService.java
index 9ae372a..8b96635 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/service/AccessService.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/service/AccessService.java
@@ -19,7 +19,6 @@
package org.apache.kylin.rest.service;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.List;
import org.apache.kylin.common.persistence.AclEntity;
@@ -298,18 +297,16 @@ public class AccessService {
}
public List<AccessEntryResponse> generateAceResponses(Acl acl) {
- if (null == acl) {
- return Collections.emptyList();
- }
- List<AccessEntryResponse> accessControlEntities = new ArrayList<AccessEntryResponse>();
+ List<AccessEntryResponse> result = new ArrayList<AccessEntryResponse>();
- // Cause there is a circle reference in AccessControlEntry, it needs to
- // set acl to null as a workaround.
- for (AccessControlEntry ace : acl.getEntries()) {
- accessControlEntities.add(new AccessEntryResponse(ace.getId(), ace.getSid(), ace.getPermission(), ace.isGranting()));
+ while (acl != null) {
+ for (AccessControlEntry ace : acl.getEntries()) {
+ result.add(new AccessEntryResponse(ace.getId(), ace.getSid(), ace.getPermission(), ace.isGranting()));
+ }
+ acl = acl.getParentAcl();
}
- return accessControlEntities;
+ return result;
}
/**
@@ -322,7 +319,8 @@ public class AccessService {
Message msg = MsgPicker.getMsg();
// Can't revoke admin permission from domain object owner
- if (acl.getOwner().equals(acl.getEntries().get(indexOfAce).getSid()) && BasePermission.ADMINISTRATION.equals(acl.getEntries().get(indexOfAce).getPermission())) {
+ if (acl.getOwner().equals(acl.getEntries().get(indexOfAce).getSid())
+ && BasePermission.ADMINISTRATION.equals(acl.getEntries().get(indexOfAce).getPermission())) {
throw new ForbiddenException(msg.getREVOKE_ADMIN_PERMISSION());
}
}
[30/50] kylin git commit: minor,
introduce ManagedUser to replace Spring User
Posted by li...@apache.org.
minor, introduce ManagedUser to replace Spring User
temp
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/cf2f27a3
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/cf2f27a3
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/cf2f27a3
Branch: refs/heads/master
Commit: cf2f27a3a8ffc41d5d909ff2b4fd38887305fe9d
Parents: 071f3b9
Author: Hongbin Ma <ma...@apache.org>
Authored: Thu Jun 22 14:52:28 2017 +0800
Committer: Hongbin Ma <ma...@kyligence.io>
Committed: Thu Jun 22 18:26:32 2017 +0800
----------------------------------------------------------------------
.../rest/controller2/QueryControllerV2.java | 6 +
.../security/KylinAuthenticationProvider.java | 16 +-
.../kylin/rest/security/LdapProvider.java | 107 ---------
.../apache/kylin/rest/security/ManagedUser.java | 235 +++++++++++++++++++
.../rest/service/AclTableMigrationTool.java | 64 ++---
.../rest/service/UserGrantedAuthority.java | 5 +
.../org/apache/kylin/rest/service/UserInfo.java | 82 -------
.../apache/kylin/rest/service/UserService.java | 48 ++--
server/src/main/resources/kylinSecurity.xml | 4 +-
.../rest/controller/UserControllerTest.java | 4 +-
.../kylin/rest/service/ServiceTestBase.java | 15 +-
.../kylin/rest/service/UserServiceTest.java | 8 +-
12 files changed, 318 insertions(+), 276 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/cf2f27a3/server-base/src/main/java/org/apache/kylin/rest/controller2/QueryControllerV2.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/controller2/QueryControllerV2.java b/server-base/src/main/java/org/apache/kylin/rest/controller2/QueryControllerV2.java
index a641a53..a1b65a0 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/controller2/QueryControllerV2.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/controller2/QueryControllerV2.java
@@ -23,10 +23,13 @@ import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import javax.servlet.http.HttpServletResponse;
+import com.google.common.collect.Maps;
import org.apache.commons.io.IOUtils;
+import org.apache.kylin.common.debug.BackdoorToggles;
import org.apache.kylin.metadata.querymeta.SelectedColumnMeta;
import org.apache.kylin.rest.controller.BasicController;
import org.apache.kylin.rest.exception.InternalErrorException;
@@ -84,6 +87,9 @@ public class QueryControllerV2 extends BasicController {
"application/vnd.apache.kylin-v2+json" })
@ResponseBody
public EnvelopeResponse prepareQueryV2(@RequestBody PrepareSqlRequest sqlRequest) {
+ Map<String, String> toggles = Maps.newHashMap();
+ toggles.put(BackdoorToggles.DEBUG_TOGGLE_PREPARE_ONLY, "true");
+ BackdoorToggles.addToggles(toggles);
return new EnvelopeResponse(ResponseCode.CODE_SUCCESS, queryService.doQueryWithCache(sqlRequest), "");
}
http://git-wip-us.apache.org/repos/asf/kylin/blob/cf2f27a3/server-base/src/main/java/org/apache/kylin/rest/security/KylinAuthenticationProvider.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/security/KylinAuthenticationProvider.java b/server-base/src/main/java/org/apache/kylin/rest/security/KylinAuthenticationProvider.java
index dc475c9..7322b84 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/security/KylinAuthenticationProvider.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/security/KylinAuthenticationProvider.java
@@ -18,8 +18,6 @@
package org.apache.kylin.rest.security;
-import com.google.common.hash.HashFunction;
-import com.google.common.hash.Hashing;
import org.apache.kylin.common.util.ByteArray;
import org.apache.kylin.rest.service.UserService;
import org.slf4j.Logger;
@@ -30,11 +28,13 @@ import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
-import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.util.Assert;
+import com.google.common.hash.HashFunction;
+import com.google.common.hash.Hashing;
+
import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;
@@ -87,17 +87,19 @@ public class KylinAuthenticationProvider implements AuthenticationProvider {
logger.debug("Authenticated user " + authed.toString());
- UserDetails user;
+ ManagedUser user;
if (authed.getDetails() == null) {
//authed.setAuthenticated(false);
- throw new UsernameNotFoundException("User not found in LDAP, check whether he/she has been added to the groups.");
+ throw new UsernameNotFoundException(
+ "User not found in LDAP, check whether he/she has been added to the groups.");
}
if (authed.getDetails() instanceof UserDetails) {
- user = (UserDetails) authed.getDetails();
+ UserDetails details = (UserDetails) authed.getDetails();
+ user = new ManagedUser(details.getUsername(), details.getPassword(), false, details.getAuthorities());
} else {
- user = new User(authentication.getName(), "skippped-ldap", authed.getAuthorities());
+ user = new ManagedUser(authentication.getName(), "skippped-ldap", false, authed.getAuthorities());
}
Assert.notNull(user, "The UserDetail is null.");
http://git-wip-us.apache.org/repos/asf/kylin/blob/cf2f27a3/server-base/src/main/java/org/apache/kylin/rest/security/LdapProvider.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/security/LdapProvider.java b/server-base/src/main/java/org/apache/kylin/rest/security/LdapProvider.java
deleted file mode 100644
index c76301b..0000000
--- a/server-base/src/main/java/org/apache/kylin/rest/security/LdapProvider.java
+++ /dev/null
@@ -1,107 +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.
-*/
-
-package org.apache.kylin.rest.security;
-
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.util.Arrays;
-
-import org.apache.kylin.rest.service.UserService;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Qualifier;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.AuthenticationException;
-import org.springframework.security.core.context.SecurityContextHolder;
-import org.springframework.security.core.userdetails.User;
-import org.springframework.security.core.userdetails.UserDetails;
-import org.springframework.security.ldap.authentication.LdapAuthenticationProvider;
-import org.springframework.security.ldap.authentication.LdapAuthenticator;
-import org.springframework.security.ldap.userdetails.LdapAuthoritiesPopulator;
-
-import net.sf.ehcache.Cache;
-import net.sf.ehcache.CacheManager;
-import net.sf.ehcache.Element;
-
-/**
- * @author xduo
- * @deprecated replaced by KylinAuthenticationProvider
- *
- */
-public class LdapProvider extends LdapAuthenticationProvider {
-
- private static final Logger logger = LoggerFactory.getLogger(LdapProvider.class);
-
- @Autowired
- @Qualifier("userService")
- UserService userService;
-
- @Autowired
- private CacheManager cacheManager;
-
- MessageDigest md = null;
-
- /**
- * @param authenticator
- * @param authoritiesPopulator
- */
- public LdapProvider(LdapAuthenticator authenticator, LdapAuthoritiesPopulator authoritiesPopulator) {
- super(authenticator, authoritiesPopulator);
-
- try {
- md = MessageDigest.getInstance("MD5");
- } catch (NoSuchAlgorithmException e) {
- throw new RuntimeException("Failed to init Message Digest ", e);
- }
- }
-
- @Override
- public Authentication authenticate(Authentication authentication) throws AuthenticationException {
- Authentication authed = null;
- Cache userCache = cacheManager.getCache("UserCache");
- md.reset();
- byte[] hashKey = md.digest((authentication.getName() + authentication.getCredentials()).getBytes());
- String userKey = Arrays.toString(hashKey);
-
- Element authedUser = userCache.get(userKey);
- if (null != authedUser) {
- authed = (Authentication) authedUser.getObjectValue();
- SecurityContextHolder.getContext().setAuthentication(authed);
- } else {
- try {
- authed = super.authenticate(authentication);
- userCache.put(new Element(userKey, authed));
- } catch (AuthenticationException e) {
- logger.error("Failed to auth user: " + authentication.getName(), e);
- throw e;
- }
-
- UserDetails user = new User(authentication.getName(), "skippped-ldap", authed.getAuthorities());
-
- if (!userService.userExists(authentication.getName())) {
- userService.createUser(user);
- } else {
- userService.updateUser(user);
- }
- }
-
- return authed;
- }
-}
http://git-wip-us.apache.org/repos/asf/kylin/blob/cf2f27a3/server-base/src/main/java/org/apache/kylin/rest/security/ManagedUser.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/security/ManagedUser.java b/server-base/src/main/java/org/apache/kylin/rest/security/ManagedUser.java
new file mode 100644
index 0000000..4805d5c
--- /dev/null
+++ b/server-base/src/main/java/org/apache/kylin/rest/security/ManagedUser.java
@@ -0,0 +1,235 @@
+/*
+ * 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.rest.security;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.annotation.Nullable;
+
+import org.apache.kylin.common.persistence.RootPersistentEntity;
+import org.apache.kylin.rest.service.UserGrantedAuthority;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.userdetails.UserDetails;
+
+import com.fasterxml.jackson.annotation.JsonAutoDetect;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.google.common.base.Function;
+import com.google.common.collect.Collections2;
+import com.google.common.collect.Lists;
+
+@SuppressWarnings("serial")
+@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.NONE, getterVisibility = JsonAutoDetect.Visibility.NONE, isGetterVisibility = JsonAutoDetect.Visibility.NONE, setterVisibility = JsonAutoDetect.Visibility.NONE)
+public class ManagedUser extends RootPersistentEntity implements UserDetails {
+
+ @JsonProperty
+ private String username;
+ @JsonProperty
+ private String password;
+ @JsonProperty
+ private List<String> authorities = Lists.newArrayList();
+ @JsonProperty
+ private boolean disabled = false;
+ @JsonProperty
+ private boolean defaultPassword = false;
+ @JsonProperty
+ private boolean locked = false;
+ @JsonProperty
+ private long lockedTime = 0L;
+ @JsonProperty
+ private int wrongTime = 0;
+
+ private Boolean legacyCatered = false;
+ //DISABLED_ROLE is a ancient way to represent disabled user
+ //now we no longer support such way, however legacy metadata may still contain it
+ private static final String DISABLED_ROLE = "--disabled--";
+
+ //this is computed
+ private List<UserGrantedAuthority> grantedAuthorities = null;
+
+ public ManagedUser() {
+ }
+
+ public ManagedUser(String username, String password, Boolean defaultPassword, String... authorities) {
+ this.username = username;
+ this.password = password;
+ this.setDefaultPassword(defaultPassword);
+
+ this.authorities = Lists.newArrayList(authorities);
+ this.grantedAuthorities = null;
+ }
+
+ public ManagedUser(String username, String password, Boolean defaultPassword,
+ Collection<? extends GrantedAuthority> grantedAuthorities) {
+ this.username = username;
+ this.password = password;
+ this.setDefaultPassword(defaultPassword);
+
+ this.setGrantedAuthorities(grantedAuthorities);
+ }
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String userName) {
+ this.username = userName;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ private void caterLegacy() {
+ if (!legacyCatered) {
+ synchronized (legacyCatered) {
+ Iterator<String> iterator = authorities.iterator();
+ while (iterator.hasNext()) {
+ if (DISABLED_ROLE.equals(iterator.next())) {
+ iterator.remove();
+ this.disabled = true;
+ }
+ }
+ legacyCatered = true;
+ }
+ }
+ }
+
+ public List<UserGrantedAuthority> getAuthorities() {
+ caterLegacy();
+ if (grantedAuthorities == null) {
+ grantedAuthorities = Lists.newArrayList();
+ for (String a : authorities) {
+ this.grantedAuthorities.add(new UserGrantedAuthority(a));
+ }
+ }
+ return grantedAuthorities;
+ }
+
+ public void setGrantedAuthorities(Collection<? extends GrantedAuthority> grantedAuthorities) {
+ this.authorities = Lists
+ .newArrayList(Collections2.transform(grantedAuthorities, new Function<GrantedAuthority, String>() {
+ @Nullable
+ @Override
+ public String apply(@Nullable GrantedAuthority input) {
+ return input.getAuthority();
+ }
+ }));
+ this.grantedAuthorities = null;
+ }
+
+ public boolean isDisabled() {
+ caterLegacy();
+ return disabled;
+ }
+
+ public void setDisabled(boolean disabled) {
+ this.disabled = disabled;
+ }
+
+ public boolean isDefaultPassword() {
+ return defaultPassword;
+ }
+
+ public void setDefaultPassword(boolean defaultPassword) {
+ this.defaultPassword = defaultPassword;
+ }
+
+ public boolean isLocked() {
+ return locked;
+ }
+
+ public void setLocked(boolean locked) {
+ this.locked = locked;
+ }
+
+ public int getWrongTime() {
+ return wrongTime;
+ }
+
+ public long getLockedTime() {
+ return lockedTime;
+ }
+
+ public void increaseWrongTime() {
+ int wrongTime = this.getWrongTime();
+ if (wrongTime == 2) {
+ this.setLocked(true);
+ this.lockedTime = System.currentTimeMillis();
+ this.wrongTime = 0;
+ } else {
+ this.wrongTime = wrongTime + 1;
+ }
+ }
+
+ @Override
+ public boolean isAccountNonExpired() {
+ return true;
+ }
+
+ @Override
+ public boolean isAccountNonLocked() {
+ return !locked;
+ }
+
+ @Override
+ public boolean isCredentialsNonExpired() {
+ return true;
+ }
+
+ @Override
+ public boolean isEnabled() {
+ return !disabled;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((username == null) ? 0 : username.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ ManagedUser other = (ManagedUser) obj;
+ if (username == null) {
+ if (other.username != null)
+ return false;
+ } else if (!username.equals(other.username))
+ return false;
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ return "KapManagedUser [username=" + username + ", authorities=" + grantedAuthorities + "]";
+ }
+}
http://git-wip-us.apache.org/repos/asf/kylin/blob/cf2f27a3/server-base/src/main/java/org/apache/kylin/rest/service/AclTableMigrationTool.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/service/AclTableMigrationTool.java b/server-base/src/main/java/org/apache/kylin/rest/service/AclTableMigrationTool.java
index fc50410..64bac23 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/service/AclTableMigrationTool.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/service/AclTableMigrationTool.java
@@ -19,7 +19,6 @@
package org.apache.kylin.rest.service;
import java.io.IOException;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
@@ -40,6 +39,7 @@ import org.apache.kylin.common.persistence.ResourceStore;
import org.apache.kylin.common.persistence.StringEntity;
import org.apache.kylin.common.util.Bytes;
import org.apache.kylin.rest.security.AclConstant;
+import org.apache.kylin.rest.security.ManagedUser;
import org.apache.kylin.rest.util.Serializer;
import org.apache.kylin.storage.hbase.HBaseConnection;
import org.apache.kylin.storage.hbase.HBaseResourceStore;
@@ -53,11 +53,13 @@ public class AclTableMigrationTool {
private static final Serializer<SidInfo> sidSerializer = new Serializer<SidInfo>(SidInfo.class);
- private static final Serializer<DomainObjectInfo> domainObjSerializer = new Serializer<DomainObjectInfo>(DomainObjectInfo.class);
+ private static final Serializer<DomainObjectInfo> domainObjSerializer = new Serializer<DomainObjectInfo>(
+ DomainObjectInfo.class);
private static final Serializer<AceInfo> aceSerializer = new Serializer<AceInfo>(AceInfo.class);
- private static final Serializer<UserGrantedAuthority[]> ugaSerializer = new Serializer<UserGrantedAuthority[]>(UserGrantedAuthority[].class);
+ private static final Serializer<UserGrantedAuthority[]> ugaSerializer = new Serializer<UserGrantedAuthority[]>(
+ UserGrantedAuthority[].class);
public static final String MIGRATE_OK_PREFIX = "MIGRATE_OK_";
@@ -69,7 +71,8 @@ public class AclTableMigrationTool {
return;
} else {
if (!kylinConfig.getServerMode().equals("all")) {
- throw new IllegalStateException("Please make sure that you have config kylin.server.mode=all before migrating data");
+ throw new IllegalStateException(
+ "Please make sure that you have config kylin.server.mode=all before migrating data");
}
logger.info("Start to migrate acl table data");
ResourceStore store = ResourceStore.getStore(kylinConfig);
@@ -144,11 +147,9 @@ public class AclTableMigrationTool {
return;
Result result = rs.next();
while (result != null) {
- User user = hbaseRowToUser(result);
- UserInfo userInfo = convert(user);
- store.deleteResource(UserService.getId(userInfo.getUsername()));
- store.putResource(UserService.getId(userInfo.getUsername()), userInfo, 0,
- UserService.SERIALIZER);
+ ManagedUser user = hbaseRowToUser(result);
+ store.deleteResource(UserService.getId(user.getUsername()));
+ store.putResource(UserService.getId(user.getUsername()), user, 0, UserService.SERIALIZER);
result = rs.next();
}
}
@@ -172,7 +173,8 @@ public class AclTableMigrationTool {
return store.exists(MIGRATE_OK_PREFIX + tableName);
}
- private void convertToResourceStore(KylinConfig kylinConfig, String tableName, ResourceStore store, ResultConverter converter) throws IOException {
+ private void convertToResourceStore(KylinConfig kylinConfig, String tableName, ResourceStore store,
+ ResultConverter converter) throws IOException {
Table table = null;
ResultScanner rs = null;
@@ -181,7 +183,8 @@ public class AclTableMigrationTool {
table = HBaseConnection.get(kylinConfig.getStorageUrl()).getTable(TableName.valueOf(tableName));
rs = table.getScanner(scan);
converter.convertResult(rs, store);
- store.putResource(MIGRATE_OK_PREFIX + tableName, new StringEntity(tableName + " migrated"), StringEntity.serializer);
+ store.putResource(MIGRATE_OK_PREFIX + tableName, new StringEntity(tableName + " migrated"),
+ StringEntity.serializer);
} finally {
IOUtils.closeQuietly(rs);
IOUtils.closeQuietly(table);
@@ -190,7 +193,8 @@ public class AclTableMigrationTool {
}
private DomainObjectInfo getDomainObjectInfoFromRs(Result result) {
- String type = String.valueOf(result.getValue(Bytes.toBytes(AclConstant.ACL_INFO_FAMILY), Bytes.toBytes(AclConstant.ACL_INFO_FAMILY_TYPE_COLUMN)));
+ String type = String.valueOf(result.getValue(Bytes.toBytes(AclConstant.ACL_INFO_FAMILY),
+ Bytes.toBytes(AclConstant.ACL_INFO_FAMILY_TYPE_COLUMN)));
String id = new String(result.getRow());
DomainObjectInfo newInfo = new DomainObjectInfo();
newInfo.setId(id);
@@ -199,17 +203,20 @@ public class AclTableMigrationTool {
}
private DomainObjectInfo getParentDomainObjectInfoFromRs(Result result) throws IOException {
- DomainObjectInfo parentInfo = domainObjSerializer.deserialize(result.getValue(Bytes.toBytes(AclConstant.ACL_INFO_FAMILY), Bytes.toBytes(AclConstant.ACL_INFO_FAMILY_PARENT_COLUMN)));
+ DomainObjectInfo parentInfo = domainObjSerializer.deserialize(result.getValue(
+ Bytes.toBytes(AclConstant.ACL_INFO_FAMILY), Bytes.toBytes(AclConstant.ACL_INFO_FAMILY_PARENT_COLUMN)));
return parentInfo;
}
private boolean getInheriting(Result result) {
- boolean entriesInheriting = Bytes.toBoolean(result.getValue(Bytes.toBytes(AclConstant.ACL_INFO_FAMILY), Bytes.toBytes(AclConstant.ACL_INFO_FAMILY_ENTRY_INHERIT_COLUMN)));
+ boolean entriesInheriting = Bytes.toBoolean(result.getValue(Bytes.toBytes(AclConstant.ACL_INFO_FAMILY),
+ Bytes.toBytes(AclConstant.ACL_INFO_FAMILY_ENTRY_INHERIT_COLUMN)));
return entriesInheriting;
}
private SidInfo getOwnerSidInfo(Result result) throws IOException {
- SidInfo owner = sidSerializer.deserialize(result.getValue(Bytes.toBytes(AclConstant.ACL_INFO_FAMILY), Bytes.toBytes(AclConstant.ACL_INFO_FAMILY_OWNER_COLUMN)));
+ SidInfo owner = sidSerializer.deserialize(result.getValue(Bytes.toBytes(AclConstant.ACL_INFO_FAMILY),
+ Bytes.toBytes(AclConstant.ACL_INFO_FAMILY_OWNER_COLUMN)));
return owner;
}
@@ -226,27 +233,14 @@ public class AclTableMigrationTool {
return allAceInfoMap;
}
- private UserInfo convert(User user) {
- if (user == null)
- return null;
- UserInfo newInfo = new UserInfo();
- newInfo.setUsername(user.getUserName());
- newInfo.setPassword(user.getPassword());
- List<String> authorities = new ArrayList<>();
- for (String auth : user.getAuthorities()) {
- authorities.add(auth);
- }
- newInfo.setAuthorities(authorities);
- return newInfo;
- }
-
- private User hbaseRowToUser(Result result) throws JsonParseException, JsonMappingException, IOException {
+ private ManagedUser hbaseRowToUser(Result result) throws JsonParseException, JsonMappingException, IOException {
if (null == result || result.isEmpty())
return null;
String username = Bytes.toString(result.getRow());
- byte[] valueBytes = result.getValue(Bytes.toBytes(AclConstant.USER_AUTHORITY_FAMILY), Bytes.toBytes(AclConstant.USER_AUTHORITY_COLUMN));
+ byte[] valueBytes = result.getValue(Bytes.toBytes(AclConstant.USER_AUTHORITY_FAMILY),
+ Bytes.toBytes(AclConstant.USER_AUTHORITY_COLUMN));
UserGrantedAuthority[] deserialized = ugaSerializer.deserialize(valueBytes);
String password = "";
@@ -261,13 +255,7 @@ public class AclTableMigrationTool {
authorities = Arrays.asList(deserialized);
}
}
- List<String> authoritiesStr = new ArrayList<>();
- for (UserGrantedAuthority auth : authorities) {
- if (auth != null) {
- authoritiesStr.add(auth.getAuthority());
- }
- }
- return new User(username, password, authoritiesStr);
+ return new ManagedUser(username, password, false, authorities);
}
interface ResultConverter {
http://git-wip-us.apache.org/repos/asf/kylin/blob/cf2f27a3/server-base/src/main/java/org/apache/kylin/rest/service/UserGrantedAuthority.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/service/UserGrantedAuthority.java b/server-base/src/main/java/org/apache/kylin/rest/service/UserGrantedAuthority.java
index 4c2a392..1227177 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/service/UserGrantedAuthority.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/service/UserGrantedAuthority.java
@@ -20,10 +20,15 @@ package org.apache.kylin.rest.service;
import org.springframework.security.core.GrantedAuthority;
+import com.fasterxml.jackson.annotation.JsonAutoDetect;
+import com.fasterxml.jackson.annotation.JsonProperty;
+@SuppressWarnings("serial")
+@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.NONE, getterVisibility = JsonAutoDetect.Visibility.NONE, isGetterVisibility = JsonAutoDetect.Visibility.NONE, setterVisibility = JsonAutoDetect.Visibility.NONE)
public class UserGrantedAuthority implements GrantedAuthority {
private static final long serialVersionUID = -5128905636841891058L;
+ @JsonProperty
private String authority;
public UserGrantedAuthority() {
http://git-wip-us.apache.org/repos/asf/kylin/blob/cf2f27a3/server-base/src/main/java/org/apache/kylin/rest/service/UserInfo.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/service/UserInfo.java b/server-base/src/main/java/org/apache/kylin/rest/service/UserInfo.java
deleted file mode 100644
index 644883d..0000000
--- a/server-base/src/main/java/org/apache/kylin/rest/service/UserInfo.java
+++ /dev/null
@@ -1,82 +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.
-*/
-
-package org.apache.kylin.rest.service;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.kylin.common.persistence.RootPersistentEntity;
-import org.springframework.security.core.GrantedAuthority;
-import org.springframework.security.core.userdetails.UserDetails;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-
-@SuppressWarnings("serial")
-public class UserInfo extends RootPersistentEntity {
-
- @JsonProperty()
- private String username;
- @JsonProperty()
- private String password;
- @JsonProperty()
- private List<String> authorities = new ArrayList<>();
-
- public UserInfo(String username, String password, List<String> authorities) {
- this.username = username;
- this.password = password;
- this.authorities = authorities;
- }
-
- public UserInfo(UserDetails user) {
- this.username = user.getUsername();
- this.password = user.getPassword();
- for (GrantedAuthority a : user.getAuthorities()) {
- this.authorities.add(a.getAuthority());
- }
- }
-
- public UserInfo() {
- }
-
- public String getUsername() {
- return username;
- }
-
- public void setUsername(String username) {
- this.username = username;
- }
-
- public String getPassword() {
- return password;
- }
-
- public void setPassword(String password) {
- this.password = password;
- }
-
- public List<String> getAuthorities() {
- return authorities;
- }
-
- public void setAuthorities(List<String> authorities) {
- this.authorities = authorities;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/kylin/blob/cf2f27a3/server-base/src/main/java/org/apache/kylin/rest/service/UserService.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/service/UserService.java b/server-base/src/main/java/org/apache/kylin/rest/service/UserService.java
index e803040..504c035 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/service/UserService.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/service/UserService.java
@@ -31,15 +31,17 @@ import org.apache.kylin.common.persistence.Serializer;
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.security.ManagedUser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.GrantedAuthority;
-import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.provisioning.UserDetailsManager;
import org.springframework.stereotype.Component;
+import com.google.common.base.Preconditions;
+
/**
*/
@Component("userService")
@@ -49,7 +51,7 @@ public class UserService implements UserDetailsManager {
public static final String DIR_PREFIX = "/user/";
- public static final Serializer<UserInfo> SERIALIZER = new JsonSerializer<>(UserInfo.class);
+ public static final Serializer<ManagedUser> SERIALIZER = new JsonSerializer<>(ManagedUser.class);
protected ResourceStore aclStore;
@@ -67,11 +69,13 @@ public class UserService implements UserDetailsManager {
@Override
//@PreAuthorize(Constant.ACCESS_HAS_ROLE_ADMIN) --- DON'T DO THIS, CAUSES CIRCULAR DEPENDENCY BETWEEN UserService & AclService
public void updateUser(UserDetails user) {
+ Preconditions.checkState(user instanceof ManagedUser, "User {} is not ManagedUser", user);
+ ManagedUser managedUser = (ManagedUser) user;
try {
deleteUser(user.getUsername());
String id = getId(user.getUsername());
- aclStore.putResource(id, new UserInfo(user), 0, SERIALIZER);
- logger.debug("update user : {}", user.getUsername());
+ aclStore.putResource(id, managedUser, 0, SERIALIZER);
+ logger.trace("update user : {}", user.getUsername());
} catch (IOException e) {
throw new InternalErrorException(e);
}
@@ -82,7 +86,7 @@ public class UserService implements UserDetailsManager {
try {
String id = getId(userName);
aclStore.deleteResource(id);
- logger.debug("delete user : {}", userName);
+ logger.trace("delete user : {}", userName);
} catch (IOException e) {
throw new InternalErrorException(e);
}
@@ -96,23 +100,27 @@ public class UserService implements UserDetailsManager {
@Override
public boolean userExists(String userName) {
try {
- logger.debug("judge user exist: {}", userName);
+ logger.trace("judge user exist: {}", userName);
return aclStore.exists(getId(userName));
} catch (IOException e) {
throw new InternalErrorException(e);
}
}
+ /**
+ *
+ * @return a ManagedUser
+ */
@Override
public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {
Message msg = MsgPicker.getMsg();
try {
- UserInfo userInfo = aclStore.getResource(getId(userName), UserInfo.class, SERIALIZER);
- if (userInfo == null) {
+ ManagedUser managedUser = aclStore.getResource(getId(userName), ManagedUser.class, SERIALIZER);
+ if (managedUser == null) {
throw new UsernameNotFoundException(String.format(msg.getUSER_NOT_FOUND(), userName));
}
- logger.debug("load user : {}", userName);
- return wrap(userInfo);
+ logger.trace("load user : {}", userName);
+ return managedUser;
} catch (IOException e) {
throw new InternalErrorException(e);
}
@@ -130,28 +138,12 @@ public class UserService implements UserDetailsManager {
return all;
}
- public List<UserDetails> listUsers() throws IOException {
- List<UserDetails> all = new ArrayList<UserDetails>();
- List<UserInfo> userInfos = aclStore.getAllResources(DIR_PREFIX, UserInfo.class, SERIALIZER);
- for (UserInfo info : userInfos) {
- all.add(wrap(info));
- }
- return all;
+ public List<ManagedUser> listUsers() throws IOException {
+ return aclStore.getAllResources(DIR_PREFIX, ManagedUser.class, SERIALIZER);
}
public static String getId(String userName) {
return DIR_PREFIX + userName;
}
- protected User wrap(UserInfo userInfo) {
- if (userInfo == null)
- return null;
- List<GrantedAuthority> authorities = new ArrayList<>();
- List<String> auths = userInfo.getAuthorities();
- for (String str : auths) {
- authorities.add(new UserGrantedAuthority(str));
- }
- return new User(userInfo.getUsername(), userInfo.getPassword(), authorities);
- }
-
}
http://git-wip-us.apache.org/repos/asf/kylin/blob/cf2f27a3/server/src/main/resources/kylinSecurity.xml
----------------------------------------------------------------------
diff --git a/server/src/main/resources/kylinSecurity.xml b/server/src/main/resources/kylinSecurity.xml
index 039bded..53ed511 100644
--- a/server/src/main/resources/kylinSecurity.xml
+++ b/server/src/main/resources/kylinSecurity.xml
@@ -246,7 +246,7 @@
<scr:intercept-url pattern="/api/admin*/**" access="hasRole('ROLE_ADMIN')"/>
<scr:intercept-url pattern="/api/**" access="isAuthenticated()"/>
- <scr:logout invalidate-session="true" delete-cookies="JSESSIONID"/>
+ <scr:logout invalidate-session="true" delete-cookies="JSESSIONID" logout-url="/j_spring_security_logout" logout-success-url="/." />
<scr:session-management session-fixation-protection="newSession"/>
</scr:http>
</beans>
@@ -288,7 +288,7 @@
<scr:intercept-url pattern="/api/admin*/**" access="hasRole('ROLE_ADMIN')"/>
<scr:intercept-url pattern="/api/**" access="isAuthenticated()"/>
- <scr:logout invalidate-session="true" delete-cookies="JSESSIONID"/>
+ <scr:logout invalidate-session="true" delete-cookies="JSESSIONID" logout-url="/j_spring_security_logout" logout-success-url="/." />
<scr:session-management session-fixation-protection="newSession"/>
</scr:http>
http://git-wip-us.apache.org/repos/asf/kylin/blob/cf2f27a3/server/src/test/java/org/apache/kylin/rest/controller/UserControllerTest.java
----------------------------------------------------------------------
diff --git a/server/src/test/java/org/apache/kylin/rest/controller/UserControllerTest.java b/server/src/test/java/org/apache/kylin/rest/controller/UserControllerTest.java
index 767aaf1..f6b4ae1 100644
--- a/server/src/test/java/org/apache/kylin/rest/controller/UserControllerTest.java
+++ b/server/src/test/java/org/apache/kylin/rest/controller/UserControllerTest.java
@@ -23,6 +23,7 @@ import java.util.ArrayList;
import java.util.List;
import org.apache.kylin.rest.constant.Constant;
+import org.apache.kylin.rest.security.ManagedUser;
import org.apache.kylin.rest.service.ServiceTestBase;
import org.junit.Assert;
import org.junit.Before;
@@ -32,7 +33,6 @@ import org.springframework.security.authentication.TestingAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
-import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
/**
@@ -46,7 +46,7 @@ public class UserControllerTest extends ServiceTestBase {
public static void setupResource() {
staticCreateTestMetadata();
List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
- User user = new User("ADMIN", "ADMIN", authorities);
+ ManagedUser user = new ManagedUser("ADMIN", "ADMIN", false, authorities);
Authentication authentication = new TestingAuthenticationToken(user, "ADMIN", Constant.ROLE_ADMIN);
SecurityContextHolder.getContext().setAuthentication(authentication);
}
http://git-wip-us.apache.org/repos/asf/kylin/blob/cf2f27a3/server/src/test/java/org/apache/kylin/rest/service/ServiceTestBase.java
----------------------------------------------------------------------
diff --git a/server/src/test/java/org/apache/kylin/rest/service/ServiceTestBase.java b/server/src/test/java/org/apache/kylin/rest/service/ServiceTestBase.java
index b45b27b..1d60a53 100644
--- a/server/src/test/java/org/apache/kylin/rest/service/ServiceTestBase.java
+++ b/server/src/test/java/org/apache/kylin/rest/service/ServiceTestBase.java
@@ -24,6 +24,7 @@ import org.apache.kylin.common.KylinConfig;
import org.apache.kylin.common.util.LocalFileMetadataTestCase;
import org.apache.kylin.metadata.cachesync.Broadcaster;
import org.apache.kylin.rest.constant.Constant;
+import org.apache.kylin.rest.security.ManagedUser;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
@@ -35,7 +36,6 @@ import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.authentication.TestingAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
-import org.springframework.security.core.userdetails.User;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@@ -71,18 +71,19 @@ public class ServiceTestBase extends LocalFileMetadataTestCase {
Broadcaster.getInstance(config).notifyClearAll();
if (!userService.userExists("ADMIN")) {
- userService.createUser(new User("ADMIN", "KYLIN", Arrays.asList(//
- new UserGrantedAuthority(Constant.ROLE_ADMIN), new UserGrantedAuthority(Constant.ROLE_ANALYST), new UserGrantedAuthority(Constant.ROLE_MODELER))));
+ userService.createUser(new ManagedUser("ADMIN", "KYLIN", false, Arrays.asList(//
+ new UserGrantedAuthority(Constant.ROLE_ADMIN), new UserGrantedAuthority(Constant.ROLE_ANALYST),
+ new UserGrantedAuthority(Constant.ROLE_MODELER))));
}
if (!userService.userExists("MODELER")) {
- userService.createUser(new User("MODELER", "MODELER", Arrays.asList(//
- new UserGrantedAuthority(Constant.ROLE_ANALYST), new UserGrantedAuthority(Constant.ROLE_MODELER))));
+ userService.createUser(new ManagedUser("MODELER", "MODELER", false, Arrays.asList(//
+ new UserGrantedAuthority(Constant.ROLE_ANALYST), new UserGrantedAuthority(Constant.ROLE_MODELER))));
}
if (!userService.userExists("ANALYST")) {
- userService.createUser(new User("ANALYST", "ANALYST", Arrays.asList(//
- new UserGrantedAuthority(Constant.ROLE_ANALYST))));
+ userService.createUser(new ManagedUser("ANALYST", "ANALYST", false, Arrays.asList(//
+ new UserGrantedAuthority(Constant.ROLE_ANALYST))));
}
}
http://git-wip-us.apache.org/repos/asf/kylin/blob/cf2f27a3/server/src/test/java/org/apache/kylin/rest/service/UserServiceTest.java
----------------------------------------------------------------------
diff --git a/server/src/test/java/org/apache/kylin/rest/service/UserServiceTest.java b/server/src/test/java/org/apache/kylin/rest/service/UserServiceTest.java
index 0d4b580..c49b552 100644
--- a/server/src/test/java/org/apache/kylin/rest/service/UserServiceTest.java
+++ b/server/src/test/java/org/apache/kylin/rest/service/UserServiceTest.java
@@ -23,13 +23,13 @@ import java.util.ArrayList;
import java.util.List;
import org.apache.kylin.rest.constant.Constant;
+import org.apache.kylin.rest.security.ManagedUser;
import org.junit.Assert;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
-import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
/**
@@ -44,11 +44,12 @@ public class UserServiceTest extends ServiceTestBase {
@Test
public void testBasics() throws IOException {
userService.deleteUser("ADMIN");
+
Assert.assertTrue(!userService.userExists("ADMIN"));
List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
authorities.add(new SimpleGrantedAuthority(Constant.ROLE_ADMIN));
- User user = new User("ADMIN", "PWD", authorities);
+ ManagedUser user = new ManagedUser("ADMIN", "PWD", false, authorities);
userService.createUser(user);
Assert.assertTrue(userService.userExists("ADMIN"));
@@ -59,7 +60,8 @@ public class UserServiceTest extends ServiceTestBase {
Assert.assertEquals(Constant.ROLE_ADMIN, ud.getAuthorities().iterator().next().getAuthority());
Assert.assertEquals(1, ud.getAuthorities().size());
- Assert.assertTrue(userService.listUserAuthorities().contains(Constant.ROLE_ADMIN));
+ List<String> strings = userService.listUserAuthorities();
+ Assert.assertTrue(strings.contains(Constant.ROLE_ADMIN));
}
}
[22/50] kylin git commit: KYLIN-2662 report error when writing super
large dict cell
Posted by li...@apache.org.
KYLIN-2662 report error when writing super large dict cell
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/73bd0339
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/73bd0339
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/73bd0339
Branch: refs/heads/master
Commit: 73bd0339fea74944e465921ed4283215b01e2c67
Parents: 247f3cd
Author: Roger Shi <ro...@hotmail.com>
Authored: Tue Jun 20 16:32:01 2017 +0800
Committer: Hongbin Ma <ma...@kyligence.io>
Committed: Tue Jun 20 17:16:03 2017 +0800
----------------------------------------------------------------------
.../main/java/org/apache/kylin/common/util/BytesUtil.java | 4 ++++
.../src/main/java/org/apache/kylin/dict/TrieDictionary.java | 5 ++++-
.../java/org/apache/kylin/dict/TrieDictionaryBuilder.java | 8 ++++++++
3 files changed, 16 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/73bd0339/core-common/src/main/java/org/apache/kylin/common/util/BytesUtil.java
----------------------------------------------------------------------
diff --git a/core-common/src/main/java/org/apache/kylin/common/util/BytesUtil.java b/core-common/src/main/java/org/apache/kylin/common/util/BytesUtil.java
index 49f1ee0..8cc559e 100644
--- a/core-common/src/main/java/org/apache/kylin/common/util/BytesUtil.java
+++ b/core-common/src/main/java/org/apache/kylin/common/util/BytesUtil.java
@@ -177,6 +177,10 @@ public class BytesUtil {
return r;
}
+ public static boolean isPositiveShort(int i) {
+ return (i & 0xFFFF7000) == 0;
+ }
+
// from WritableUtils
// ============================================================================
http://git-wip-us.apache.org/repos/asf/kylin/blob/73bd0339/core-dictionary/src/main/java/org/apache/kylin/dict/TrieDictionary.java
----------------------------------------------------------------------
diff --git a/core-dictionary/src/main/java/org/apache/kylin/dict/TrieDictionary.java b/core-dictionary/src/main/java/org/apache/kylin/dict/TrieDictionary.java
index 8849015..53daeb7 100644
--- a/core-dictionary/src/main/java/org/apache/kylin/dict/TrieDictionary.java
+++ b/core-dictionary/src/main/java/org/apache/kylin/dict/TrieDictionary.java
@@ -29,7 +29,6 @@ import java.io.ObjectOutputStream;
import java.io.PrintStream;
import java.util.Arrays;
-
import org.apache.kylin.common.util.Bytes;
import org.apache.kylin.common.util.BytesUtil;
import org.apache.kylin.common.util.ClassUtil;
@@ -101,6 +100,10 @@ public class TrieDictionary<T> extends CacheDictionary<T> {
this.sizeNoValuesBeneath = headIn.read();
this.baseId = headIn.readShort();
this.maxValueLength = headIn.readShort();
+ if (maxValueLength < 0) {
+ throw new IllegalStateException("maxValueLength is negative (" + maxValueLength
+ + "). Dict value is too long, whose length is larger than " + Short.MAX_VALUE);
+ }
String converterName = headIn.readUTF();
if (converterName.isEmpty() == false)
http://git-wip-us.apache.org/repos/asf/kylin/blob/73bd0339/core-dictionary/src/main/java/org/apache/kylin/dict/TrieDictionaryBuilder.java
----------------------------------------------------------------------
diff --git a/core-dictionary/src/main/java/org/apache/kylin/dict/TrieDictionaryBuilder.java b/core-dictionary/src/main/java/org/apache/kylin/dict/TrieDictionaryBuilder.java
index 1750ac1..18169ca 100644
--- a/core-dictionary/src/main/java/org/apache/kylin/dict/TrieDictionaryBuilder.java
+++ b/core-dictionary/src/main/java/org/apache/kylin/dict/TrieDictionaryBuilder.java
@@ -442,7 +442,9 @@ public class TrieDictionaryBuilder<T> {
headOut.writeInt((int) stats.mbpn_footprint); // body size
headOut.write(sizeChildOffset);
headOut.write(sizeNoValuesBeneath);
+ positiveShortPreCheck(baseId, "baseId");
headOut.writeShort(baseId);
+ positiveShortPreCheck(stats.maxValueLength, "stats.maxValueLength");
headOut.writeShort(stats.maxValueLength);
headOut.writeUTF(bytesConverter == null ? "" : bytesConverter.getClass().getName());
headOut.close();
@@ -483,6 +485,12 @@ public class TrieDictionaryBuilder<T> {
return trieBytes;
}
+ private void positiveShortPreCheck(int i, String fieldName) {
+ if (!BytesUtil.isPositiveShort(i)) {
+ throw new IllegalStateException(fieldName + " is not positive short, usually caused by too long dict value.");
+ }
+ }
+
private void build_overwriteChildOffset(int parentOffset, int childOffset, int sizeChildOffset, byte[] trieBytes) {
int flags = (int) trieBytes[parentOffset] & (TrieDictionary.BIT_IS_LAST_CHILD | TrieDictionary.BIT_IS_END_OF_VALUE);
BytesUtil.writeUnsigned(childOffset, trieBytes, parentOffset, sizeChildOffset);
[18/50] kylin git commit: fix minor issues
Posted by li...@apache.org.
fix minor issues
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/361b58d6
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/361b58d6
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/361b58d6
Branch: refs/heads/master
Commit: 361b58d6dc5fc1add839952ecf1c687662577bc8
Parents: d67bf45
Author: Hongbin Ma <ma...@apache.org>
Authored: Mon Jun 19 15:34:16 2017 +0800
Committer: Ni Chunen <zj...@sjtu.org>
Committed: Mon Jun 19 16:39:05 2017 +0800
----------------------------------------------------------------------
.../org/apache/kylin/jdbc/ITJDBCDriverTest.java | 16 ++++++++--------
.../kylin/rest/controller/QueryController.java | 16 ++++++++++++----
.../org/apache/kylin/rest/service/QueryService.java | 2 +-
3 files changed, 21 insertions(+), 13 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/361b58d6/kylin-it/src/test/java/org/apache/kylin/jdbc/ITJDBCDriverTest.java
----------------------------------------------------------------------
diff --git a/kylin-it/src/test/java/org/apache/kylin/jdbc/ITJDBCDriverTest.java b/kylin-it/src/test/java/org/apache/kylin/jdbc/ITJDBCDriverTest.java
index bdf61f8..ba293ae 100644
--- a/kylin-it/src/test/java/org/apache/kylin/jdbc/ITJDBCDriverTest.java
+++ b/kylin-it/src/test/java/org/apache/kylin/jdbc/ITJDBCDriverTest.java
@@ -222,17 +222,15 @@ public class ITJDBCDriverTest extends HBaseMetadataTestCase {
public void testPreparedStatement() throws Exception {
Connection conn = getConnection();
- PreparedStatement statement = conn.prepareStatement("select LSTG_FORMAT_NAME, sum(price) as GMV, count(1) as TRANS_CNT from test_kylin_fact " + "where LSTG_FORMAT_NAME = ? group by LSTG_FORMAT_NAME");
+ PreparedStatement statement = conn.prepareStatement(
+ "select LSTG_FORMAT_NAME, sum(price) as GMV, count(1) as TRANS_CNT from test_kylin_fact "
+ + "where LSTG_FORMAT_NAME = ? group by LSTG_FORMAT_NAME");
statement.setString(1, "FP-GTC");
ResultSet rs = statement.executeQuery();
- Assert.assertTrue(rs.next());
-
- String format_name = rs.getString(1);
-
- Assert.assertTrue("FP-GTC".equals(format_name));
+ Assert.assertFalse(rs.next());
rs.close();
statement.close();
@@ -242,7 +240,8 @@ public class ITJDBCDriverTest extends HBaseMetadataTestCase {
@Test
public void testResultSet() throws Exception {
- String sql = "select LSTG_FORMAT_NAME, sum(price) as GMV, count(1) as TRANS_CNT from test_kylin_fact \n" + " group by LSTG_FORMAT_NAME ";
+ String sql = "select LSTG_FORMAT_NAME, sum(price) as GMV, count(1) as TRANS_CNT from test_kylin_fact \n"
+ + " group by LSTG_FORMAT_NAME ";
Connection conn = getConnection();
Statement statement = conn.createStatement();
@@ -270,7 +269,8 @@ public class ITJDBCDriverTest extends HBaseMetadataTestCase {
@Test
public void testResultSetWithMaxRows() throws Exception {
- String sql = "select LSTG_FORMAT_NAME, sum(price) as GMV, count(1) as TRANS_CNT from test_kylin_fact \n" + " group by LSTG_FORMAT_NAME ";
+ String sql = "select LSTG_FORMAT_NAME, sum(price) as GMV, count(1) as TRANS_CNT from test_kylin_fact \n"
+ + " group by LSTG_FORMAT_NAME ";
Connection conn = getConnection();
Statement statement = conn.createStatement();
http://git-wip-us.apache.org/repos/asf/kylin/blob/361b58d6/server-base/src/main/java/org/apache/kylin/rest/controller/QueryController.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/controller/QueryController.java b/server-base/src/main/java/org/apache/kylin/rest/controller/QueryController.java
index 35dcee4..61250ea 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/controller/QueryController.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/controller/QueryController.java
@@ -20,13 +20,14 @@ package org.apache.kylin.rest.controller;
import java.io.IOException;
import java.sql.SQLException;
+import java.text.SimpleDateFormat;
import java.util.ArrayList;
+import java.util.Date;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
-import com.google.common.collect.Maps;
import org.apache.commons.io.IOUtils;
import org.apache.kylin.common.debug.BackdoorToggles;
import org.apache.kylin.metadata.querymeta.SelectedColumnMeta;
@@ -54,6 +55,8 @@ import org.supercsv.io.CsvListWriter;
import org.supercsv.io.ICsvListWriter;
import org.supercsv.prefs.CsvPreference;
+import com.google.common.collect.Maps;
+
/**
* Handle query requests.
*
@@ -82,7 +85,7 @@ public class QueryController extends BasicController {
Map<String, String> toggles = Maps.newHashMap();
toggles.put(BackdoorToggles.DEBUG_TOGGLE_PREPARE_ONLY, "true");
BackdoorToggles.addToggles(toggles);
-
+
return queryService.doQueryWithCache(sqlRequest);
}
@@ -90,7 +93,8 @@ public class QueryController extends BasicController {
@ResponseBody
public void saveQuery(@RequestBody SaveSqlRequest sqlRequest) throws IOException {
String creator = SecurityContextHolder.getContext().getAuthentication().getName();
- Query newQuery = new Query(sqlRequest.getName(), sqlRequest.getProject(), sqlRequest.getSql(), sqlRequest.getDescription());
+ Query newQuery = new Query(sqlRequest.getName(), sqlRequest.getProject(), sqlRequest.getSql(),
+ sqlRequest.getDescription());
queryService.saveQuery(creator, newQuery);
}
@@ -114,7 +118,11 @@ public class QueryController extends BasicController {
public void downloadQueryResult(@PathVariable String format, SQLRequest sqlRequest, HttpServletResponse response) {
SQLResponse result = queryService.doQueryWithCache(sqlRequest);
response.setContentType("text/" + format + ";charset=utf-8");
- response.setHeader("Content-Disposition", "attachment; filename=\"result." + format + "\"");
+
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
+ Date now = new Date();
+ String nowStr = sdf.format(now);
+ response.setHeader("Content-Disposition", "attachment; filename=\"" + nowStr + ".result." + format + "\"");
ICsvListWriter csvWriter = null;
try {
http://git-wip-us.apache.org/repos/asf/kylin/blob/361b58d6/server-base/src/main/java/org/apache/kylin/rest/service/QueryService.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/service/QueryService.java b/server-base/src/main/java/org/apache/kylin/rest/service/QueryService.java
index bf32140..d6554fc 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/service/QueryService.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/service/QueryService.java
@@ -772,7 +772,7 @@ public class QueryService extends BasicService {
String columnName = field.getKey();
BasicSqlType basicSqlType = (BasicSqlType) field.getValue();
- columnMetas.add(new SelectedColumnMeta(false, config.caseSensitive(), false, false, basicSqlType.isNullable() ? 1 : 0, true, basicSqlType.getPrecision(), columnName, columnName, null, null, null, basicSqlType.getPrecision(), basicSqlType.getScale(), basicSqlType.getSqlTypeName().getJdbcOrdinal(), basicSqlType.getSqlTypeName().getName(), true, false, false));
+ columnMetas.add(new SelectedColumnMeta(false, config.caseSensitive(), false, false, basicSqlType.isNullable() ? 1 : 0, true, basicSqlType.getPrecision(), columnName, columnName, null, null, null, basicSqlType.getPrecision(), basicSqlType.getScale() < 0 ? 0 : basicSqlType.getScale(), basicSqlType.getSqlTypeName().getJdbcOrdinal(), basicSqlType.getSqlTypeName().getName(), true, false, false));
}
} else {
[47/50] kylin git commit: #488 (#1406)
Posted by li...@apache.org.
#488 (#1406)
* #488
* #488 some code refine
* #488
* #488
* #488
* #488
* #488
* #488
* #488
* #488
* #488
* code refine
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/1acd066c
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/1acd066c
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/1acd066c
Branch: refs/heads/master
Commit: 1acd066cc0e5dc40e9547f25be7fcc992a1dd941
Parents: 05631b5
Author: luguosheng1314 <55...@qq.com>
Authored: Tue Jun 27 19:03:20 2017 +0800
Committer: GitHub <no...@github.com>
Committed: Tue Jun 27 19:03:20 2017 +0800
----------------------------------------------------------------------
webapp/app/partials/tables/loadStreamingTable.html | 3 ---
1 file changed, 3 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/1acd066c/webapp/app/partials/tables/loadStreamingTable.html
----------------------------------------------------------------------
diff --git a/webapp/app/partials/tables/loadStreamingTable.html b/webapp/app/partials/tables/loadStreamingTable.html
index 2f2a1ec..beac941 100644
--- a/webapp/app/partials/tables/loadStreamingTable.html
+++ b/webapp/app/partials/tables/loadStreamingTable.html
@@ -15,7 +15,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
-->
-
<div class="modal-body streaming-source" style="height: 360px;">
<div class="col-xs-5">
<p class="text-info">
@@ -31,7 +30,6 @@
Source json invalid, Please correct your schema and generate again.
</small>
</div>
-
<div style="margin-bottom: 20px;">
<span class="label label-info">JSON</span>
</div>
@@ -41,7 +39,6 @@
mode:'json',
onLoad: streamingOnLoad
}">
-
</div>
</div>
<div class="col-xs-1" style="margin-top:300px;text-align:center;">
[44/50] kylin git commit: minor,
project renaming also copy ACL information
Posted by li...@apache.org.
minor, project renaming also copy ACL information
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/450845c6
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/450845c6
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/450845c6
Branch: refs/heads/master
Commit: 450845c6377c131db801f9eca9c4e062fd67fc0e
Parents: 6f8a91c
Author: Roger Shi <ro...@hotmail.com>
Authored: Mon Jun 26 21:19:43 2017 +0800
Committer: Hongbin Ma <ma...@kyligence.io>
Committed: Tue Jun 27 11:18:03 2017 +0800
----------------------------------------------------------------------
.../kylin/metadata/project/ProjectManager.java | 52 +++++++++++---------
.../rest/controller/ProjectController.java | 6 ++-
.../rest/controller2/ProjectControllerV2.java | 10 ++--
.../java/org/apache/kylin/rest/msg/Message.java | 4 --
.../kylin/rest/service/ProjectService.java | 24 ++++++++-
5 files changed, 62 insertions(+), 34 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/450845c6/core-metadata/src/main/java/org/apache/kylin/metadata/project/ProjectManager.java
----------------------------------------------------------------------
diff --git a/core-metadata/src/main/java/org/apache/kylin/metadata/project/ProjectManager.java b/core-metadata/src/main/java/org/apache/kylin/metadata/project/ProjectManager.java
index d4b3ff4..213b136 100644
--- a/core-metadata/src/main/java/org/apache/kylin/metadata/project/ProjectManager.java
+++ b/core-metadata/src/main/java/org/apache/kylin/metadata/project/ProjectManager.java
@@ -47,6 +47,7 @@ import org.apache.kylin.metadata.realization.RealizationType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
@@ -216,35 +217,40 @@ public class ProjectManager {
}
}
- //update project itself
- public ProjectInstance updateProject(ProjectInstance project, String newName, String newDesc,
+ // rename project
+ public ProjectInstance renameProject(ProjectInstance project, String newName, String newDesc,
LinkedHashMap<String, String> overrideProps) throws IOException {
- if (!project.getName().equals(newName)) {
- ProjectInstance newProject = this.createProject(newName, project.getOwner(), newDesc, overrideProps);
-
- newProject.setCreateTimeUTC(project.getCreateTimeUTC());
- newProject.recordUpdateTime(System.currentTimeMillis());
- newProject.setRealizationEntries(project.getRealizationEntries());
- newProject.setTables(project.getTables());
- newProject.setModels(project.getModels());
- newProject.setExtFilters(project.getExtFilters());
+ Preconditions.checkArgument(!project.getName().equals(newName));
+ ProjectInstance newProject = this.createProject(newName, project.getOwner(), newDesc, overrideProps);
+
+ newProject.setUuid(project.getUuid());
+ newProject.setCreateTimeUTC(project.getCreateTimeUTC());
+ newProject.recordUpdateTime(System.currentTimeMillis());
+ newProject.setRealizationEntries(project.getRealizationEntries());
+ newProject.setTables(project.getTables());
+ newProject.setModels(project.getModels());
+ newProject.setExtFilters(project.getExtFilters());
+
+ removeProject(project);
+ updateProject(newProject);
- removeProject(project);
- updateProject(newProject);
+ return newProject;
+ }
- return newProject;
- } else {
- project.setName(newName);
- project.setDescription(newDesc);
- project.setOverrideKylinProps(overrideProps);
+ //update project itself
+ public ProjectInstance updateProject(ProjectInstance project, String newName, String newDesc,
+ LinkedHashMap<String, String> overrideProps) throws IOException {
+ Preconditions.checkArgument(project.getName().equals(newName));
+ project.setName(newName);
+ project.setDescription(newDesc);
+ project.setOverrideKylinProps(overrideProps);
- if (project.getUuid() == null)
- project.updateRandomUuid();
+ if (project.getUuid() == null)
+ project.updateRandomUuid();
- updateProject(project);
+ updateProject(project);
- return project;
- }
+ return project;
}
private void updateProject(ProjectInstance prj) throws IOException {
http://git-wip-us.apache.org/repos/asf/kylin/blob/450845c6/server-base/src/main/java/org/apache/kylin/rest/controller/ProjectController.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/controller/ProjectController.java b/server-base/src/main/java/org/apache/kylin/rest/controller/ProjectController.java
index 89c8b23..74e806e 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/controller/ProjectController.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/controller/ProjectController.java
@@ -172,7 +172,11 @@ public class ProjectController extends BasicController {
throw new InternalErrorException("The project named " + formerProjectName + " does not exists");
}
- updatedProj = projectService.updateProject(projectDesc, currentProject);
+ if (projectDesc.getName().equals(currentProject.getName())) {
+ updatedProj = projectService.updateProject(projectDesc, currentProject);
+ } else {
+ updatedProj = projectService.renameProject(projectDesc, currentProject);
+ }
} catch (Exception e) {
logger.error("Failed to deal with the request.", e);
throw new InternalErrorException(e.getLocalizedMessage());
http://git-wip-us.apache.org/repos/asf/kylin/blob/450845c6/server-base/src/main/java/org/apache/kylin/rest/controller2/ProjectControllerV2.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/controller2/ProjectControllerV2.java b/server-base/src/main/java/org/apache/kylin/rest/controller2/ProjectControllerV2.java
index 6dea4e3..a25e5b1 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/controller2/ProjectControllerV2.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/controller2/ProjectControllerV2.java
@@ -138,12 +138,12 @@ public class ProjectControllerV2 extends BasicController {
throw new BadRequestException(String.format(msg.getPROJECT_NOT_FOUND(), formerProjectName));
}
- // cannot modify project name if it's not empty
- if (!currentProject.getName().equals(projectDesc.getName()) && !isProjectEmpty(currentProject.getName())) {
- throw new BadRequestException(msg.getRENAME_PROJECT_NOT_EMPTY());
+ ProjectInstance updatedProj;
+ if (projectDesc.getName().equals(currentProject.getName())) {
+ updatedProj = projectService.updateProject(projectDesc, currentProject);
+ } else {
+ updatedProj = projectService.renameProject(projectDesc, currentProject);
}
-
- ProjectInstance updatedProj = projectService.updateProject(projectDesc, currentProject);
return new EnvelopeResponse(ResponseCode.CODE_SUCCESS, updatedProj, "");
}
http://git-wip-us.apache.org/repos/asf/kylin/blob/450845c6/server-base/src/main/java/org/apache/kylin/rest/msg/Message.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/msg/Message.java b/server-base/src/main/java/org/apache/kylin/rest/msg/Message.java
index 9ed38bb..45c1a65 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/msg/Message.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/msg/Message.java
@@ -249,10 +249,6 @@ public class Message {
return "Cannot delete non-empty project";
}
- public String getRENAME_PROJECT_NOT_EMPTY() {
- return "Cannot rename non-empty project";
- }
-
// Table
public String getHIVE_TABLE_NOT_FOUND() {
return "Cannot find Hive table '%s'.";
http://git-wip-us.apache.org/repos/asf/kylin/blob/450845c6/server-base/src/main/java/org/apache/kylin/rest/service/ProjectService.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/service/ProjectService.java b/server-base/src/main/java/org/apache/kylin/rest/service/ProjectService.java
index f71097b..c6bd6cf 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/service/ProjectService.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/service/ProjectService.java
@@ -28,6 +28,7 @@ import javax.annotation.Nullable;
import org.apache.directory.api.util.Strings;
import org.apache.kylin.cube.CubeInstance;
+import org.apache.kylin.metadata.draft.Draft;
import org.apache.kylin.metadata.project.ProjectInstance;
import org.apache.kylin.metadata.project.ProjectManager;
import org.apache.kylin.metadata.realization.RealizationType;
@@ -94,6 +95,10 @@ public class ProjectService extends BasicService {
@PreAuthorize(Constant.ACCESS_HAS_ROLE_ADMIN + " or hasPermission(#currentProject, 'ADMINISTRATION') or hasPermission(#currentProject, 'MANAGEMENT')")
public ProjectInstance updateProject(ProjectInstance newProject, ProjectInstance currentProject) throws IOException {
+ if (!newProject.getName().equals(currentProject.getName())) {
+ return renameProject(newProject, currentProject);
+ }
+
String newProjectName = newProject.getName();
String newDescription = newProject.getDescription();
LinkedHashMap<String, String> overrideProps = newProject.getOverrideKylinProps();
@@ -101,10 +106,27 @@ public class ProjectService extends BasicService {
ProjectInstance updatedProject = getProjectManager().updateProject(currentProject, newProjectName, newDescription, overrideProps);
logger.debug("Project updated.");
-
return updatedProject;
}
+ @PreAuthorize(Constant.ACCESS_HAS_ROLE_ADMIN + " or hasPermission(#currentProject, 'ADMINISTRATION')")
+ public ProjectInstance renameProject(ProjectInstance newProject, ProjectInstance currentProject) throws IOException {
+ String newProjectName = newProject.getName();
+ String newDescription = newProject.getDescription();
+ LinkedHashMap<String, String> overrideProps = newProject.getOverrideKylinProps();
+
+ // rename project but keep UUID, acl keeps the same
+ ProjectInstance renamedProject = getProjectManager().renameProject(currentProject, newProjectName, newDescription, overrideProps);
+
+ // rebind draft and project
+ for (Draft draft : getDraftManager().list(currentProject.getName())) {
+ draft.setProject(newProjectName);
+ }
+
+ logger.debug("Project rename.");
+ return renamedProject;
+ }
+
@PostFilter(Constant.ACCESS_POST_FILTER_READ)
public List<ProjectInstance> listProjects(final Integer limit, final Integer offset) {
List<ProjectInstance> projects = listAllProjects(limit, offset);
[43/50] kylin git commit: minor, deduplicate returned acl entry
Posted by li...@apache.org.
minor, deduplicate returned acl entry
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/6f8a91c0
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/6f8a91c0
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/6f8a91c0
Branch: refs/heads/master
Commit: 6f8a91c0dde0cf09efe3ff5e99533baed50f85c1
Parents: f79fa38
Author: Roger Shi <ro...@hotmail.com>
Authored: Mon Jun 26 20:12:39 2017 +0800
Committer: Hongbin Ma <ma...@kyligence.io>
Committed: Mon Jun 26 20:23:10 2017 +0800
----------------------------------------------------------------------
.../java/org/apache/kylin/rest/service/AccessService.java | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/6f8a91c0/server-base/src/main/java/org/apache/kylin/rest/service/AccessService.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/service/AccessService.java b/server-base/src/main/java/org/apache/kylin/rest/service/AccessService.java
index 8b96635..e5cd793 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/service/AccessService.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/service/AccessService.java
@@ -20,7 +20,9 @@ package org.apache.kylin.rest.service;
import java.util.ArrayList;
import java.util.List;
+import java.util.Set;
+import com.google.common.collect.Sets;
import org.apache.kylin.common.persistence.AclEntity;
import org.apache.kylin.common.persistence.RootPersistentEntity;
import org.apache.kylin.rest.constant.Constant;
@@ -298,10 +300,14 @@ public class AccessService {
public List<AccessEntryResponse> generateAceResponses(Acl acl) {
List<AccessEntryResponse> result = new ArrayList<AccessEntryResponse>();
+ Set<Sid> sidSet = Sets.newHashSet();
while (acl != null) {
for (AccessControlEntry ace : acl.getEntries()) {
- result.add(new AccessEntryResponse(ace.getId(), ace.getSid(), ace.getPermission(), ace.isGranting()));
+ if (!sidSet.contains(ace.getSid())) {
+ result.add(new AccessEntryResponse(ace.getId(), ace.getSid(), ace.getPermission(), ace.isGranting()));
+ sidSet.add(ace.getSid());
+ }
}
acl = acl.getParentAcl();
}
[35/50] kylin git commit: #1276 loose global dict column limit
Posted by li...@apache.org.
#1276 loose global dict column limit
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/e6f58d1b
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/e6f58d1b
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/e6f58d1b
Branch: refs/heads/master
Commit: e6f58d1b8129d3ff024e6cfc1462dccbb65a27d8
Parents: c6ade2f
Author: Roger Shi <ro...@hotmail.com>
Authored: Fri Jun 23 10:09:06 2017 +0800
Committer: Hongbin Ma <ma...@kyligence.io>
Committed: Fri Jun 23 19:14:31 2017 +0800
----------------------------------------------------------------------
.../kylin/cube/model/validation/rule/DictionaryRule.java | 7 -------
.../cube/model/validation/rule/DictionaryRuleTest.java | 10 ++--------
2 files changed, 2 insertions(+), 15 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/e6f58d1b/core-cube/src/main/java/org/apache/kylin/cube/model/validation/rule/DictionaryRule.java
----------------------------------------------------------------------
diff --git a/core-cube/src/main/java/org/apache/kylin/cube/model/validation/rule/DictionaryRule.java b/core-cube/src/main/java/org/apache/kylin/cube/model/validation/rule/DictionaryRule.java
index 8da3ca0..548586f 100644
--- a/core-cube/src/main/java/org/apache/kylin/cube/model/validation/rule/DictionaryRule.java
+++ b/core-cube/src/main/java/org/apache/kylin/cube/model/validation/rule/DictionaryRule.java
@@ -29,7 +29,6 @@ import org.apache.kylin.cube.model.DictionaryDesc;
import org.apache.kylin.cube.model.validation.IValidatorRule;
import org.apache.kylin.cube.model.validation.ResultLevel;
import org.apache.kylin.cube.model.validation.ValidateContext;
-import org.apache.kylin.dict.GlobalDictionaryBuilder;
import org.apache.kylin.metadata.model.TblColRef;
/**
@@ -46,7 +45,6 @@ public class DictionaryRule implements IValidatorRule<CubeDesc> {
static final String ERROR_REUSE_BUILDER_BOTH_SET = "REUSE and BUILDER both set on dictionary for column: ";
static final String ERROR_REUSE_BUILDER_BOTH_EMPTY = "REUSE and BUILDER both empty on dictionary for column: ";
static final String ERROR_TRANSITIVE_REUSE = "Transitive REUSE is not allowed for dictionary: ";
- static final String ERROR_GLOBAL_DICTIONNARY_ONLY_MEASURE = "Global dictionary couldn't be used for dimension column: ";
@Override
public void validate(CubeDesc cubeDesc, ValidateContext context) {
@@ -82,11 +80,6 @@ public class DictionaryRule implements IValidatorRule<CubeDesc> {
return;
}
- if (StringUtils.isNotEmpty(builderClass) && builderClass.equalsIgnoreCase(GlobalDictionaryBuilder.class.getName()) && dimensionColumns.contains(dictCol)) {
- context.addResult(ResultLevel.ERROR, ERROR_GLOBAL_DICTIONNARY_ONLY_MEASURE + dictCol);
- return;
- }
-
if (reuseCol != null) {
reuseDictionaries.add(dictDesc);
} else {
http://git-wip-us.apache.org/repos/asf/kylin/blob/e6f58d1b/core-cube/src/test/java/org/apache/kylin/cube/model/validation/rule/DictionaryRuleTest.java
----------------------------------------------------------------------
diff --git a/core-cube/src/test/java/org/apache/kylin/cube/model/validation/rule/DictionaryRuleTest.java b/core-cube/src/test/java/org/apache/kylin/cube/model/validation/rule/DictionaryRuleTest.java
index 0dd9b76..0f11f4b 100644
--- a/core-cube/src/test/java/org/apache/kylin/cube/model/validation/rule/DictionaryRuleTest.java
+++ b/core-cube/src/test/java/org/apache/kylin/cube/model/validation/rule/DictionaryRuleTest.java
@@ -19,7 +19,6 @@
package org.apache.kylin.cube.model.validation.rule;
import static org.apache.kylin.cube.model.validation.rule.DictionaryRule.ERROR_DUPLICATE_DICTIONARY_COLUMN;
-import static org.apache.kylin.cube.model.validation.rule.DictionaryRule.ERROR_GLOBAL_DICTIONNARY_ONLY_MEASURE;
import static org.apache.kylin.cube.model.validation.rule.DictionaryRule.ERROR_REUSE_BUILDER_BOTH_EMPTY;
import static org.apache.kylin.cube.model.validation.rule.DictionaryRule.ERROR_REUSE_BUILDER_BOTH_SET;
import static org.apache.kylin.cube.model.validation.rule.DictionaryRule.ERROR_TRANSITIVE_REUSE;
@@ -30,7 +29,6 @@ import java.io.FileInputStream;
import java.io.IOException;
import java.util.List;
-import com.google.common.collect.Lists;
import org.apache.kylin.common.KylinConfig;
import org.apache.kylin.common.util.JsonUtil;
import org.apache.kylin.common.util.LocalFileMetadataTestCase;
@@ -42,6 +40,8 @@ import org.junit.After;
import org.junit.Before;
import org.junit.Test;
+import com.google.common.collect.Lists;
+
public class DictionaryRuleTest extends LocalFileMetadataTestCase {
private static KylinConfig config;
@@ -96,12 +96,6 @@ public class DictionaryRuleTest extends LocalFileMetadataTestCase {
}
@Test
- public void testBadDesc5() throws IOException {
- testDictionaryDesc(ERROR_GLOBAL_DICTIONNARY_ONLY_MEASURE,
- DictionaryDesc.create("CATEG_LVL2_NAME", null, GlobalDictionaryBuilder.class.getName()));
- }
-
- @Test
public void testGoodDesc2() throws IOException {
testDictionaryDesc(null, DictionaryDesc.create("SELLER_ID", null, GlobalDictionaryBuilder.class.getName()));
}
[20/50] kylin git commit: #754 Change broadcast threads to daemon
threads
Posted by li...@apache.org.
#754 Change broadcast threads to daemon threads
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/5a4e465d
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/5a4e465d
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/5a4e465d
Branch: refs/heads/master
Commit: 5a4e465dd8b8fda640db74e595491a2b2dd3c9db
Parents: 4d2a548
Author: auphyroc99 <45...@qq.com>
Authored: Tue Jun 20 14:44:01 2017 +0800
Committer: Roger Shi <ro...@gmail.com>
Committed: Tue Jun 20 15:01:11 2017 +0800
----------------------------------------------------------------------
.../kylin/metadata/cachesync/Broadcaster.java | 22 +++++++++++++-------
1 file changed, 14 insertions(+), 8 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/5a4e465d/core-metadata/src/main/java/org/apache/kylin/metadata/cachesync/Broadcaster.java
----------------------------------------------------------------------
diff --git a/core-metadata/src/main/java/org/apache/kylin/metadata/cachesync/Broadcaster.java b/core-metadata/src/main/java/org/apache/kylin/metadata/cachesync/Broadcaster.java
index 4fbfc7c..c9e1130 100644
--- a/core-metadata/src/main/java/org/apache/kylin/metadata/cachesync/Broadcaster.java
+++ b/core-metadata/src/main/java/org/apache/kylin/metadata/cachesync/Broadcaster.java
@@ -114,26 +114,28 @@ public class Broadcaster {
@Override
public void run() {
final Map<String, RestClient> restClientMap = Maps.newHashMap();
- final ExecutorService wipingCachePool = new ThreadPoolExecutor(1, 10, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
+ final ExecutorService wipingCachePool = new ThreadPoolExecutor(1, 10, 60L, TimeUnit.SECONDS,
+ new LinkedBlockingQueue<Runnable>(), new DaemonThreadFactory());
while (true) {
try {
final BroadcastEvent broadcastEvent = broadcastEvents.takeFirst();
String[] restServers = config.getRestServers();
- logger.info("Servers in the cluster: " + Arrays.toString(restServers));
+ logger.debug("Servers in the cluster: " + Arrays.toString(restServers));
for (final String node : restServers) {
if (restClientMap.containsKey(node) == false) {
restClientMap.put(node, new RestClient(node));
}
}
- logger.info("Announcing new broadcast event: " + broadcastEvent);
+ logger.debug("Announcing new broadcast event: " + broadcastEvent);
for (final String node : restServers) {
wipingCachePool.execute(new Runnable() {
@Override
public void run() {
try {
- restClientMap.get(node).wipeCache(broadcastEvent.getEntity(), broadcastEvent.getEvent(), broadcastEvent.getCacheKey());
+ restClientMap.get(node).wipeCache(broadcastEvent.getEntity(),
+ broadcastEvent.getEvent(), broadcastEvent.getCacheKey());
} catch (IOException e) {
logger.warn("Thread failed during wipe cache at " + broadcastEvent, e);
}
@@ -192,7 +194,8 @@ public class Broadcaster {
if (list == null)
return;
- logger.trace("Broadcasting metadata change: entity=" + entity + ", event=" + event + ", cacheKey=" + cacheKey + ", listeners=" + list);
+ logger.trace("Broadcasting metadata change: entity=" + entity + ", event=" + event + ", cacheKey=" + cacheKey
+ + ", listeners=" + list);
// prevents concurrent modification exception
list = Lists.newArrayList(list);
@@ -222,7 +225,8 @@ public class Broadcaster {
break;
}
- logger.debug("Done broadcasting metadata change: entity=" + entity + ", event=" + event + ", cacheKey=" + cacheKey);
+ logger.debug(
+ "Done broadcasting metadata change: entity=" + entity + ", event=" + event + ", cacheKey=" + cacheKey);
}
/**
@@ -279,7 +283,8 @@ public class Broadcaster {
public void onProjectDataChange(Broadcaster broadcaster, String project) throws IOException {
}
- public void onEntityChange(Broadcaster broadcaster, String entity, Event event, String cacheKey) throws IOException {
+ public void onEntityChange(Broadcaster broadcaster, String entity, Event event, String cacheKey)
+ throws IOException {
}
}
@@ -343,7 +348,8 @@ public class Broadcaster {
@Override
public String toString() {
- return Objects.toStringHelper(this).add("entity", entity).add("event", event).add("cacheKey", cacheKey).toString();
+ return Objects.toStringHelper(this).add("entity", entity).add("event", event).add("cacheKey", cacheKey)
+ .toString();
}
}
[37/50] kylin git commit: minor,
remove refine user cache in spring security
Posted by li...@apache.org.
minor, remove refine user cache in spring security
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/3280172b
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/3280172b
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/3280172b
Branch: refs/heads/master
Commit: 3280172b737f85479eb3432fa12c267b477674fd
Parents: 22d8fae
Author: Hongbin Ma <ma...@apache.org>
Authored: Fri Jun 23 19:08:41 2017 +0800
Committer: liyang-gmt8 <li...@apache.org>
Committed: Fri Jun 23 20:26:46 2017 +0800
----------------------------------------------------------------------
.../apache/kylin/common/KylinConfigBase.java | 10 ++-
.../security/KylinAuthenticationProvider.java | 91 ++++++++++++--------
.../apache/kylin/rest/security/ManagedUser.java | 78 ++++++++---------
.../apache/kylin/rest/service/UserService.java | 10 +++
server/src/main/resources/ehcache-test.xml | 9 +-
server/src/main/resources/ehcache.xml | 9 +-
6 files changed, 111 insertions(+), 96 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/3280172b/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 2ccf3cf..ecd5261 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
@@ -502,7 +502,7 @@ abstract public class KylinConfigBase implements Serializable {
public Integer getSchedulerPollIntervalSecond() {
return Integer.parseInt(getOptional("kylin.job.scheduler.poll-interval-second", "30"));
}
-
+
public Integer getErrorRecordThreshold() {
return Integer.parseInt(getOptional("kylin.job.error-record-threshold", "0"));
}
@@ -1073,6 +1073,14 @@ abstract public class KylinConfigBase implements Serializable {
return getOptionalIntArray("kylin.server.query-metrics-percentiles-intervals", dft);
}
+ public int getServerUserCacheExpireSeconds() {
+ return Integer.valueOf(this.getOptional("kylin.server.auth-user-cache.expire-seconds", "300"));
+ }
+
+ public int getServerUserCacheMaxEntries() {
+ return Integer.valueOf(this.getOptional("kylin.server.auth-user-cache.max-entries", "100"));
+ }
+
// ============================================================================
// WEB
// ============================================================================
http://git-wip-us.apache.org/repos/asf/kylin/blob/3280172b/server-base/src/main/java/org/apache/kylin/rest/security/KylinAuthenticationProvider.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/security/KylinAuthenticationProvider.java b/server-base/src/main/java/org/apache/kylin/rest/security/KylinAuthenticationProvider.java
index 7322b84..dd9cbad 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/security/KylinAuthenticationProvider.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/security/KylinAuthenticationProvider.java
@@ -18,7 +18,10 @@
package org.apache.kylin.rest.security;
-import org.apache.kylin.common.util.ByteArray;
+import java.util.Arrays;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.kylin.common.KylinConfig;
import org.apache.kylin.rest.service.UserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -32,13 +35,12 @@ import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.util.Assert;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.RemovalListener;
+import com.google.common.cache.RemovalNotification;
import com.google.common.hash.HashFunction;
import com.google.common.hash.Hashing;
-import net.sf.ehcache.Cache;
-import net.sf.ehcache.CacheManager;
-import net.sf.ehcache.Element;
-
/**
* A wrapper class for the authentication provider; Will do something more for Kylin.
*/
@@ -46,13 +48,21 @@ public class KylinAuthenticationProvider implements AuthenticationProvider {
private static final Logger logger = LoggerFactory.getLogger(KylinAuthenticationProvider.class);
+ private final static com.google.common.cache.Cache<String, Authentication> userCache = CacheBuilder.newBuilder()
+ .maximumSize(KylinConfig.getInstanceFromEnv().getServerUserCacheMaxEntries())
+ .expireAfterWrite(KylinConfig.getInstanceFromEnv().getServerUserCacheExpireSeconds(), TimeUnit.SECONDS)
+ .removalListener(new RemovalListener<String, Authentication>() {
+ @Override
+ public void onRemoval(RemovalNotification<String, Authentication> notification) {
+ KylinAuthenticationProvider.logger.debug("User cache {} is removed due to {}",
+ notification.getKey(), notification.getCause());
+ }
+ }).build();
+
@Autowired
@Qualifier("userService")
UserService userService;
- @Autowired
- private CacheManager cacheManager;
-
//Embedded authentication provider
private AuthenticationProvider authenticationProvider;
@@ -67,48 +77,53 @@ public class KylinAuthenticationProvider implements AuthenticationProvider {
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
- Authentication authed = null;
- Cache userCache = cacheManager.getCache("UserCache");
+
byte[] hashKey = hf.hashString(authentication.getName() + authentication.getCredentials()).asBytes();
- ByteArray userKey = new ByteArray(hashKey);
+ String userKey = Arrays.toString(hashKey);
+
+ if (userService.isEvictCacheFlag()) {
+ userCache.invalidateAll();
+ userService.setEvictCacheFlag(false);
+ }
+ Authentication authed = userCache.getIfPresent(userKey);
- Element authedUser = userCache.get(userKey);
- if (null != authedUser) {
- authed = (Authentication) authedUser.getObjectValue();
+ if (null != authed) {
SecurityContextHolder.getContext().setAuthentication(authed);
} else {
try {
authed = authenticationProvider.authenticate(authentication);
- userCache.put(new Element(userKey, authed));
+
+ ManagedUser user;
+
+ if (authed.getDetails() == null) {
+ //authed.setAuthenticated(false);
+ throw new UsernameNotFoundException(
+ "User not found in LDAP, check whether he/she has been added to the groups.");
+ }
+
+ if (authed.getDetails() instanceof UserDetails) {
+ UserDetails details = (UserDetails) authed.getDetails();
+ user = new ManagedUser(details.getUsername(), details.getPassword(), false,
+ details.getAuthorities());
+ } else {
+ user = new ManagedUser(authentication.getName(), "skippped-ldap", false, authed.getAuthorities());
+ }
+ Assert.notNull(user, "The UserDetail is null.");
+
+ logger.debug("User {} authorities : {}", user.getUsername(), user.getAuthorities());
+ if (!userService.userExists(user.getUsername())) {
+ userService.createUser(user);
+ } else {
+ userService.updateUser(user);
+ }
+
+ userCache.put(userKey, authed);
} catch (AuthenticationException e) {
logger.error("Failed to auth user: " + authentication.getName(), e);
throw e;
}
logger.debug("Authenticated user " + authed.toString());
-
- ManagedUser user;
-
- if (authed.getDetails() == null) {
- //authed.setAuthenticated(false);
- throw new UsernameNotFoundException(
- "User not found in LDAP, check whether he/she has been added to the groups.");
- }
-
- if (authed.getDetails() instanceof UserDetails) {
- UserDetails details = (UserDetails) authed.getDetails();
- user = new ManagedUser(details.getUsername(), details.getPassword(), false, details.getAuthorities());
- } else {
- user = new ManagedUser(authentication.getName(), "skippped-ldap", false, authed.getAuthorities());
- }
- Assert.notNull(user, "The UserDetail is null.");
-
- logger.debug("User authorities :" + user.getAuthorities());
- if (!userService.userExists(user.getUsername())) {
- userService.createUser(user);
- } else {
- userService.updateUser(user);
- }
}
return authed;
http://git-wip-us.apache.org/repos/asf/kylin/blob/3280172b/server-base/src/main/java/org/apache/kylin/rest/security/ManagedUser.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/security/ManagedUser.java b/server-base/src/main/java/org/apache/kylin/rest/security/ManagedUser.java
index 4805d5c..280339e 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/security/ManagedUser.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/security/ManagedUser.java
@@ -22,8 +22,6 @@ import java.util.Collection;
import java.util.Iterator;
import java.util.List;
-import javax.annotation.Nullable;
-
import org.apache.kylin.common.persistence.RootPersistentEntity;
import org.apache.kylin.rest.service.UserGrantedAuthority;
import org.springframework.security.core.GrantedAuthority;
@@ -31,8 +29,6 @@ import org.springframework.security.core.userdetails.UserDetails;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonProperty;
-import com.google.common.base.Function;
-import com.google.common.collect.Collections2;
import com.google.common.collect.Lists;
@SuppressWarnings("serial")
@@ -44,7 +40,7 @@ public class ManagedUser extends RootPersistentEntity implements UserDetails {
@JsonProperty
private String password;
@JsonProperty
- private List<String> authorities = Lists.newArrayList();
+ private List<UserGrantedAuthority> authorities = Lists.newArrayList();
@JsonProperty
private boolean disabled = false;
@JsonProperty
@@ -56,24 +52,40 @@ public class ManagedUser extends RootPersistentEntity implements UserDetails {
@JsonProperty
private int wrongTime = 0;
- private Boolean legacyCatered = false;
//DISABLED_ROLE is a ancient way to represent disabled user
//now we no longer support such way, however legacy metadata may still contain it
private static final String DISABLED_ROLE = "--disabled--";
- //this is computed
- private List<UserGrantedAuthority> grantedAuthorities = null;
-
public ManagedUser() {
}
- public ManagedUser(String username, String password, Boolean defaultPassword, String... authorities) {
+ public ManagedUser(@JsonProperty String username, @JsonProperty String password,
+ @JsonProperty List<UserGrantedAuthority> authorities, @JsonProperty boolean disabled,
+ @JsonProperty boolean defaultPassword, @JsonProperty boolean locked, @JsonProperty long lockedTime,
+ @JsonProperty int wrongTime) {
+ this.username = username;
+ this.password = password;
+ this.authorities = authorities;
+ this.disabled = disabled;
+ this.defaultPassword = defaultPassword;
+ this.locked = locked;
+ this.lockedTime = lockedTime;
+ this.wrongTime = wrongTime;
+
+ caterLegacy();
+ }
+
+ public ManagedUser(String username, String password, Boolean defaultPassword, String... authoritiesStr) {
this.username = username;
this.password = password;
this.setDefaultPassword(defaultPassword);
- this.authorities = Lists.newArrayList(authorities);
- this.grantedAuthorities = null;
+ this.authorities = Lists.newArrayList();
+ for (String a : authoritiesStr) {
+ authorities.add(new UserGrantedAuthority(a));
+ }
+
+ caterLegacy();
}
public ManagedUser(String username, String password, Boolean defaultPassword,
@@ -83,6 +95,8 @@ public class ManagedUser extends RootPersistentEntity implements UserDetails {
this.setDefaultPassword(defaultPassword);
this.setGrantedAuthorities(grantedAuthorities);
+
+ caterLegacy();
}
public String getUsername() {
@@ -102,45 +116,27 @@ public class ManagedUser extends RootPersistentEntity implements UserDetails {
}
private void caterLegacy() {
- if (!legacyCatered) {
- synchronized (legacyCatered) {
- Iterator<String> iterator = authorities.iterator();
- while (iterator.hasNext()) {
- if (DISABLED_ROLE.equals(iterator.next())) {
- iterator.remove();
- this.disabled = true;
- }
- }
- legacyCatered = true;
+ Iterator<UserGrantedAuthority> iterator = authorities.iterator();
+ while (iterator.hasNext()) {
+ if (DISABLED_ROLE.equals(iterator.next().getAuthority())) {
+ iterator.remove();
+ this.disabled = true;
}
}
}
public List<UserGrantedAuthority> getAuthorities() {
- caterLegacy();
- if (grantedAuthorities == null) {
- grantedAuthorities = Lists.newArrayList();
- for (String a : authorities) {
- this.grantedAuthorities.add(new UserGrantedAuthority(a));
- }
- }
- return grantedAuthorities;
+ return this.authorities;
}
public void setGrantedAuthorities(Collection<? extends GrantedAuthority> grantedAuthorities) {
- this.authorities = Lists
- .newArrayList(Collections2.transform(grantedAuthorities, new Function<GrantedAuthority, String>() {
- @Nullable
- @Override
- public String apply(@Nullable GrantedAuthority input) {
- return input.getAuthority();
- }
- }));
- this.grantedAuthorities = null;
+ this.authorities = Lists.newArrayList();
+ for (GrantedAuthority grantedAuthority : grantedAuthorities) {
+ this.authorities.add(new UserGrantedAuthority(grantedAuthority.getAuthority()));
+ }
}
public boolean isDisabled() {
- caterLegacy();
return disabled;
}
@@ -230,6 +226,6 @@ public class ManagedUser extends RootPersistentEntity implements UserDetails {
@Override
public String toString() {
- return "KapManagedUser [username=" + username + ", authorities=" + grantedAuthorities + "]";
+ return "ManagedUser [username=" + username + ", authorities=" + authorities + "]";
}
}
http://git-wip-us.apache.org/repos/asf/kylin/blob/3280172b/server-base/src/main/java/org/apache/kylin/rest/service/UserService.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/service/UserService.java b/server-base/src/main/java/org/apache/kylin/rest/service/UserService.java
index 504c035..6682c03 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/service/UserService.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/service/UserService.java
@@ -54,6 +54,16 @@ public class UserService implements UserDetailsManager {
public static final Serializer<ManagedUser> SERIALIZER = new JsonSerializer<>(ManagedUser.class);
protected ResourceStore aclStore;
+
+ private boolean evictCacheFlag = false;
+
+ public boolean isEvictCacheFlag() {
+ return evictCacheFlag;
+ }
+
+ public void setEvictCacheFlag(boolean evictCacheFlag) {
+ this.evictCacheFlag = evictCacheFlag;
+ }
@PostConstruct
public void init() throws IOException {
http://git-wip-us.apache.org/repos/asf/kylin/blob/3280172b/server/src/main/resources/ehcache-test.xml
----------------------------------------------------------------------
diff --git a/server/src/main/resources/ehcache-test.xml b/server/src/main/resources/ehcache-test.xml
index bffe27a..5bd4d13 100644
--- a/server/src/main/resources/ehcache-test.xml
+++ b/server/src/main/resources/ehcache-test.xml
@@ -27,11 +27,4 @@
>
<persistence strategy="none"/>
</cache>
- <cache name="UserCache"
- eternal="false"
- timeToLiveSeconds="10800"
- memoryStoreEvictionPolicy="LRU"
- >
- <persistence strategy="none"/>
- </cache>
-</ehcache>
\ No newline at end of file
+</ehcache>
http://git-wip-us.apache.org/repos/asf/kylin/blob/3280172b/server/src/main/resources/ehcache.xml
----------------------------------------------------------------------
diff --git a/server/src/main/resources/ehcache.xml b/server/src/main/resources/ehcache.xml
index 1d49ca6..c9efc13 100644
--- a/server/src/main/resources/ehcache.xml
+++ b/server/src/main/resources/ehcache.xml
@@ -27,11 +27,4 @@
>
<persistence strategy="none"/>
</cache>
- <cache name="UserCache"
- eternal="false"
- timeToLiveSeconds="10800"
- memoryStoreEvictionPolicy="LRU"
- >
- <persistence strategy="none"/>
- </cache>
-</ehcache>
\ No newline at end of file
+</ehcache>
[40/50] kylin git commit: minor, fix thread local KylinConfig bug
Posted by li...@apache.org.
minor, fix thread local KylinConfig bug
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/0f8c21ba
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/0f8c21ba
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/0f8c21ba
Branch: refs/heads/master
Commit: 0f8c21ba350afee829a5e847d234705d8b2ef559
Parents: 81ff9a4
Author: Hongbin Ma <ma...@apache.org>
Authored: Sun Jun 25 17:03:16 2017 +0800
Committer: Dong Li <li...@apache.org>
Committed: Sun Jun 25 17:17:49 2017 +0800
----------------------------------------------------------------------
.../src/main/java/org/apache/kylin/common/KylinConfig.java | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/0f8c21ba/core-common/src/main/java/org/apache/kylin/common/KylinConfig.java
----------------------------------------------------------------------
diff --git a/core-common/src/main/java/org/apache/kylin/common/KylinConfig.java b/core-common/src/main/java/org/apache/kylin/common/KylinConfig.java
index 0f77096..1298807 100644
--- a/core-common/src/main/java/org/apache/kylin/common/KylinConfig.java
+++ b/core-common/src/main/java/org/apache/kylin/common/KylinConfig.java
@@ -57,7 +57,7 @@ public class KylinConfig extends KylinConfigBase {
private static KylinConfig SYS_ENV_INSTANCE = null;
// thread-local instances, will override SYS_ENV_INSTANCE
- private static final transient ThreadLocal<KylinConfig> THREAD_ENV_INSTANCE = new ThreadLocal<>();
+ private static transient ThreadLocal<KylinConfig> THREAD_ENV_INSTANCE = new ThreadLocal<>();
public static KylinConfig getInstanceFromEnv() {
synchronized (KylinConfig.class) {
@@ -88,7 +88,7 @@ public class KylinConfig extends KylinConfigBase {
logger.info("Destroy KylinConfig");
dumpStackTrace();
SYS_ENV_INSTANCE = null;
- THREAD_ENV_INSTANCE.remove();
+ THREAD_ENV_INSTANCE = new ThreadLocal<>();
}
}
@@ -197,6 +197,10 @@ public class KylinConfig extends KylinConfigBase {
public static void setKylinConfigThreadLocal(KylinConfig config) {
THREAD_ENV_INSTANCE.set(config);
}
+
+ public static void removeKylinConfigThreadLocal() {
+ THREAD_ENV_INSTANCE.remove();
+ }
public static KylinConfig createKylinConfig(String propsInStr) throws IOException {
Properties props = new Properties();
[07/50] kylin git commit: minor, improve odbc performance
Posted by li...@apache.org.
minor, improve odbc performance
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/51f22e28
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/51f22e28
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/51f22e28
Branch: refs/heads/master
Commit: 51f22e284467f23c8aeeed8ea79e5133ddd1141e
Parents: f32165e
Author: lidongsjtu <li...@apache.org>
Authored: Thu Jun 15 17:03:20 2017 +0800
Committer: Hongbin Ma <ma...@kyligence.io>
Committed: Thu Jun 15 21:17:54 2017 +0800
----------------------------------------------------------------------
odbc/Common/REST.cpp | 67 +++++++++++++++++++++--------------
odbc/Common/REST.h | 1 +
odbc/Driver/KO_DIAG.CPP | 17 ++++-----
odbc/Driver/KO_EXEC.CPP | 6 ++--
odbc/TestDLL/SimpleQueryTest.cpp | 6 ++--
5 files changed, 57 insertions(+), 40 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/51f22e28/odbc/Common/REST.cpp
----------------------------------------------------------------------
diff --git a/odbc/Common/REST.cpp b/odbc/Common/REST.cpp
index 858ecd4..8f0c7bb 100644
--- a/odbc/Common/REST.cpp
+++ b/odbc/Common/REST.cpp
@@ -280,34 +280,28 @@ std::unique_ptr <MetadataResponse> restGetMeta ( char* serverAddr, long port, ch
wstring cookQuery ( wchar_t* p )
{
- wchar_t* q = new wchar_t[wcslen ( p ) + 1];
- wcscpy ( q, p );
-
- for ( int i = 0; i < ( int ) wcslen ( q ); i++ )
- {
- if ( q[i] == '\r' || q[i] == '\n' || q[i] == '\t' )
- {
- q[i] = ' ';
- }
- }
-
- wstring ret ( q );
- delete[] q;
- size_t pos = 0;
+ std::wstringstream wss;
- for ( size_t pos = 0;; pos += 2 )
+ int l = wcslen ( p );
+ for ( int i = 0; i < l; i++ )
{
- pos = ret . find ( L"\"", pos );
-
- if ( pos == wstring::npos )
+ if ( p[i] == L'\r' || p[i] == L'\n' || p[i] == L'\t' )
{
- break;
- }
-
- ret . insert ( pos, L"\\" );
+ wss << L' ';
+ }
+
+ else if (p[i] == L'"')
+ {
+ wss << L"\\\"";
+ }
+
+ else
+ {
+ wss << p[i];
+ }
}
- return ret;
+ return wss.str();
}
wstring getBodyString ( http_response& response )
@@ -389,10 +383,15 @@ std::unique_ptr <SQLResponse> convertToSQLResponse ( int statusFlag,
wstring requestQuery ( wchar_t* rawSql, char* serverAddr, long port, char* username,
char* passwd,
char* project,
+ bool isPrepare,
int* statusFlag)
{
//using local cache to intercept probing queries
- const wchar_t* cachedQueryRes = loadCache ( rawSql );
+ const wchar_t* cachedQueryRes = NULL;
+
+ if (isPrepare) {
+ cachedQueryRes = loadCache ( rawSql );
+ }
if ( cachedQueryRes != NULL )
{
@@ -404,8 +403,24 @@ wstring requestQuery ( wchar_t* rawSql, char* serverAddr, long port, char* usern
wstring serverAddrW = completeServerStr ( serverAddr, port );
http_client_config config;
config . set_timeout ( utility::seconds ( 36000 ) );
+
+ //uncomment these lines for debug with proxy
+ //wstring p = L"http://127.0.0.1:8888";
+ //config.set_proxy(web_proxy(p));
+
http_client session ( serverAddrW, config );
- http_request request = makeRequest ( username, passwd, L"/kylin/api/query", methods::POST );
+ http_request request;
+
+ if (!isPrepare)
+ {
+ request = makeRequest ( username, passwd, L"/kylin/api/query", methods::POST );
+ }
+
+ else
+ {
+ request = makeRequest ( username, passwd, L"/kylin/api/query/prestate", methods::POST );
+ }
+
wstring sql = cookQuery ( rawSql );
std::wstringstream wss;
wss << L"{ \"acceptPartial\": false, \"project\" : \"" << project << L"\", " << " \"sql\" : \"" << sql << L"\" }" ;
@@ -444,7 +459,7 @@ wstring requestQuery ( wchar_t* rawSql, char* serverAddr, long port, char* usern
wstring ret = getBodyString ( response );
- if (*statusFlag == 1)
+ if (*statusFlag == 1 && isPrepare)
{
storeCache(rawSql, ret.c_str());
}
http://git-wip-us.apache.org/repos/asf/kylin/blob/51f22e28/odbc/Common/REST.h
----------------------------------------------------------------------
diff --git a/odbc/Common/REST.h b/odbc/Common/REST.h
index f70d7d5..60c14a7 100644
--- a/odbc/Common/REST.h
+++ b/odbc/Common/REST.h
@@ -38,4 +38,5 @@ std::unique_ptr <SQLResponse> convertToSQLResponse ( int status,
wstring requestQuery ( wchar_t* rawSql, char* serverAddr, long port, char* username,
char* passwd,
char* project,
+ bool isPrepare,
int* statusFlag);
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/kylin/blob/51f22e28/odbc/Driver/KO_DIAG.CPP
----------------------------------------------------------------------
diff --git a/odbc/Driver/KO_DIAG.CPP b/odbc/Driver/KO_DIAG.CPP
index ac313e7..def819c 100644
--- a/odbc/Driver/KO_DIAG.CPP
+++ b/odbc/Driver/KO_DIAG.CPP
@@ -644,7 +644,8 @@ RETCODE SQL_API SQLGetDiagRec ( SQLSMALLINT pHandleType,
pODBCDiagRow _SQLPutDiagRow ( pODBCDiag pDiag, StrPtr pFunc, StrPtr pState, Long pNativeErrorCode,
StrPtr pMsgArgs, va_list pArgs )
{
- Char s[4096]; // arbitary and maximum length of message
+ // to avoid: TST1003: The message for sqlstate '01000' is longer than SQL_MAX_MESSAGE_LENGTH - 1.
+ Char s[SQL_MAX_MESSAGE_LENGTH - 1]; // arbitary and maximum length of message
pODBCDiagRow l;
pODBCDiagRow r;
@@ -660,7 +661,7 @@ pODBCDiagRow _SQLPutDiagRow ( pODBCDiag pDiag, StrPtr pFunc, StrPtr pState, Long
// check if there is some message
if ( pMsgArgs )
{
- vsprintf ( s + strlen ( s ), pMsgArgs, pArgs );
+ vsnprintf ( s + strlen ( s ), SQL_MAX_MESSAGE_LENGTH - 2 - strlen(s), pMsgArgs, pArgs );
}
else
@@ -1110,13 +1111,13 @@ void _ODBCLogMsg ( LogLevel level, const char* pMsgArgs, ... )
break;
}
- time_t now = time ( 0 );
- struct tm tstruct;
- char buffer[100];
- tstruct = *localtime ( &now );
- strftime ( buffer, 100, "%Y-%m-%d.%X", &tstruct );
+ char ts[24];
+ SYSTEMTIME sys;
+ GetLocalTime( &sys );
+ sprintf( ts, "%4d-%02d-%02d %02d:%02d:%02d.%03d", sys.wYear, sys.wMonth, sys.wDay, sys.wHour, sys.wMinute, sys.wSecond, sys.wMilliseconds);
+
_write ( gLogFile, "[", 1 );
- _write ( gLogFile, buffer, strlen ( buffer ) );
+ _write ( gLogFile, ts, strlen ( ts ) );
_write ( gLogFile, "]", 1 );
// MSG PARSING
http://git-wip-us.apache.org/repos/asf/kylin/blob/51f22e28/odbc/Driver/KO_EXEC.CPP
----------------------------------------------------------------------
diff --git a/odbc/Driver/KO_EXEC.CPP b/odbc/Driver/KO_EXEC.CPP
index 514375e..8a8992c 100644
--- a/odbc/Driver/KO_EXEC.CPP
+++ b/odbc/Driver/KO_EXEC.CPP
@@ -129,7 +129,7 @@ RETCODE SQL_API _SQLExecStmtFromReq ( pODBCStmt pStmt, bool pPrepared ) {
try {
__ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "start to call rest api" ) );
response = requestQuery ( pStmt->Stmt, pStmt->Conn->Server, pStmt->Conn->ServerPort, pStmt->Conn->UserName, pStmt->Conn->Password,
- pStmt->Conn->Project, &status );
+ pStmt->Conn->Project, pPrepared, &status );
__ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "received and uncompressed rest response:" ) );
p = convertToSQLResponse(status, response);
__ODBCLOG ( _ODBCLogMsg ( LogLevel_DEBUG, "parsed to SQLResponse" ) );
@@ -207,7 +207,7 @@ RETCODE SQL_API SQLPrepareW ( SQLHSTMT pStmt,
( ( pODBCStmt ) pStmt )->Prepared = 1;
- return _SQLExecStmtFromReq((pODBCStmt)pStmt,1);
+ return _SQLExecStmtFromReq((pODBCStmt)pStmt, 1);
//return SQL_SUCCESS;
}
@@ -230,7 +230,7 @@ RETCODE SQL_API SQLExecute ( HSTMT pStmt ) {
}
// excute the request
- x = _SQLExecStmtFromReq ( ( pODBCStmt ) pStmt, 1 );
+ x = _SQLExecStmtFromReq ( ( pODBCStmt ) pStmt, 0 );
return x;
}
http://git-wip-us.apache.org/repos/asf/kylin/blob/51f22e28/odbc/TestDLL/SimpleQueryTest.cpp
----------------------------------------------------------------------
diff --git a/odbc/TestDLL/SimpleQueryTest.cpp b/odbc/TestDLL/SimpleQueryTest.cpp
index 7f857a9..9705b5e 100644
--- a/odbc/TestDLL/SimpleQueryTest.cpp
+++ b/odbc/TestDLL/SimpleQueryTest.cpp
@@ -23,7 +23,7 @@ void simpleQueryTest ()
//Intercept query test
{
int status;
- wstring s = requestQuery ( L"SELECT 1", KServerAddr, KPort, KUserName, KPassword, KDefaultProject, &status );
+ wstring s = requestQuery ( L"SELECT 1", KServerAddr, KPort, KUserName, KPassword, KDefaultProject, false, &status );
std::unique_ptr <SQLResponse> y = convertToSQLResponse(status, s);
if ( ( int ) y -> results . size () != 1 )
@@ -34,7 +34,7 @@ void simpleQueryTest ()
//Ungzipped Query Test
{
int status;
- wstring s = requestQuery ( L"select cal_dt from test_kylin_fact limit 1", KServerAddr, KPort, KUserName, KPassword, KDefaultProject, &status );
+ wstring s = requestQuery ( L"select cal_dt from test_kylin_fact limit 1", KServerAddr, KPort, KUserName, KPassword, KDefaultProject, false, &status );
std::unique_ptr <SQLResponse> y = convertToSQLResponse(status, s);
if ( ( int ) y -> results . size () != 1 )
@@ -45,7 +45,7 @@ void simpleQueryTest ()
//zipped Query Test
{
int status;
- wstring s = requestQuery ( L"select * from test_kylin_fact limit 12", KServerAddr, KPort, KUserName, KPassword, KDefaultProject, &status );
+ wstring s = requestQuery ( L"select * from test_kylin_fact limit 12", KServerAddr, KPort, KUserName, KPassword, KDefaultProject, false, &status );
std::unique_ptr <SQLResponse> y = convertToSQLResponse(status, s);
if ( ( int ) y -> results . size () != 12 )
[38/50] kylin git commit: minor, fix NPE when limit or offset is null
Posted by li...@apache.org.
minor, fix NPE when limit or offset is null
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/ba7bfd61
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/ba7bfd61
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/ba7bfd61
Branch: refs/heads/master
Commit: ba7bfd6131f3bb296dacbec3066340ffdce5765b
Parents: 3280172
Author: Hongbin Ma <ma...@apache.org>
Authored: Fri Jun 23 21:04:28 2017 +0800
Committer: Hongbin Ma <ma...@kyligence.io>
Committed: Fri Jun 23 21:26:05 2017 +0800
----------------------------------------------------------------------
.../src/main/java/org/apache/kylin/rest/request/SQLRequest.java | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/ba7bfd61/server-base/src/main/java/org/apache/kylin/rest/request/SQLRequest.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/request/SQLRequest.java b/server-base/src/main/java/org/apache/kylin/rest/request/SQLRequest.java
index 4b3d9c8..54900ba 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/request/SQLRequest.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/request/SQLRequest.java
@@ -68,7 +68,7 @@ public class SQLRequest implements Serializable {
}
public Integer getOffset() {
- return offset;
+ return offset == null ? 0 : offset;
}
public void setOffset(Integer offset) {
@@ -76,7 +76,7 @@ public class SQLRequest implements Serializable {
}
public Integer getLimit() {
- return limit;
+ return limit == null ? 0 : limit;
}
public void setLimit(Integer limit) {
[11/50] kylin git commit: Support schedule streaming cube (#1148)
Posted by li...@apache.org.
Support schedule streaming cube (#1148)
* Support schedule streaming cube
* Resume schedulers after login
* Set streaming cube's endOffset from Integer.MAX_VALUE to Long.MAX_VALUE
* Call AccessService apis only for rest apis.
* Resume scheduler jobs after scheduler service initialized.
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/81d26370
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/81d26370
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/81d26370
Branch: refs/heads/master
Commit: 81d26370c8365faf1de2c74cfb2af7869d786a1a
Parents: 6182589
Author: Ni Chunen <zj...@sjtu.org>
Authored: Fri Jun 16 21:24:14 2017 +0800
Committer: Roger Shi <ro...@gmail.com>
Committed: Fri Jun 16 21:24:14 2017 +0800
----------------------------------------------------------------------
.../java/org/apache/kylin/rest/service/JobService.java | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/81d26370/server-base/src/main/java/org/apache/kylin/rest/service/JobService.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/service/JobService.java b/server-base/src/main/java/org/apache/kylin/rest/service/JobService.java
index 7eb1292..6451d66 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/service/JobService.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/service/JobService.java
@@ -205,8 +205,13 @@ public class JobService extends BasicService implements InitializingBean {
public JobInstance submitJob(CubeInstance cube, long startDate, long endDate, long startOffset, long endOffset, //
Map<Integer, Long> sourcePartitionOffsetStart, Map<Integer, Long> sourcePartitionOffsetEnd,
CubeBuildTypeEnum buildType, boolean force, String submitter) throws IOException {
- return submitJobInternal(cube, startDate, endDate, startOffset, endOffset, sourcePartitionOffsetStart,
+ JobInstance jobInstance = submitJobInternal(cube, startDate, endDate, startOffset, endOffset, sourcePartitionOffsetStart,
sourcePartitionOffsetEnd, buildType, force, submitter);
+
+ accessService.init(jobInstance, null);
+ accessService.inherit(jobInstance, cube);
+
+ return jobInstance;
}
public JobInstance submitJobInternal(CubeInstance cube, long startDate, long endDate, long startOffset,
@@ -262,9 +267,6 @@ public class JobService extends BasicService implements InitializingBean {
JobInstance jobInstance = getSingleJobInstance(job);
- accessService.init(jobInstance, null);
- accessService.inherit(jobInstance, cube);
-
return jobInstance;
}
[46/50] kylin git commit: KYLIN-2681 Convert input sql's expression
to computed column if computed colum defined
Posted by li...@apache.org.
KYLIN-2681 Convert input sql's expression to computed column if computed colum defined
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/05631b58
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/05631b58
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/05631b58
Branch: refs/heads/master
Commit: 05631b588c0b49bb156e85dcaf3dca27e79b700c
Parents: 4f20ba3
Author: Aron.tao <24...@qq.com>
Authored: Sun Jun 25 18:45:27 2017 +0800
Committer: Hongbin Ma <ma...@kyligence.io>
Committed: Tue Jun 27 18:29:11 2017 +0800
----------------------------------------------------------------------
.../query/util/CognosParenthesesEscape.java | 2 +-
.../query/util/ConvertToComputedColumn.java | 353 +++++++++++++++++++
.../query/util/KeywordDefaultDirtyHack.java | 2 +-
.../org/apache/kylin/query/util/QueryUtil.java | 11 +-
.../query/util/CognosParenthesesEscapeTest.java | 32 +-
.../query/util/ConvertToComputedColumnTest.java | 135 +++++++
.../apache/kylin/query/util/QueryUtilTest.java | 6 +-
.../apache/kylin/rest/service/QueryService.java | 2 +-
8 files changed, 520 insertions(+), 23 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/05631b58/query/src/main/java/org/apache/kylin/query/util/CognosParenthesesEscape.java
----------------------------------------------------------------------
diff --git a/query/src/main/java/org/apache/kylin/query/util/CognosParenthesesEscape.java b/query/src/main/java/org/apache/kylin/query/util/CognosParenthesesEscape.java
index 6d930a5..8c6d82d 100644
--- a/query/src/main/java/org/apache/kylin/query/util/CognosParenthesesEscape.java
+++ b/query/src/main/java/org/apache/kylin/query/util/CognosParenthesesEscape.java
@@ -32,7 +32,7 @@ public class CognosParenthesesEscape implements QueryUtil.IQueryTransformer {
private static final Pattern FROM_PATTERN = Pattern.compile("\\s+from\\s+(\\s*\\(\\s*)+(?!\\s*select\\s)", Pattern.CASE_INSENSITIVE);
@Override
- public String transform(String sql) {
+ public String transform(String sql, String project) {
if (sql == null || sql.isEmpty()) {
return sql;
}
http://git-wip-us.apache.org/repos/asf/kylin/blob/05631b58/query/src/main/java/org/apache/kylin/query/util/ConvertToComputedColumn.java
----------------------------------------------------------------------
diff --git a/query/src/main/java/org/apache/kylin/query/util/ConvertToComputedColumn.java b/query/src/main/java/org/apache/kylin/query/util/ConvertToComputedColumn.java
new file mode 100644
index 0000000..d8f1220
--- /dev/null
+++ b/query/src/main/java/org/apache/kylin/query/util/ConvertToComputedColumn.java
@@ -0,0 +1,353 @@
+/*
+ * 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.query.util;
+
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+import javax.annotation.Nullable;
+
+import org.apache.calcite.sql.SqlCall;
+import org.apache.calcite.sql.SqlDataTypeSpec;
+import org.apache.calcite.sql.SqlDynamicParam;
+import org.apache.calcite.sql.SqlIdentifier;
+import org.apache.calcite.sql.SqlIntervalQualifier;
+import org.apache.calcite.sql.SqlLiteral;
+import org.apache.calcite.sql.SqlNode;
+import org.apache.calcite.sql.SqlNodeList;
+import org.apache.calcite.sql.SqlSelect;
+import org.apache.calcite.sql.parser.SqlParseException;
+import org.apache.calcite.sql.parser.SqlParser;
+import org.apache.calcite.sql.parser.SqlParserPos;
+import org.apache.calcite.sql.util.SqlVisitor;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.kylin.common.KylinConfig;
+import org.apache.kylin.metadata.MetadataManager;
+import org.apache.kylin.metadata.model.DataModelDesc;
+import org.apache.kylin.metadata.project.ProjectInstance;
+import org.apache.kylin.metadata.project.ProjectManager;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Functions;
+import com.google.common.base.Predicate;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSortedMap;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Ordering;
+
+public class ConvertToComputedColumn implements QueryUtil.IQueryTransformer {
+ private static final Logger logger = LoggerFactory.getLogger(ConvertToComputedColumn.class);
+
+ @Override
+ public String transform(String sql, String project) {
+ if (project == null) {
+ return sql;
+ }
+ ImmutableSortedMap<String, String> computedColumns = getSortedComputedColumnWithProject(project);
+ return replaceComputedColumn(sql, computedColumns);
+ }
+
+ static String replaceComputedColumn(String inputSql, ImmutableSortedMap<String, String> computedColumn) {
+ if (inputSql == null) {
+ return "";
+ }
+
+ if (computedColumn == null || computedColumn.isEmpty()) {
+ return inputSql;
+ }
+ String result = inputSql;
+ String[] lines = inputSql.split("\n");
+ List<Pair<String, String>> toBeReplacedExp = new ArrayList<>(); //{"alias":"expression"}, like {"t1":"t1.a+t1.b+t1.c"}
+
+ for (String ccExp : computedColumn.keySet()) {
+ List<SqlNode> matchedNodes = new ArrayList<>();
+ try {
+ matchedNodes = getMatchedNodes(inputSql, computedColumn.get(ccExp));
+ } catch (SqlParseException e) {
+ logger.error("Convert to computedColumn Fail,parse sql fail ", e.getMessage());
+ }
+ for (SqlNode node : matchedNodes) {
+ Pair<Integer, Integer> startEndPos = getReplacePos(lines, node);
+ int start = startEndPos.getLeft();
+ int end = startEndPos.getRight();
+ //add table alias like t1.column,if exists alias
+ String alias = getTableAlias(node);
+ toBeReplacedExp.add(Pair.of(alias, inputSql.substring(start, end)));
+ }
+ logger.debug("Computed column: " + ccExp + "'s matched list:" + toBeReplacedExp);
+ //replace user's input sql
+ for (Pair<String, String> toBeReplaced : toBeReplacedExp) {
+ result = result.replace(toBeReplaced.getRight(), toBeReplaced.getLeft() + ccExp);
+ }
+ }
+ return result;
+ }
+
+ private static Pair<Integer, Integer> getReplacePos(String[] lines, SqlNode node) {
+ SqlParserPos pos = node.getParserPosition();
+ int lineStart = pos.getLineNum();
+ int columnStart = pos.getColumnNum() - 1;
+ int columnEnd = pos.getEndColumnNum();
+ //for the case that sql is multi lines
+ for (int i = 0; i < lineStart - 1; i++) {
+ int offset = lines[i].length();
+ columnStart += offset + 1;
+ columnEnd += offset + 1;
+ }
+ return Pair.of(columnStart, columnEnd);
+ }
+
+ //Return matched node's position and its alias(if exists).If can not find matches, return an empty capacity list
+ private static List<SqlNode> getMatchedNodes(String inputSql, String ccExp) throws SqlParseException {
+ if (ccExp == null || ccExp.equals("")) {
+ return new ArrayList<>();
+ }
+ ArrayList<SqlNode> toBeReplacedNodes = new ArrayList<>();
+ SqlNode ccNode = getCCExpNode(ccExp);
+ List<SqlNode> inputNodes = getInputTreeNodes(inputSql);
+
+ // find whether user input sql's tree node equals computed columns's define expression
+ for (SqlNode inputNode : inputNodes) {
+ if (isNodeEqual(inputNode, ccNode)) {
+ toBeReplacedNodes.add(inputNode);
+ }
+ }
+ return toBeReplacedNodes;
+ }
+
+ private static List<SqlNode> getInputTreeNodes(String inputSql) throws SqlParseException {
+ SqlTreeVisitor stv = new SqlTreeVisitor();
+ parse(inputSql).accept(stv);
+ return stv.getSqlNodes();
+ }
+
+ private static SqlNode getCCExpNode(String ccExp) throws SqlParseException {
+ ccExp = "select " + ccExp + " from t";
+ return ((SqlSelect) parse(ccExp)).getSelectList().get(0);
+ }
+
+ static SqlNode parse(String sql) throws SqlParseException {
+ SqlParser.ConfigBuilder parserBuilder = SqlParser.configBuilder();
+ SqlParser sqlParser = SqlParser.create(sql, parserBuilder.build());
+ return sqlParser.parseQuery();
+ }
+
+ static boolean isNodeEqual(SqlNode node0, SqlNode node1) {
+ if (node0 == null) {
+ return node1 == null;
+ } else if (node1 == null) {
+ return false;
+ }
+
+ if (!Objects.equals(node0.getClass().getSimpleName(), node1.getClass().getSimpleName())) {
+ return false;
+ }
+
+ if (node0 instanceof SqlCall) {
+ SqlCall thisNode = (SqlCall) node0;
+ SqlCall thatNode = (SqlCall) node1;
+ if (!thisNode.getOperator().getName().equalsIgnoreCase(thatNode.getOperator().getName())) {
+ return false;
+ }
+ return isNodeEqual(thisNode.getOperandList(), thatNode.getOperandList());
+ }
+ if (node0 instanceof SqlLiteral) {
+ SqlLiteral thisNode = (SqlLiteral) node0;
+ SqlLiteral thatNode = (SqlLiteral) node1;
+ return Objects.equals(thisNode.getValue(), thatNode.getValue());
+ }
+ if (node0 instanceof SqlNodeList) {
+ SqlNodeList thisNode = (SqlNodeList) node0;
+ SqlNodeList thatNode = (SqlNodeList) node1;
+ if (thisNode.getList().size() != thatNode.getList().size()) {
+ return false;
+ }
+ for (int i = 0; i < thisNode.getList().size(); i++) {
+ SqlNode thisChild = thisNode.getList().get(i);
+ final SqlNode thatChild = thatNode.getList().get(i);
+ if (!isNodeEqual(thisChild, thatChild)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ if (node0 instanceof SqlIdentifier) {
+ SqlIdentifier thisNode = (SqlIdentifier) node0;
+ SqlIdentifier thatNode = (SqlIdentifier) node1;
+ // compare ignore table alias.eg: expression like "a.b + a.c + a.d" ,alias a will be ignored when compared
+ String name0 = thisNode.names.get(thisNode.names.size() - 1).replace("\"", "");
+ String name1 = thatNode.names.get(thatNode.names.size() - 1).replace("\"", "");
+ return name0.equalsIgnoreCase(name1);
+ }
+
+ logger.error("Convert to computed column fail,failed to compare two nodes,unknown instance type");
+ return false;
+ }
+
+ private static boolean isNodeEqual(List<SqlNode> operands0, List<SqlNode> operands1) {
+ if (operands0.size() != operands1.size()) {
+ return false;
+ }
+ for (int i = 0; i < operands0.size(); i++) {
+ if (!isNodeEqual(operands0.get(i), operands1.get(i))) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private static String getTableAlias(SqlNode node) {
+ if (node instanceof SqlCall) {
+ SqlCall call = (SqlCall) node;
+ return getTableAlias(call.getOperandList());
+ }
+ if (node instanceof SqlIdentifier) {
+ StringBuilder alias = new StringBuilder("");
+ ImmutableList<String> names = ((SqlIdentifier) node).names;
+ if (names.size() >= 2) {
+ for (int i = 0; i < names.size() - 1; i++) {
+ alias.append(names.get(i)).append(".");
+ }
+ }
+ return alias.toString();
+ }
+ if (node instanceof SqlNodeList) {
+ return "";
+ }
+ if (node instanceof SqlLiteral) {
+ return "";
+ }
+ return "";
+ }
+
+ private static String getTableAlias(List<SqlNode> operands) {
+ for (SqlNode operand : operands) {
+ return getTableAlias(operand);
+ }
+ return "";
+ }
+
+ private ImmutableSortedMap<String, String> getSortedComputedColumnWithProject(String project) {
+ MetadataManager metadataManager = MetadataManager.getInstance(KylinConfig.getInstanceFromEnv());
+ Map<String, MetadataManager.CCInfo> ccInfoMap = metadataManager.getCcInfoMap();
+ final ProjectInstance projectInstance = ProjectManager.getInstance(KylinConfig.getInstanceFromEnv())
+ .getProject(project);
+
+ Iterable<MetadataManager.CCInfo> projectCCInfo = Iterables.filter(ccInfoMap.values(),
+ new Predicate<MetadataManager.CCInfo>() {
+ @Override
+ public boolean apply(@Nullable MetadataManager.CCInfo ccInfo) {
+ return Iterables.any(ccInfo.getDataModelDescs(), new Predicate<DataModelDesc>() {
+ @Override
+ public boolean apply(@Nullable DataModelDesc model) {
+ return projectInstance.containsModel(model.getName());
+ }
+ });
+ }
+ });
+
+ Map<String, String> computedColumns = new HashMap<>();
+ for (MetadataManager.CCInfo ccInfo : projectCCInfo) {
+ computedColumns.put(ccInfo.getComputedColumnDesc().getColumnName(),
+ ccInfo.getComputedColumnDesc().getExpression());
+ }
+
+ return getMapSortedByValue(computedColumns);
+ }
+
+ static ImmutableSortedMap<String, String> getMapSortedByValue(Map<String, String> computedColumns) {
+ if (computedColumns == null || computedColumns.isEmpty()) {
+ return null;
+ }
+
+ Ordering<String> ordering = Ordering.from(new Comparator<String>() {
+ @Override
+ public int compare(String o1, String o2) {
+ return Integer.compare(o1.replaceAll("\\s*", "").length(), o2.replaceAll("\\s*", "").length());
+ }
+ }).reverse().nullsLast().onResultOf(Functions.forMap(computedColumns, null)).compound(Ordering.natural());
+ return ImmutableSortedMap.copyOf(computedColumns, ordering);
+ }
+
+}
+
+class SqlTreeVisitor implements SqlVisitor<SqlNode> {
+ private List<SqlNode> sqlNodes;
+
+ SqlTreeVisitor() {
+ this.sqlNodes = new ArrayList<>();
+ }
+
+ List<SqlNode> getSqlNodes() {
+ return sqlNodes;
+ }
+
+ @Override
+ public SqlNode visit(SqlNodeList nodeList) {
+ sqlNodes.add(nodeList);
+ for (int i = 0; i < nodeList.size(); i++) {
+ SqlNode node = nodeList.get(i);
+ node.accept(this);
+ }
+ return null;
+ }
+
+ @Override
+ public SqlNode visit(SqlLiteral literal) {
+ sqlNodes.add(literal);
+ return null;
+ }
+
+ @Override
+ public SqlNode visit(SqlCall call) {
+ sqlNodes.add(call);
+ for (SqlNode operand : call.getOperandList()) {
+ if (operand != null) {
+ operand.accept(this);
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public SqlNode visit(SqlIdentifier id) {
+ sqlNodes.add(id);
+ return null;
+ }
+
+ @Override
+ public SqlNode visit(SqlDataTypeSpec type) {
+ return null;
+ }
+
+ @Override
+ public SqlNode visit(SqlDynamicParam param) {
+ return null;
+ }
+
+ @Override
+ public SqlNode visit(SqlIntervalQualifier intervalQualifier) {
+ return null;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/kylin/blob/05631b58/query/src/main/java/org/apache/kylin/query/util/KeywordDefaultDirtyHack.java
----------------------------------------------------------------------
diff --git a/query/src/main/java/org/apache/kylin/query/util/KeywordDefaultDirtyHack.java b/query/src/main/java/org/apache/kylin/query/util/KeywordDefaultDirtyHack.java
index e1398f6..23faf8e 100644
--- a/query/src/main/java/org/apache/kylin/query/util/KeywordDefaultDirtyHack.java
+++ b/query/src/main/java/org/apache/kylin/query/util/KeywordDefaultDirtyHack.java
@@ -21,7 +21,7 @@ package org.apache.kylin.query.util;
public class KeywordDefaultDirtyHack implements QueryUtil.IQueryTransformer {
@Override
- public String transform(String sql) {
+ public String transform(String sql, String project) {
// KYLIN-2108, DEFAULT is hive default database, but a sql keyword too, needs quote
sql = sql.replace("DEFAULT.", "\"DEFAULT\".");
sql = sql.replace("default.", "\"default\".");
http://git-wip-us.apache.org/repos/asf/kylin/blob/05631b58/query/src/main/java/org/apache/kylin/query/util/QueryUtil.java
----------------------------------------------------------------------
diff --git a/query/src/main/java/org/apache/kylin/query/util/QueryUtil.java b/query/src/main/java/org/apache/kylin/query/util/QueryUtil.java
index d48a26f..7794f94 100644
--- a/query/src/main/java/org/apache/kylin/query/util/QueryUtil.java
+++ b/query/src/main/java/org/apache/kylin/query/util/QueryUtil.java
@@ -38,14 +38,15 @@ public class QueryUtil {
private static List<IQueryTransformer> queryTransformers;
public interface IQueryTransformer {
- String transform(String sql);
+ String transform(String sql, String project);
}
+ // for mockup test
public static String massageSql(String sql) {
- return massageSql(sql, 0, 0);
+ return massageSql(sql, null, 0, 0);
}
- public static String massageSql(String sql, int limit, int offset) {
+ public static String massageSql(String sql, String project, int limit, int offset) {
sql = sql.trim();
sql = sql.replace("\r", " ").replace("\n", System.getProperty("line.separator"));
@@ -65,7 +66,7 @@ public class QueryUtil {
initQueryTransformers();
}
for (IQueryTransformer t : queryTransformers) {
- sql = t.transform(sql);
+ sql = t.transform(sql, project);
}
return sql;
}
@@ -100,7 +101,7 @@ public class QueryUtil {
private static final Pattern PTN_HAVING_ESCAPE_FUNCTION = Pattern.compile("\\{fn" + "(.*?)" + "\\}", Pattern.CASE_INSENSITIVE);
@Override
- public String transform(String sql) {
+ public String transform(String sql, String project) {
Matcher m;
// Case fn{ EXTRACT(...) }
http://git-wip-us.apache.org/repos/asf/kylin/blob/05631b58/query/src/test/java/org/apache/kylin/query/util/CognosParenthesesEscapeTest.java
----------------------------------------------------------------------
diff --git a/query/src/test/java/org/apache/kylin/query/util/CognosParenthesesEscapeTest.java b/query/src/test/java/org/apache/kylin/query/util/CognosParenthesesEscapeTest.java
index 153c097..7825dbd 100644
--- a/query/src/test/java/org/apache/kylin/query/util/CognosParenthesesEscapeTest.java
+++ b/query/src/test/java/org/apache/kylin/query/util/CognosParenthesesEscapeTest.java
@@ -15,6 +15,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package org.apache.kylin.query.util;
import java.io.File;
@@ -33,16 +34,18 @@ public class CognosParenthesesEscapeTest {
CognosParenthesesEscape escape = new CognosParenthesesEscape();
String data = " from ((a left outer join b on a.x1 = b.y1 and a.x2=b.y2 and a.x3= b.y3) inner join c as cc on a.x1=cc.z1 ) join d dd on a.x1=d.w1 and a.x2 =d.w2 ";
String expected = " from a left outer join b on a.x1 = b.y1 and a.x2=b.y2 and a.x3= b.y3 inner join c as cc on a.x1=cc.z1 join d dd on a.x1=d.w1 and a.x2 =d.w2 ";
- String transformed = escape.transform(data);
+ String transformed = escape.transform(data, null);
Assert.assertEquals(expected, transformed);
}
@Test
public void advanced1Test() throws IOException {
CognosParenthesesEscape escape = new CognosParenthesesEscape();
- String query = FileUtils.readFileToString(new File("src/test/resources/query/cognos/query01.sql"), Charset.defaultCharset());
- String expected = FileUtils.readFileToString(new File("src/test/resources/query/cognos/query01.sql.expected"), Charset.defaultCharset());
- String transformed = escape.transform(query);
+ String query = FileUtils.readFileToString(new File("src/test/resources/query/cognos/query01.sql"),
+ Charset.defaultCharset());
+ String expected = FileUtils.readFileToString(new File("src/test/resources/query/cognos/query01.sql.expected"),
+ Charset.defaultCharset());
+ String transformed = escape.transform(query, null);
//System.out.println(transformed);
Assert.assertEquals(expected, transformed);
}
@@ -50,9 +53,11 @@ public class CognosParenthesesEscapeTest {
@Test
public void advanced2Test() throws IOException {
CognosParenthesesEscape escape = new CognosParenthesesEscape();
- String query = FileUtils.readFileToString(new File("src/test/resources/query/cognos/query02.sql"), Charset.defaultCharset());
- String expected = FileUtils.readFileToString(new File("src/test/resources/query/cognos/query02.sql.expected"), Charset.defaultCharset());
- String transformed = escape.transform(query);
+ String query = FileUtils.readFileToString(new File("src/test/resources/query/cognos/query02.sql"),
+ Charset.defaultCharset());
+ String expected = FileUtils.readFileToString(new File("src/test/resources/query/cognos/query02.sql.expected"),
+ Charset.defaultCharset());
+ String transformed = escape.transform(query, null);
//System.out.println(transformed);
Assert.assertEquals(expected, transformed);
}
@@ -60,9 +65,11 @@ public class CognosParenthesesEscapeTest {
@Test
public void advanced3Test() throws IOException {
CognosParenthesesEscape escape = new CognosParenthesesEscape();
- String query = FileUtils.readFileToString(new File("src/test/resources/query/cognos/query03.sql"), Charset.defaultCharset());
- String expected = FileUtils.readFileToString(new File("src/test/resources/query/cognos/query03.sql.expected"), Charset.defaultCharset());
- String transformed = escape.transform(query);
+ String query = FileUtils.readFileToString(new File("src/test/resources/query/cognos/query03.sql"),
+ Charset.defaultCharset());
+ String expected = FileUtils.readFileToString(new File("src/test/resources/query/cognos/query03.sql.expected"),
+ Charset.defaultCharset());
+ String transformed = escape.transform(query, null);
//System.out.println(transformed);
Assert.assertEquals(expected, transformed);
}
@@ -70,11 +77,12 @@ public class CognosParenthesesEscapeTest {
@Test
public void proguardTest() throws IOException {
CognosParenthesesEscape escape = new CognosParenthesesEscape();
- Collection<File> files = FileUtils.listFiles(new File("../kylin-it/src/test/resources"), new String[] { "sql" }, true);
+ Collection<File> files = FileUtils.listFiles(new File("../kylin-it/src/test/resources"), new String[] { "sql" },
+ true);
for (File f : files) {
System.out.println("checking " + f.getAbsolutePath());
String query = FileUtils.readFileToString(f, Charset.defaultCharset());
- String transformed = escape.transform(query);
+ String transformed = escape.transform(query, null);
Assert.assertEquals(query, transformed);
}
}
http://git-wip-us.apache.org/repos/asf/kylin/blob/05631b58/query/src/test/java/org/apache/kylin/query/util/ConvertToComputedColumnTest.java
----------------------------------------------------------------------
diff --git a/query/src/test/java/org/apache/kylin/query/util/ConvertToComputedColumnTest.java b/query/src/test/java/org/apache/kylin/query/util/ConvertToComputedColumnTest.java
new file mode 100644
index 0000000..c3efe8d
--- /dev/null
+++ b/query/src/test/java/org/apache/kylin/query/util/ConvertToComputedColumnTest.java
@@ -0,0 +1,135 @@
+/*
+ * 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.query.util;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.calcite.sql.SqlNode;
+import org.apache.calcite.sql.SqlSelect;
+import org.apache.calcite.sql.parser.SqlParseException;
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.google.common.collect.ImmutableSortedMap;
+
+public class ConvertToComputedColumnTest {
+ @Test
+ public void testEqual() throws SqlParseException {
+ String sql0 = "select a.a + a.b + a.c from t as a";
+ String sql1 = "select (((a . a + a.b + a.c))) from t as a";
+ String sql2 = "select (a + b) + c from t";
+ String sql3 = "select a.a + (a.b + a.c) from t as a";
+
+ SqlNode sn0 = getSelectNode(sql0);
+ SqlNode sn1 = getSelectNode(sql1);
+ SqlNode sn2 = getSelectNode(sql2);
+ SqlNode sn3 = getSelectNode(sql3);
+
+ Assert.assertEquals(true, ConvertToComputedColumn.isNodeEqual(sn0, sn1));
+ Assert.assertEquals(true, ConvertToComputedColumn.isNodeEqual(sn0, sn2));
+ Assert.assertEquals(false, ConvertToComputedColumn.isNodeEqual(sn0, sn3));
+ }
+
+ @Test
+ public void testErrorCase() {
+ //computed column is null or empty
+ String sql = "select a from t";
+ Map<String, String> map = new HashMap<>();
+ ImmutableSortedMap<String, String> computedColumns = ConvertToComputedColumn.getMapSortedByValue(map);
+ Assert.assertEquals("select a from t", ConvertToComputedColumn.replaceComputedColumn(sql, null));
+ Assert.assertEquals("select a from t", ConvertToComputedColumn.replaceComputedColumn(sql, computedColumns));
+
+ //input is null or empty or parse error
+ String sql1 = "";
+ String sql2 = "select sum(a from t";
+ Map<String, String> map2 = new HashMap<>();
+ map2.put("cc", "a + b");
+ ImmutableSortedMap<String, String> computedColumns2 = ConvertToComputedColumn.getMapSortedByValue(map2);
+ Assert.assertEquals("", ConvertToComputedColumn.replaceComputedColumn(null, computedColumns2));
+ Assert.assertEquals("", ConvertToComputedColumn.replaceComputedColumn(sql1, computedColumns2));
+ Assert.assertEquals("select sum(a from t",
+ ConvertToComputedColumn.replaceComputedColumn(sql2, computedColumns2));
+ }
+
+ @Test
+ public void testReplaceComputedColumn() throws SqlParseException {
+ String sql0 = "select (\"DB\".\"t1\" . \"a\" + DB.t1.b + DB.t1.c) as c, substring(substring(lstg_format_name,1,3),1,3) as d from table1 as t1 group by t1.a+ t1.b + t1.c having t1.a+t1.b+t1.c > 100 order by t1.a +t1.b +t1.c";
+ String sql1 = "select sum(sum(a)) from t";
+ String sql2 = "select t1.a + t1.b as aa, t2.c + t2.d as bb from table1 t1,table2 t2 where t1.a + t1.b > t2.c + t2.d order by t1.a + t1.b";
+ String sql3 = "select substring(substring(lstg_format_name,1,3),1,3) from a";
+
+ String expr0 = "a + b + c";
+ String expr1 = "sum(a)";
+ String expr2 = "a + b";
+ String expr3 = "c + d";
+ String expr = "substring(substring(lstg_format_name,1,3),1,3)";
+
+ Map<String, String> map = new HashMap<>();
+ map.put("cc0", expr0);
+ map.put("cc1", expr1);
+ map.put("cc2", expr2);
+ map.put("cc3", expr3);
+ map.put("cc", expr);
+
+ ImmutableSortedMap<String, String> computedColumns = ConvertToComputedColumn.getMapSortedByValue(map);
+ Assert.assertEquals(
+ "select (DB.t1.cc0) as c, cc as d from table1 as t1 group by T1.cc0 having T1.cc0 > 100 order by T1.cc0",
+ ConvertToComputedColumn.replaceComputedColumn(sql0, computedColumns));
+ Assert.assertEquals("select sum(cc1) from t",
+ ConvertToComputedColumn.replaceComputedColumn(sql1, computedColumns));
+ Assert.assertEquals(
+ "select T1.cc2 as aa, T2.cc3 as bb from table1 t1,table2 t2 where T1.cc2 > T2.cc3 order by T1.cc2",
+ ConvertToComputedColumn.replaceComputedColumn(sql2, computedColumns));
+ Assert.assertEquals("select cc from a", ConvertToComputedColumn.replaceComputedColumn(sql3, computedColumns));
+
+ }
+
+ private static SqlNode getSelectNode(String sql) throws SqlParseException {
+ return ((SqlSelect) ConvertToComputedColumn.parse(sql)).getSelectList().get(0);
+ }
+
+ @Test
+ public void testTwoCCHasSameSubExp() {
+ String sql0 = "select a + b + c from t order by a + b";
+
+ String expr0 = "a + b";
+ String expr1 = "a + b + c";
+
+ Map<String, String> map = new HashMap<>();
+ map.put("cc1", expr0);
+ map.put("cc0", expr1);
+ ImmutableSortedMap<String, String> computedColumns = ConvertToComputedColumn.getMapSortedByValue(map);
+ Assert.assertEquals("select cc0 from t order by cc1",
+ ConvertToComputedColumn.replaceComputedColumn(sql0, computedColumns));
+
+ //防止添加的顺序造成影响
+ String expr11 = "a + b + c";
+ String expr00 = "a + b";
+
+ Map<String, String> map2 = new HashMap<>();
+ map2.put("cc0", expr11);
+ map2.put("cc1", expr00);
+ ImmutableSortedMap<String, String> computedColumns1 = ConvertToComputedColumn.getMapSortedByValue(map2);
+ Assert.assertEquals("select cc0 from t order by cc1",
+ ConvertToComputedColumn.replaceComputedColumn(sql0, computedColumns1));
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/kylin/blob/05631b58/query/src/test/java/org/apache/kylin/query/util/QueryUtilTest.java
----------------------------------------------------------------------
diff --git a/query/src/test/java/org/apache/kylin/query/util/QueryUtilTest.java b/query/src/test/java/org/apache/kylin/query/util/QueryUtilTest.java
index a1edd89..f168d1e 100644
--- a/query/src/test/java/org/apache/kylin/query/util/QueryUtilTest.java
+++ b/query/src/test/java/org/apache/kylin/query/util/QueryUtilTest.java
@@ -40,12 +40,12 @@ public class QueryUtilTest extends LocalFileMetadataTestCase {
public void testMassageSql() {
{
String sql = "select ( date '2001-09-28' + interval floor(1.2) day) from test_kylin_fact";
- String s = QueryUtil.massageSql(sql, 0, 0);
+ String s = QueryUtil.massageSql(sql, null, 0, 0);
Assert.assertEquals("select ( date '2001-09-28' + interval '1' day) from test_kylin_fact", s);
}
{
String sql = "select ( date '2001-09-28' + interval floor(2) month) from test_kylin_fact group by ( date '2001-09-28' + interval floor(2) month)";
- String s = QueryUtil.massageSql(sql, 0, 0);
+ String s = QueryUtil.massageSql(sql, null, 0, 0);
Assert.assertEquals("select ( date '2001-09-28' + interval '2' month) from test_kylin_fact group by ( date '2001-09-28' + interval '2' month)", s);
}
}
@@ -54,7 +54,7 @@ public class QueryUtilTest extends LocalFileMetadataTestCase {
public void testKeywordDefaultDirtyHack() {
{
String sql = "select * from DEFAULT.TEST_KYLIN_FACT";
- String s = QueryUtil.massageSql(sql, 0, 0);
+ String s = QueryUtil.massageSql(sql, null, 0, 0);
Assert.assertEquals("select * from \"DEFAULT\".TEST_KYLIN_FACT", s);
}
}
http://git-wip-us.apache.org/repos/asf/kylin/blob/05631b58/server-base/src/main/java/org/apache/kylin/rest/service/QueryService.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/service/QueryService.java b/server-base/src/main/java/org/apache/kylin/rest/service/QueryService.java
index d6554fc..8d18901 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/service/QueryService.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/service/QueryService.java
@@ -471,7 +471,7 @@ public class QueryService extends BasicService {
return fakeResponse;
}
- String correctedSql = QueryUtil.massageSql(sqlRequest.getSql(), sqlRequest.getLimit(), sqlRequest.getOffset());
+ String correctedSql = QueryUtil.massageSql(sqlRequest.getSql(), sqlRequest.getProject(), sqlRequest.getLimit(), sqlRequest.getOffset());
if (!correctedSql.equals(sqlRequest.getSql())) {
logger.info("The corrected query: " + correctedSql);
[15/50] kylin git commit: KYLIN-2676 Add UUID into excludes list
Posted by li...@apache.org.
KYLIN-2676 Add UUID into excludes list
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/66dc5418
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/66dc5418
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/66dc5418
Branch: refs/heads/master
Commit: 66dc5418ce9860103a67398256ee11a7e428d4a0
Parents: ea06950
Author: auphyroc99 <45...@qq.com>
Authored: Fri Jun 16 15:32:33 2017 +0800
Committer: Hongbin Ma <ma...@kyligence.io>
Committed: Mon Jun 19 13:23:47 2017 +0800
----------------------------------------------------------------------
.../kylin/common/persistence/ResourceTool.java | 40 +++++++++++++++-----
1 file changed, 31 insertions(+), 9 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/66dc5418/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 6ba68ae..6a73e12 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
@@ -37,6 +37,8 @@ public class ResourceTool {
private static String[] excludes = null;
private static final Logger logger = LoggerFactory.getLogger(ResourceTool.class);
+ private static final String[] IMMUTABLE_PREFIX = { "/UUID" };
+
public static void main(String[] args) throws IOException {
args = StringUtil.filterSystemArgs(args);
@@ -52,13 +54,15 @@ public class ResourceTool {
String include = System.getProperty("include");
if (include != null) {
- setIncludes(include.split("\\s*,\\s*"));
+ addIncludes(include.split("\\s*,\\s*"));
}
String exclude = System.getProperty("exclude");
if (exclude != null) {
- setExcludes(exclude.split("\\s*,\\s*"));
+ addExcludes(exclude.split("\\s*,\\s*"));
}
+ addExcludes(IMMUTABLE_PREFIX);
+
String cmd = args[0];
switch (cmd) {
case "reset":
@@ -91,16 +95,34 @@ public class ResourceTool {
return includes;
}
- public static void setIncludes(String[] arg) {
- includes = arg;
+ public static void addIncludes(String[] arg) {
+ if (arg != null) {
+ if (includes != null) {
+ String[] nIncludes = new String[includes.length + arg.length];
+ System.arraycopy(includes, 0, nIncludes, 0, includes.length);
+ System.arraycopy(arg, 0, nIncludes, includes.length, arg.length);
+ includes = nIncludes;
+ } else {
+ includes = arg;
+ }
+ }
}
public static String[] getExcludes() {
return excludes;
}
- public static void setExcludes(String[] arg) {
- excludes = arg;
+ public static void addExcludes(String[] arg) {
+ if (arg != null) {
+ if (excludes != null) {
+ String[] nExcludes = new String[excludes.length + arg.length];
+ System.arraycopy(excludes, 0, nExcludes, 0, excludes.length);
+ System.arraycopy(arg, 0, nExcludes, excludes.length, arg.length);
+ excludes = nExcludes;
+ } else {
+ excludes = arg;
+ }
+ }
}
public static String cat(KylinConfig config, String path) throws IOException {
@@ -134,16 +156,16 @@ public class ResourceTool {
ResourceStore dst = ResourceStore.getStore(dstConfig);
logger.info("Copy from {} to {}", src, dst);
-
+
copyR(src, dst, path);
}
public static void copy(KylinConfig srcConfig, KylinConfig dstConfig, List<String> paths) throws IOException {
ResourceStore src = ResourceStore.getStore(srcConfig);
ResourceStore dst = ResourceStore.getStore(dstConfig);
-
+
logger.info("Copy from {} to {}", src, dst);
-
+
for (String path : paths) {
copyR(src, dst, path);
}
[24/50] kylin git commit: disable csrf for spring 4
Posted by li...@apache.org.
disable csrf for spring 4
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/7661ad79
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/7661ad79
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/7661ad79
Branch: refs/heads/master
Commit: 7661ad79b40e9defcd02019f9b55ce0299459dd2
Parents: 73faf99
Author: Roger Shi <ro...@hotmail.com>
Authored: Tue Jun 20 18:40:38 2017 +0800
Committer: Hongbin Ma <ma...@kyligence.io>
Committed: Tue Jun 20 19:14:02 2017 +0800
----------------------------------------------------------------------
server/src/main/resources/kylinSecurity.xml | 2 ++
1 file changed, 2 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/7661ad79/server/src/main/resources/kylinSecurity.xml
----------------------------------------------------------------------
diff --git a/server/src/main/resources/kylinSecurity.xml b/server/src/main/resources/kylinSecurity.xml
index 43a0082..506b2f1 100644
--- a/server/src/main/resources/kylinSecurity.xml
+++ b/server/src/main/resources/kylinSecurity.xml
@@ -29,6 +29,8 @@
<scr:expression-handler ref="expressionHandler"/>
</scr:global-method-security>
+ <scr:csrf disabled="true"/>
+
<!-- acl config -->
<bean id="aclPermissionFactory" class="org.apache.kylin.rest.security.AclPermissionFactory"/>
[06/50] kylin git commit: #1173 refine Cube and Model search API
Posted by li...@apache.org.
#1173 refine Cube and Model search API
provide both exact-match and fuzzy search API for Cube and Model
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/f32165ef
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/f32165ef
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/f32165ef
Branch: refs/heads/master
Commit: f32165ef3c89ed6a6004a63d28f7227e6cd6d1e6
Parents: 56e9fb9
Author: Roger Shi <ro...@hotmail.com>
Authored: Thu Jun 15 20:56:07 2017 +0800
Committer: Hongbin Ma <ma...@kyligence.io>
Committed: Thu Jun 15 21:16:29 2017 +0800
----------------------------------------------------------------------
.../apache/kylin/rest/controller/CubeController.java | 2 +-
.../kylin/rest/controller2/CubeControllerV2.java | 3 ++-
.../kylin/rest/controller2/ModelControllerV2.java | 3 ++-
.../org/apache/kylin/rest/service/CubeService.java | 5 +++--
.../org/apache/kylin/rest/service/ModelService.java | 15 ++++++++-------
.../org/apache/kylin/rest/service/QueryService.java | 2 +-
.../apache/kylin/rest/service/CubeServiceTest.java | 2 +-
.../apache/kylin/rest/service/ModelServiceTest.java | 6 +++---
8 files changed, 21 insertions(+), 17 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/f32165ef/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 bfa5603..14c80a0 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
@@ -101,7 +101,7 @@ public class CubeController extends BasicController {
@ResponseBody
public List<CubeInstance> getCubes(@RequestParam(value = "cubeName", required = false) String cubeName, @RequestParam(value = "modelName", required = false) String modelName, @RequestParam(value = "projectName", required = false) String projectName, @RequestParam(value = "limit", required = false) Integer limit, @RequestParam(value = "offset", required = false) Integer offset) {
List<CubeInstance> cubes;
- cubes = cubeService.listAllCubes(cubeName, projectName, modelName);
+ cubes = cubeService.listAllCubes(cubeName, projectName, modelName, true);
int climit = (null == limit) ? cubes.size() : limit;
int coffset = (null == offset) ? 0 : offset;
http://git-wip-us.apache.org/repos/asf/kylin/blob/f32165ef/server-base/src/main/java/org/apache/kylin/rest/controller2/CubeControllerV2.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/controller2/CubeControllerV2.java b/server-base/src/main/java/org/apache/kylin/rest/controller2/CubeControllerV2.java
index 309fffc..720cf76 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/controller2/CubeControllerV2.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/controller2/CubeControllerV2.java
@@ -102,6 +102,7 @@ public class CubeControllerV2 extends BasicController {
@RequestMapping(value = "", method = { RequestMethod.GET }, produces = { "application/vnd.apache.kylin-v2+json" })
@ResponseBody
public EnvelopeResponse getCubesPaging(@RequestParam(value = "cubeName", required = false) String cubeName,
+ @RequestParam(value = "exactMatch", required = false, defaultValue = "true") boolean exactMatch,
@RequestParam(value = "modelName", required = false) String modelName,
@RequestParam(value = "projectName", required = false) String projectName,
@RequestParam(value = "pageOffset", required = false, defaultValue = "0") Integer pageOffset,
@@ -109,7 +110,7 @@ public class CubeControllerV2 extends BasicController {
HashMap<String, Object> data = new HashMap<String, Object>();
List<CubeInstanceResponse> response = new ArrayList<CubeInstanceResponse>();
- List<CubeInstance> cubes = cubeService.listAllCubes(cubeName, projectName, modelName);
+ List<CubeInstance> cubes = cubeService.listAllCubes(cubeName, projectName, modelName, exactMatch);
// official cubes
for (CubeInstance cube : cubes) {
http://git-wip-us.apache.org/repos/asf/kylin/blob/f32165ef/server-base/src/main/java/org/apache/kylin/rest/controller2/ModelControllerV2.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/controller2/ModelControllerV2.java b/server-base/src/main/java/org/apache/kylin/rest/controller2/ModelControllerV2.java
index e775c9c..58f6bee 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/controller2/ModelControllerV2.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/controller2/ModelControllerV2.java
@@ -92,6 +92,7 @@ public class ModelControllerV2 extends BasicController {
@RequestMapping(value = "", method = { RequestMethod.GET }, produces = { "application/vnd.apache.kylin-v2+json" })
@ResponseBody
public EnvelopeResponse getModelsPaging(@RequestParam(value = "modelName", required = false) String modelName,
+ @RequestParam(value = "exactMatch", required = false, defaultValue = "true") boolean exactMatch,
@RequestParam(value = "projectName", required = false) String projectName,
@RequestParam(value = "pageOffset", required = false, defaultValue = "0") Integer pageOffset,
@RequestParam(value = "pageSize", required = false, defaultValue = "10") Integer pageSize)
@@ -100,7 +101,7 @@ public class ModelControllerV2 extends BasicController {
List<DataModelDescResponse> response = new ArrayList<DataModelDescResponse>();
// official models
- for (DataModelDesc m : modelService.listAllModels(modelName, projectName)) {
+ for (DataModelDesc m : modelService.listAllModels(modelName, projectName, exactMatch)) {
Preconditions.checkState(!m.isDraft());
DataModelDescResponse r = new DataModelDescResponse(m);
http://git-wip-us.apache.org/repos/asf/kylin/blob/f32165ef/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 4a03e05..74d8578 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
@@ -97,7 +97,7 @@ public class CubeService extends BasicService {
private ModelService modelService;
@PostFilter(Constant.ACCESS_POST_FILTER_READ)
- public List<CubeInstance> listAllCubes(final String cubeName, final String projectName, final String modelName) {
+ public List<CubeInstance> listAllCubes(final String cubeName, final String projectName, final String modelName, boolean exactMatch) {
List<CubeInstance> cubeInstances = null;
ProjectInstance project = (null != projectName) ? getProjectManager().getProject(projectName) : null;
@@ -124,7 +124,8 @@ public class CubeService extends BasicService {
List<CubeInstance> filterCubes = new ArrayList<CubeInstance>();
for (CubeInstance cubeInstance : filterModelCubes) {
boolean isCubeMatch = (null == cubeName)
- || cubeInstance.getName().toLowerCase().contains(cubeName.toLowerCase());
+ || (!exactMatch && cubeInstance.getName().toLowerCase().contains(cubeName.toLowerCase())) ||
+ (exactMatch && cubeInstance.getName().toLowerCase().equals(cubeName.toLowerCase()));
if (isCubeMatch) {
filterCubes.add(cubeInstance);
http://git-wip-us.apache.org/repos/asf/kylin/blob/f32165ef/server-base/src/main/java/org/apache/kylin/rest/service/ModelService.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/service/ModelService.java b/server-base/src/main/java/org/apache/kylin/rest/service/ModelService.java
index 14ee65a..fa54eaa 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/service/ModelService.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/service/ModelService.java
@@ -73,7 +73,7 @@ public class ModelService extends BasicService {
private CubeService cubeService;
@PostFilter(Constant.ACCESS_POST_FILTER_READ)
- public List<DataModelDesc> listAllModels(final String modelName, final String projectName) throws IOException {
+ public List<DataModelDesc> listAllModels(final String modelName, final String projectName, boolean exactMatch) throws IOException {
List<DataModelDesc> models;
ProjectInstance project = (null != projectName) ? getProjectManager().getProject(projectName) : null;
@@ -86,7 +86,8 @@ public class ModelService extends BasicService {
List<DataModelDesc> filterModels = new ArrayList<DataModelDesc>();
for (DataModelDesc modelDesc : models) {
boolean isModelMatch = (null == modelName) || modelName.length() == 0
- || modelDesc.getName().toLowerCase().equals(modelName.toLowerCase());
+ || (exactMatch && modelDesc.getName().toLowerCase().equals(modelName.toLowerCase()))
+ || (!exactMatch && modelDesc.getName().toLowerCase().contains(modelName.toLowerCase()));
if (isModelMatch) {
filterModels.add(modelDesc);
@@ -99,7 +100,7 @@ public class ModelService extends BasicService {
public List<DataModelDesc> getModels(final String modelName, final String projectName, final Integer limit,
final Integer offset) throws IOException {
- List<DataModelDesc> modelDescs = listAllModels(modelName, projectName);
+ List<DataModelDesc> modelDescs = listAllModels(modelName, projectName, true);
if (limit == null || offset == null) {
return modelDescs;
@@ -182,7 +183,7 @@ public class ModelService extends BasicService {
public Map<TblColRef, Set<CubeInstance>> getUsedDimCols(String modelName) {
Map<TblColRef, Set<CubeInstance>> ret = Maps.newHashMap();
- List<CubeInstance> cubeInstances = cubeService.listAllCubes(null, null, modelName);
+ List<CubeInstance> cubeInstances = cubeService.listAllCubes(null, null, modelName, true);
for (CubeInstance cubeInstance : cubeInstances) {
CubeDesc cubeDesc = cubeInstance.getDescriptor();
for (TblColRef tblColRef : cubeDesc.listDimensionColumnsIncludingDerived()) {
@@ -199,7 +200,7 @@ public class ModelService extends BasicService {
public Map<TblColRef, Set<CubeInstance>> getUsedNonDimCols(String modelName) {
Map<TblColRef, Set<CubeInstance>> ret = Maps.newHashMap();
- List<CubeInstance> cubeInstances = cubeService.listAllCubes(null, null, modelName);
+ List<CubeInstance> cubeInstances = cubeService.listAllCubes(null, null, modelName, true);
for (CubeInstance cubeInstance : cubeInstances) {
CubeDesc cubeDesc = cubeInstance.getDescriptor();
Set<TblColRef> tblColRefs = Sets.newHashSet(cubeDesc.listAllColumns());//make a copy
@@ -218,7 +219,7 @@ public class ModelService extends BasicService {
private boolean validateUpdatingModel(DataModelDesc dataModelDesc) throws IOException {
String modelName = dataModelDesc.getName();
- List<CubeInstance> cubes = cubeService.listAllCubes(null, null, modelName);
+ List<CubeInstance> cubes = cubeService.listAllCubes(null, null, modelName, true);
if (cubes != null && cubes.size() != 0) {
dataModelDesc.init(getConfig(), getMetadataManager().getAllTablesMap(),
getMetadataManager().getCcInfoMap());
@@ -255,7 +256,7 @@ public class ModelService extends BasicService {
return false;
}
- DataModelDesc originDataModelDesc = listAllModels(modelName, null).get(0);
+ DataModelDesc originDataModelDesc = listAllModels(modelName, null, true).get(0);
if (!dataModelDesc.getRootFactTable().equals(originDataModelDesc.getRootFactTable()))
return false;
http://git-wip-us.apache.org/repos/asf/kylin/blob/f32165ef/server-base/src/main/java/org/apache/kylin/rest/service/QueryService.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/service/QueryService.java b/server-base/src/main/java/org/apache/kylin/rest/service/QueryService.java
index 1b118a3..bf32140 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/service/QueryService.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/service/QueryService.java
@@ -610,7 +610,7 @@ public class QueryService extends BasicService {
ProjectInstance projectInstance = getProjectManager().getProject(project);
for (String modelName : projectInstance.getModels()) {
- DataModelDesc dataModelDesc = modelService.listAllModels(modelName, project).get(0);
+ DataModelDesc dataModelDesc = modelService.listAllModels(modelName, project, true).get(0);
if (!dataModelDesc.isDraft()) {
// update table type: FACT
http://git-wip-us.apache.org/repos/asf/kylin/blob/f32165ef/server/src/test/java/org/apache/kylin/rest/service/CubeServiceTest.java
----------------------------------------------------------------------
diff --git a/server/src/test/java/org/apache/kylin/rest/service/CubeServiceTest.java b/server/src/test/java/org/apache/kylin/rest/service/CubeServiceTest.java
index a190d6d..96146ef 100644
--- a/server/src/test/java/org/apache/kylin/rest/service/CubeServiceTest.java
+++ b/server/src/test/java/org/apache/kylin/rest/service/CubeServiceTest.java
@@ -51,7 +51,7 @@ public class CubeServiceTest extends ServiceTestBase {
Assert.assertNotNull(cubeService.getMetadataManager());
Assert.assertNotNull(cacheService.getOLAPDataSource(ProjectInstance.DEFAULT_PROJECT_NAME));
- List<CubeInstance> cubes = cubeService.listAllCubes(null, null, null);
+ List<CubeInstance> cubes = cubeService.listAllCubes(null, null, null, true);
Assert.assertNotNull(cubes);
CubeInstance cube = cubes.get(0);
}
http://git-wip-us.apache.org/repos/asf/kylin/blob/f32165ef/server/src/test/java/org/apache/kylin/rest/service/ModelServiceTest.java
----------------------------------------------------------------------
diff --git a/server/src/test/java/org/apache/kylin/rest/service/ModelServiceTest.java b/server/src/test/java/org/apache/kylin/rest/service/ModelServiceTest.java
index 2012a05..b78b18e 100644
--- a/server/src/test/java/org/apache/kylin/rest/service/ModelServiceTest.java
+++ b/server/src/test/java/org/apache/kylin/rest/service/ModelServiceTest.java
@@ -48,7 +48,7 @@ public class ModelServiceTest extends ServiceTestBase {
@Test
public void testSuccessModelUpdate() throws IOException, JobException {
- List<DataModelDesc> dataModelDescs = modelService.listAllModels("ci_inner_join_model", "default");
+ List<DataModelDesc> dataModelDescs = modelService.listAllModels("ci_inner_join_model", "default", true);
Assert.assertTrue(dataModelDescs.size() == 1);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
@@ -64,7 +64,7 @@ public class ModelServiceTest extends ServiceTestBase {
@Test
public void testSuccessModelUpdateOnComputedColumn() throws IOException, JobException, NoSuchFieldException, IllegalAccessException {
- List<DataModelDesc> dataModelDescs = modelService.listAllModels("ci_left_join_model", "default");
+ List<DataModelDesc> dataModelDescs = modelService.listAllModels("ci_left_join_model", "default", true);
Assert.assertTrue(dataModelDescs.size() == 1);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
@@ -83,7 +83,7 @@ public class ModelServiceTest extends ServiceTestBase {
expectedEx.expect(IllegalStateException.class);
expectedEx.expectMessage("Computed column named DEFAULT.TEST_KYLIN_FACT.DEAL_AMOUNT is already defined in other models: [DataModelDesc [name=ci_left_join_model], DataModelDesc [name=ci_inner_join_model]]. Please change another name, or try to keep consistent definition");
- List<DataModelDesc> dataModelDescs = modelService.listAllModels("ci_left_join_model", "default");
+ List<DataModelDesc> dataModelDescs = modelService.listAllModels("ci_left_join_model", "default", true);
Assert.assertTrue(dataModelDescs.size() == 1);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
[21/50] kylin git commit: upgrade to Spring 4
Posted by li...@apache.org.
upgrade to Spring 4
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/247f3cd2
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/247f3cd2
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/247f3cd2
Branch: refs/heads/master
Commit: 247f3cd266c77480ac0f8d329e8e7adb617b5de0
Parents: 5a4e465
Author: Yang Li <li...@apache.org>
Authored: Mon Jun 19 21:58:25 2017 +0800
Committer: Roger Shi <ro...@gmail.com>
Committed: Tue Jun 20 15:28:30 2017 +0800
----------------------------------------------------------------------
.../apache/kylin/common/KylinConfigBase.java | 3 ++
pom.xml | 28 ++++++++++++++----
.../rest/controller2/UserControllerV2.java | 7 +++--
.../kylin/rest/response/EnvelopeResponse.java | 6 ++--
.../apache/kylin/rest/service/UserService.java | 6 ++--
.../src/main/resources/applicationContext.xml | 31 +++++++-------------
server/src/main/resources/kylinSecurity.xml | 17 ++++++-----
7 files changed, 53 insertions(+), 45 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/247f3cd2/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 e64dddb..2ccf3cf 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
@@ -62,6 +62,9 @@ abstract public class KylinConfigBase implements Serializable {
public static String getKylinHome() {
String kylinHome = System.getenv("KYLIN_HOME");
if (StringUtils.isEmpty(kylinHome)) {
+ kylinHome = System.getProperty("KYLIN_HOME");
+ }
+ if (StringUtils.isEmpty(kylinHome)) {
logger.warn("KYLIN_HOME was not set");
}
return kylinHome;
http://git-wip-us.apache.org/repos/asf/kylin/blob/247f3cd2/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index f887c8d..506d734 100644
--- a/pom.xml
+++ b/pom.xml
@@ -114,11 +114,11 @@
<tomcat.version>7.0.69</tomcat.version>
<t-digest.version>3.1</t-digest.version>
- <!-- REST Service -->
- <spring.framework.version>3.2.17.RELEASE</spring.framework.version>
- <spring.framework.security.version>3.1.2.RELEASE</spring.framework.security.version>
- <spring.framework.security.extensions.version>1.0.2.RELEASE
- </spring.framework.security.extensions.version>
+ <!-- REST Service, ref https://github.com/spring-projects/spring-boot/blob/v1.3.8.RELEASE/spring-boot-dependencies/pom.xml -->
+ <spring.boot.version>1.3.8.RELEASE</spring.boot.version>
+ <spring.framework.version>4.2.8.RELEASE</spring.framework.version>
+ <spring.framework.security.version>4.0.4.RELEASE</spring.framework.security.version>
+ <spring.framework.security.extensions.version>1.0.2.RELEASE</spring.framework.security.extensions.version>
<opensaml.version>2.6.4</opensaml.version>
<aspectj.version>1.8.9</aspectj.version>
@@ -768,14 +768,30 @@
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
+ <artifactId>spring-security-config</artifactId>
+ <version>${spring.framework.security.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.security</groupId>
+ <artifactId>spring-security-core</artifactId>
+ <version>${spring.framework.security.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.security</groupId>
<artifactId>spring-security-ldap</artifactId>
<version>${spring.framework.security.version}</version>
</dependency>
<dependency>
+ <groupId>org.springframework.security</groupId>
+ <artifactId>spring-security-web</artifactId>
+ <version>${spring.framework.security.version}</version>
+ </dependency>
+ <dependency>
<groupId>org.springframework.security.extensions</groupId>
<artifactId>spring-security-saml2-core</artifactId>
<version>${spring.framework.security.extensions.version}</version>
</dependency>
+
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
@@ -1046,7 +1062,7 @@
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
- <version>1.3.6.RELEASE</version>
+ <version>${spring.boot.version}</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
http://git-wip-us.apache.org/repos/asf/kylin/blob/247f3cd2/server-base/src/main/java/org/apache/kylin/rest/controller2/UserControllerV2.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/controller2/UserControllerV2.java b/server-base/src/main/java/org/apache/kylin/rest/controller2/UserControllerV2.java
index 2f7a404..c0f5c17 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/controller2/UserControllerV2.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/controller2/UserControllerV2.java
@@ -19,6 +19,7 @@
package org.apache.kylin.rest.controller2;
import java.io.IOException;
+import java.util.List;
import org.apache.kylin.rest.controller.BasicController;
import org.apache.kylin.rest.exception.UnauthorizedException;
@@ -59,7 +60,7 @@ public class UserControllerV2 extends BasicController {
@RequestMapping(value = "/authentication", method = RequestMethod.POST, produces = {
"application/vnd.apache.kylin-v2+json" })
@ResponseBody
- public EnvelopeResponse authenticateV2() {
+ public EnvelopeResponse<UserDetails> authenticateV2() {
EnvelopeResponse response = authenticatedUserV2();
logger.debug("User login: {}", response.data);
return response;
@@ -68,7 +69,7 @@ public class UserControllerV2 extends BasicController {
@RequestMapping(value = "/authentication", method = RequestMethod.GET, produces = {
"application/vnd.apache.kylin-v2+json" })
@ResponseBody
- public EnvelopeResponse authenticatedUserV2() {
+ public EnvelopeResponse<UserDetails> authenticatedUserV2() {
Message msg = MsgPicker.getMsg();
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
@@ -95,7 +96,7 @@ public class UserControllerV2 extends BasicController {
@RequestMapping(value = "/authentication/authorities", method = RequestMethod.GET, produces = {
"application/vnd.apache.kylin-v2+json" })
@ResponseBody
- public EnvelopeResponse getAuthoritiesV2() throws IOException {
+ public EnvelopeResponse<List<String>> getAuthoritiesV2() throws IOException {
return new EnvelopeResponse(ResponseCode.CODE_SUCCESS, userService.listUserAuthorities(), "");
}
http://git-wip-us.apache.org/repos/asf/kylin/blob/247f3cd2/server-base/src/main/java/org/apache/kylin/rest/response/EnvelopeResponse.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/response/EnvelopeResponse.java b/server-base/src/main/java/org/apache/kylin/rest/response/EnvelopeResponse.java
index 7855dee..8350536 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/response/EnvelopeResponse.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/response/EnvelopeResponse.java
@@ -18,17 +18,17 @@
package org.apache.kylin.rest.response;
-public class EnvelopeResponse {
+public class EnvelopeResponse<T> {
public String code;
- public Object data;
+ public T data;
public String msg;
//only for child
protected EnvelopeResponse() {
}
- public EnvelopeResponse(String code, Object data, String msg) {
+ public EnvelopeResponse(String code, T data, String msg) {
this.code = code;
this.data = data;
this.msg = msg;
http://git-wip-us.apache.org/repos/asf/kylin/blob/247f3cd2/server-base/src/main/java/org/apache/kylin/rest/service/UserService.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/service/UserService.java b/server-base/src/main/java/org/apache/kylin/rest/service/UserService.java
index 5452543..9adfcb8 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/service/UserService.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/service/UserService.java
@@ -30,13 +30,11 @@ import org.apache.kylin.common.KylinConfig;
import org.apache.kylin.common.persistence.ResourceStore;
import org.apache.kylin.common.persistence.Serializer;
import org.apache.kylin.common.util.JsonUtil;
-import org.apache.kylin.rest.constant.Constant;
import org.apache.kylin.rest.exception.InternalErrorException;
import org.apache.kylin.rest.msg.Message;
import org.apache.kylin.rest.msg.MsgPicker;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
@@ -61,13 +59,13 @@ public class UserService implements UserDetailsManager {
}
@Override
- @PreAuthorize(Constant.ACCESS_HAS_ROLE_ADMIN)
+ //@PreAuthorize(Constant.ACCESS_HAS_ROLE_ADMIN) --- DON'T DO THIS, CAUSES CIRCULAR DEPENDENCY BETWEEN UserService & AclService
public void createUser(UserDetails user) {
updateUser(user);
}
@Override
- @PreAuthorize(Constant.ACCESS_HAS_ROLE_ADMIN)
+ //@PreAuthorize(Constant.ACCESS_HAS_ROLE_ADMIN) --- DON'T DO THIS, CAUSES CIRCULAR DEPENDENCY BETWEEN UserService & AclService
public void updateUser(UserDetails user) {
try {
deleteUser(user.getUsername());
http://git-wip-us.apache.org/repos/asf/kylin/blob/247f3cd2/server/src/main/resources/applicationContext.xml
----------------------------------------------------------------------
diff --git a/server/src/main/resources/applicationContext.xml b/server/src/main/resources/applicationContext.xml
index 8416f25..88286b5 100644
--- a/server/src/main/resources/applicationContext.xml
+++ b/server/src/main/resources/applicationContext.xml
@@ -21,15 +21,15 @@
xmlns:cache="http://www.springframework.org/schema/cache"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
+ http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/context
- http://www.springframework.org/schema/context/spring-context-3.1.xsd
+ http://www.springframework.org/schema/context/spring-context-4.2.xsd
http://www.springframework.org/schema/task
- http://www.springframework.org/schema/task/spring-task-3.1.xsd
+ http://www.springframework.org/schema/task/spring-task-4.2.xsd
http://www.springframework.org/schema/mvc
- http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
+ http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd
http://www.springframework.org/schema/aop
- http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
+ http://www.springframework.org/schema/aop/spring-aop-4.2.xsd
http://www.springframework.org/schema/cache
http://www.springframework.org/schema/cache/spring-cache.xsd">
@@ -48,8 +48,7 @@
<!-- Rest service binding -->
- <bean
- class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
+ <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
<bean id="mappingJacksonHttpMessageConverter"
class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/>
@@ -58,8 +57,7 @@
<bean id="formHttpMessageConverter"
class="org.springframework.http.converter.FormHttpMessageConverter"/>
- <bean
- class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
+ <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="messageConverters">
<list>
<ref bean="mappingJacksonHttpMessageConverter"/>
@@ -69,19 +67,11 @@
</property>
</bean>
- <bean
- class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
- <property name="mediaTypes">
- <map>
- <entry key="html" value="text/html"/>
- <entry key="json" value="application/json"/>
- </map>
- </property>
+ <bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="viewResolvers">
<list>
<bean class="org.springframework.web.servlet.view.BeanNameViewResolver"/>
- <bean
- class="org.springframework.web.servlet.view.InternalResourceViewResolver">
+ <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- <property name="prefix" value="/WEB-INF/jsp/"/> -->
<property name="suffix" value=".jsp"/>
</bean>
@@ -89,8 +79,7 @@
</property>
<property name="defaultViews">
<list>
- <bean
- class="org.springframework.web.servlet.view.json.MappingJackson2JsonView"/>
+ <bean class="org.springframework.web.servlet.view.json.MappingJackson2JsonView"/>
</list>
</property>
</bean>
http://git-wip-us.apache.org/repos/asf/kylin/blob/247f3cd2/server/src/main/resources/kylinSecurity.xml
----------------------------------------------------------------------
diff --git a/server/src/main/resources/kylinSecurity.xml b/server/src/main/resources/kylinSecurity.xml
index 374341c..43a0082 100644
--- a/server/src/main/resources/kylinSecurity.xml
+++ b/server/src/main/resources/kylinSecurity.xml
@@ -17,12 +17,13 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util" xsi:schemaLocation="http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
+ http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/security
- http://www.springframework.org/schema/security/spring-security-3.1.xsd
- http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd
-
- http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
+ http://www.springframework.org/schema/security/spring-security-4.0.xsd
+ http://www.springframework.org/schema/util
+ http://www.springframework.org/schema/util/spring-util-4.2.xsd
+ http://www.springframework.org/schema/context
+ http://www.springframework.org/schema/context/spring-context.xsd">
<scr:global-method-security pre-post-annotations="enabled">
<scr:expression-handler ref="expressionHandler"/>
@@ -45,13 +46,13 @@
class="org.springframework.security.acls.domain.AclAuthorizationStrategyImpl">
<constructor-arg>
<list>
- <bean class="org.springframework.security.core.authority.GrantedAuthorityImpl">
+ <bean class="org.springframework.security.core.authority.SimpleGrantedAuthority">
<constructor-arg value="ROLE_ADMIN"/>
</bean>
- <bean class="org.springframework.security.core.authority.GrantedAuthorityImpl">
+ <bean class="org.springframework.security.core.authority.SimpleGrantedAuthority">
<constructor-arg value="ROLE_ADMIN"/>
</bean>
- <bean class="org.springframework.security.core.authority.GrantedAuthorityImpl">
+ <bean class="org.springframework.security.core.authority.SimpleGrantedAuthority">
<constructor-arg value="ROLE_ADMIN"/>
</bean>
</list>
[33/50] kylin git commit: minor, push down operator ||
Posted by li...@apache.org.
minor, push down operator ||
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/0eeceeff
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/0eeceeff
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/0eeceeff
Branch: refs/heads/master
Commit: 0eeceeff43ff64bcd4baa1bc214e1288d7716f9e
Parents: 401bb0a
Author: Cheng Wang <ch...@kyligence.io>
Authored: Thu Jun 22 20:30:09 2017 +0800
Committer: Hongbin Ma <ma...@kyligence.io>
Committed: Thu Jun 22 20:56:24 2017 +0800
----------------------------------------------------------------------
.../filter/BuiltInFunctionTupleFilter.java | 21 +++++++++++++++-----
.../metadata/filter/function/BuiltInMethod.java | 11 +++++++++-
2 files changed, 26 insertions(+), 6 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/0eeceeff/core-metadata/src/main/java/org/apache/kylin/metadata/filter/BuiltInFunctionTupleFilter.java
----------------------------------------------------------------------
diff --git a/core-metadata/src/main/java/org/apache/kylin/metadata/filter/BuiltInFunctionTupleFilter.java b/core-metadata/src/main/java/org/apache/kylin/metadata/filter/BuiltInFunctionTupleFilter.java
index 767d868..aa9cd3d 100755
--- a/core-metadata/src/main/java/org/apache/kylin/metadata/filter/BuiltInFunctionTupleFilter.java
+++ b/core-metadata/src/main/java/org/apache/kylin/metadata/filter/BuiltInFunctionTupleFilter.java
@@ -24,6 +24,7 @@ import java.lang.reflect.Method;
import java.nio.ByteBuffer;
import java.util.Collection;
import java.util.List;
+import java.util.Map;
import org.apache.kylin.common.util.BytesUtil;
import org.apache.kylin.metadata.filter.function.BuiltInMethod;
@@ -33,6 +34,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
import com.google.common.primitives.Primitives;
public class BuiltInFunctionTupleFilter extends FunctionTupleFilter {
@@ -49,12 +51,18 @@ public class BuiltInFunctionTupleFilter extends FunctionTupleFilter {
protected boolean isValidFunc = false;
protected boolean isReversed = false;
+ final static Map<String, String> converters = Maps.newHashMap();
+ static {
+ converters.put("||", "CONCAT");
+ }
+
public BuiltInFunctionTupleFilter(String name) {
this(name, null);
}
public BuiltInFunctionTupleFilter(String name, FilterOperatorEnum filterOperatorEnum) {
- super(Lists.<TupleFilter> newArrayList(), filterOperatorEnum == null ? FilterOperatorEnum.FUNCTION : filterOperatorEnum);
+ super(Lists.<TupleFilter> newArrayList(),
+ filterOperatorEnum == null ? FilterOperatorEnum.FUNCTION : filterOperatorEnum);
this.methodParams = Lists.newArrayList();
if (name != null) {
@@ -91,7 +99,8 @@ public class BuiltInFunctionTupleFilter extends FunctionTupleFilter {
if (columnContainerFilter instanceof ColumnTupleFilter)
methodParams.set(colPosition, (Serializable) input);
else if (columnContainerFilter instanceof BuiltInFunctionTupleFilter)
- methodParams.set(colPosition, (Serializable) ((BuiltInFunctionTupleFilter) columnContainerFilter).invokeFunction(input));
+ methodParams.set(colPosition,
+ (Serializable) ((BuiltInFunctionTupleFilter) columnContainerFilter).invokeFunction(input));
return method.invoke(null, (Object[]) (methodParams.toArray()));
}
@@ -128,7 +137,8 @@ public class BuiltInFunctionTupleFilter extends FunctionTupleFilter {
if (!Primitives.isWrapperType(clazz))
methodParams.add(constVal);
else
- methodParams.add((Serializable) clazz.cast(clazz.getDeclaredMethod("valueOf", String.class).invoke(null, constVal)));
+ methodParams.add((Serializable) clazz
+ .cast(clazz.getDeclaredMethod("valueOf", String.class).invoke(null, constVal)));
} catch (Exception e) {
logger.warn("Reflection failed for methodParams. ", e);
isValidFunc = false;
@@ -186,8 +196,9 @@ public class BuiltInFunctionTupleFilter extends FunctionTupleFilter {
}
protected void initMethod() {
- if (BuiltInMethod.MAP.containsKey(name)) {
- this.method = BuiltInMethod.MAP.get(name).method;
+ String operator = BuiltInMethod.MAP.containsKey(name) ? name : converters.get(name);
+ if (operator != null) {
+ this.method = BuiltInMethod.MAP.get(operator).method;
isValidFunc = true;
}
}
http://git-wip-us.apache.org/repos/asf/kylin/blob/0eeceeff/core-metadata/src/main/java/org/apache/kylin/metadata/filter/function/BuiltInMethod.java
----------------------------------------------------------------------
diff --git a/core-metadata/src/main/java/org/apache/kylin/metadata/filter/function/BuiltInMethod.java b/core-metadata/src/main/java/org/apache/kylin/metadata/filter/function/BuiltInMethod.java
index 31ee297..e156174 100644
--- a/core-metadata/src/main/java/org/apache/kylin/metadata/filter/function/BuiltInMethod.java
+++ b/core-metadata/src/main/java/org/apache/kylin/metadata/filter/function/BuiltInMethod.java
@@ -29,7 +29,7 @@ import org.apache.commons.lang3.reflect.MethodUtils;
import com.google.common.collect.ImmutableMap;
public enum BuiltInMethod {
- UPPER(BuiltInMethod.class, "upper", String.class), LOWER(BuiltInMethod.class, "lower", String.class), SUBSTRING(BuiltInMethod.class, "substring", String.class, int.class, int.class), CHAR_LENGTH(BuiltInMethod.class, "charLength", String.class), LIKE(BuiltInMethod.class, "like", String.class, String.class), INITCAP(BuiltInMethod.class, "initcap", String.class);
+ UPPER(BuiltInMethod.class, "upper", String.class), LOWER(BuiltInMethod.class, "lower", String.class), SUBSTRING(BuiltInMethod.class, "substring", String.class, int.class, int.class), CHAR_LENGTH(BuiltInMethod.class, "charLength", String.class), LIKE(BuiltInMethod.class, "like", String.class, String.class), INITCAP(BuiltInMethod.class, "initcap", String.class), CONCAT(BuiltInMethod.class, "concat", String.class, String.class);
public final Method method;
public static final ImmutableMap<String, BuiltInMethod> MAP;
@@ -140,4 +140,13 @@ public enum BuiltInMethod {
return s.toLowerCase();
}
+ /** SQL left || right */
+ public static String concat(String left, String right) {
+ if (left == null)
+ return right;
+ if (right == null)
+ return left;
+ return left.concat(right);
+ }
+
}
[13/50] kylin git commit: #1186 #1150 forbid project rename and
remove if it's not empty
Posted by li...@apache.org.
#1186 #1150 forbid project rename and remove if it's not empty
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/0ab915da
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/0ab915da
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/0ab915da
Branch: refs/heads/master
Commit: 0ab915dad029440bf8b9c6091958f99d7cadd241
Parents: 70ad90c
Author: Roger Shi <ro...@hotmail.com>
Authored: Sat Jun 17 15:43:36 2017 +0800
Committer: Hongbin Ma <ma...@kyligence.io>
Committed: Sat Jun 17 15:47:29 2017 +0800
----------------------------------------------------------------------
.../rest/controller2/ProjectControllerV2.java | 35 ++++++++++++++++----
.../org/apache/kylin/rest/msg/CnMessage.java | 7 ++++
.../java/org/apache/kylin/rest/msg/Message.java | 8 +++++
3 files changed, 44 insertions(+), 6 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/0ab915da/server-base/src/main/java/org/apache/kylin/rest/controller2/ProjectControllerV2.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/controller2/ProjectControllerV2.java b/server-base/src/main/java/org/apache/kylin/rest/controller2/ProjectControllerV2.java
index 52e17b5..5a34807 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/controller2/ProjectControllerV2.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/controller2/ProjectControllerV2.java
@@ -32,6 +32,8 @@ import org.apache.kylin.rest.msg.MsgPicker;
import org.apache.kylin.rest.request.ProjectRequest;
import org.apache.kylin.rest.response.EnvelopeResponse;
import org.apache.kylin.rest.response.ResponseCode;
+import org.apache.kylin.rest.service.CubeService;
+import org.apache.kylin.rest.service.ModelService;
import org.apache.kylin.rest.service.ProjectService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -60,6 +62,14 @@ public class ProjectControllerV2 extends BasicController {
@Qualifier("projectService")
private ProjectService projectService;
+ @Autowired
+ @Qualifier("cubeMgmtService")
+ private CubeService cubeService;
+
+ @Autowired
+ @Qualifier("modelMgmtService")
+ private ModelService modelService;
+
@RequestMapping(value = "", method = { RequestMethod.GET }, produces = {
"application/vnd.apache.kylin-v2+json" })
@ResponseBody
@@ -123,21 +133,23 @@ public class ProjectControllerV2 extends BasicController {
ProjectInstance projectDesc = deserializeProjectDescV2(projectRequest);
- ProjectInstance updatedProj = null;
-
ProjectInstance currentProject = projectService.getProjectManager().getProject(formerProjectName);
if (currentProject == null) {
throw new BadRequestException(String.format(msg.getPROJECT_NOT_FOUND(), formerProjectName));
}
- updatedProj = projectService.updateProject(projectDesc, currentProject);
+ // cannot modify project name if it's not empty
+ if (!currentProject.getName().equals(projectDesc.getName()) && !isProjectEmpty(currentProject.getName())) {
+ throw new BadRequestException(msg.getRENAME_PROJECT_NOT_EMPTY());
+ }
+
+ ProjectInstance updatedProj = projectService.updateProject(projectDesc, currentProject);
return new EnvelopeResponse(ResponseCode.CODE_SUCCESS, updatedProj, "");
}
private ProjectInstance deserializeProjectDescV2(ProjectRequest projectRequest) throws IOException {
- ProjectInstance projectDesc = null;
logger.debug("Saving project " + projectRequest.getProjectDescData());
- projectDesc = JsonUtil.readValue(projectRequest.getProjectDescData(), ProjectInstance.class);
+ ProjectInstance projectDesc = JsonUtil.readValue(projectRequest.getProjectDescData(), ProjectInstance.class);
return projectDesc;
}
@@ -145,9 +157,20 @@ public class ProjectControllerV2 extends BasicController {
"application/vnd.apache.kylin-v2+json" })
@ResponseBody
public void deleteProjectV2(@PathVariable String projectName) throws IOException {
-
+ Message msg = MsgPicker.getMsg();
ProjectInstance project = projectService.getProjectManager().getProject(projectName);
+ if (!isProjectEmpty(projectName)) {
+ throw new BadRequestException(msg.getDELETE_PROJECT_NOT_EMPTY());
+ }
+
projectService.deleteProject(projectName, project);
}
+ private boolean isProjectEmpty(String projectName) throws IOException {
+ return cubeService.listAllCubes(projectName).isEmpty()
+ && cubeService.listCubeDrafts(null, null, projectName).isEmpty()
+ && modelService.listAllModels(null, projectName, false).isEmpty()
+ && modelService.listModelDrafts(null, projectName).isEmpty();
+ }
+
}
http://git-wip-us.apache.org/repos/asf/kylin/blob/0ab915da/server-base/src/main/java/org/apache/kylin/rest/msg/CnMessage.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/msg/CnMessage.java b/server-base/src/main/java/org/apache/kylin/rest/msg/CnMessage.java
index 1c6fb69..a828aa0 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/msg/CnMessage.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/msg/CnMessage.java
@@ -245,6 +245,13 @@ public class CnMessage extends Message {
return "找不到项目 '%s'";
}
+ public String getDELETE_PROJECT_NOT_EMPTY() {
+ return "不能删除该项目,如需要删除请先清空其中的Cube和Model";
+ }
+
+ public String getRENAME_PROJECT_NOT_EMPTY() {
+ return "不能重命名该项目,如果要重命名请先清空其中的Cube和Model";
+ }
// Table
public String getHIVE_TABLE_NOT_FOUND() {
return "找不到 Hive 表 '%s'";
http://git-wip-us.apache.org/repos/asf/kylin/blob/0ab915da/server-base/src/main/java/org/apache/kylin/rest/msg/Message.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/msg/Message.java b/server-base/src/main/java/org/apache/kylin/rest/msg/Message.java
index f4bcda7..9ed38bb 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/msg/Message.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/msg/Message.java
@@ -245,6 +245,14 @@ public class Message {
return "Cannot find project '%s'.";
}
+ public String getDELETE_PROJECT_NOT_EMPTY() {
+ return "Cannot delete non-empty project";
+ }
+
+ public String getRENAME_PROJECT_NOT_EMPTY() {
+ return "Cannot rename non-empty project";
+ }
+
// Table
public String getHIVE_TABLE_NOT_FOUND() {
return "Cannot find Hive table '%s'.";
[32/50] kylin git commit: minor, add test case for ||
Posted by li...@apache.org.
minor, add test case for ||
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/3f9d158a
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/3f9d158a
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/3f9d158a
Branch: refs/heads/master
Commit: 3f9d158a13186306b666898ea607768094805559
Parents: 0eeceef
Author: Cheng Wang <ch...@kyligence.io>
Authored: Thu Jun 22 20:55:19 2017 +0800
Committer: Hongbin Ma <ma...@kyligence.io>
Committed: Thu Jun 22 20:56:24 2017 +0800
----------------------------------------------------------------------
kylin-it/src/test/resources/query/sql/query96.sql | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/3f9d158a/kylin-it/src/test/resources/query/sql/query96.sql
----------------------------------------------------------------------
diff --git a/kylin-it/src/test/resources/query/sql/query96.sql b/kylin-it/src/test/resources/query/sql/query96.sql
index 4e80d59..eae99bc 100644
--- a/kylin-it/src/test/resources/query/sql/query96.sql
+++ b/kylin-it/src/test/resources/query/sql/query96.sql
@@ -18,5 +18,5 @@
select upper(lstg_format_name) as lstg_format_name, count(*) as cnt from test_kylin_fact
where lower(lstg_format_name)='abin' and substring(lstg_format_name,1,3) in ('ABI') and upper(lstg_format_name) > 'AAAA' and
-lower(lstg_format_name) like '%b%' and char_length(lstg_format_name) < 10 and char_length(lstg_format_name) > 3 and lstg_format_name||'a'='ABINa'
+lower(lstg_format_name) like '%b%' and char_length(lstg_format_name) < 10 and char_length(lstg_format_name) > 3 and 'abc'||lstg_format_name||'a'||'b'||'c'='abcABINabc'
group by lstg_format_name
\ No newline at end of file
[08/50] kylin git commit: KYLIN-2529 fix implementation switch for
threadLocal KylinConfig
Posted by li...@apache.org.
KYLIN-2529 fix implementation switch for threadLocal KylinConfig
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/d659bade
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/d659bade
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/d659bade
Branch: refs/heads/master
Commit: d659bade9283ecbf99e31285e620e880ef6a06b1
Parents: 51f22e2
Author: lidongsjtu <li...@apache.org>
Authored: Thu Jun 15 18:31:02 2017 +0800
Committer: liyang-gmt8 <li...@apache.org>
Committed: Fri Jun 16 10:11:21 2017 +0800
----------------------------------------------------------------------
.../org/apache/kylin/engine/EngineFactory.java | 21 ++---
.../org/apache/kylin/job/SchedulerFactory.java | 23 ++---
.../org/apache/kylin/source/SourceFactory.java | 22 +++--
.../apache/kylin/storage/StorageFactory.java | 16 ++--
.../kylin/storage/StorageFactoryTest.java | 93 ++++++++++++++++++++
5 files changed, 133 insertions(+), 42 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kylin/blob/d659bade/core-job/src/main/java/org/apache/kylin/engine/EngineFactory.java
----------------------------------------------------------------------
diff --git a/core-job/src/main/java/org/apache/kylin/engine/EngineFactory.java b/core-job/src/main/java/org/apache/kylin/engine/EngineFactory.java
index acaa7da..78b1efe 100644
--- a/core-job/src/main/java/org/apache/kylin/engine/EngineFactory.java
+++ b/core-job/src/main/java/org/apache/kylin/engine/EngineFactory.java
@@ -18,8 +18,6 @@
package org.apache.kylin.engine;
-import java.util.Map;
-
import org.apache.kylin.common.KylinConfig;
import org.apache.kylin.common.util.ImplementationSwitch;
import org.apache.kylin.cube.CubeSegment;
@@ -30,14 +28,17 @@ import org.apache.kylin.metadata.model.IJoinedFlatTableDesc;
public class EngineFactory {
- private static ImplementationSwitch<IBatchCubingEngine> batchEngines;
- static {
- Map<Integer, String> impls = KylinConfig.getInstanceFromEnv().getJobEngines();
- batchEngines = new ImplementationSwitch<>(impls, IBatchCubingEngine.class);
- }
+ // Use thread-local because KylinConfig can be thread-local and implementation might be different among multiple threads.
+ private static ThreadLocal<ImplementationSwitch<IBatchCubingEngine>> engines = new ThreadLocal<>();
public static IBatchCubingEngine batchEngine(IEngineAware aware) {
- return batchEngines.get(aware.getEngineType());
+ ImplementationSwitch<IBatchCubingEngine> current = engines.get();
+ if (current == null) {
+ current = new ImplementationSwitch<>(KylinConfig.getInstanceFromEnv().getJobEngines(),
+ IBatchCubingEngine.class);
+ engines.set(current);
+ }
+ return current.get(aware.getEngineType());
}
/** Mark deprecated to indicate for test purpose only */
@@ -45,11 +46,11 @@ public class EngineFactory {
public static IJoinedFlatTableDesc getJoinedFlatTableDesc(CubeDesc cubeDesc) {
return batchEngine(cubeDesc).getJoinedFlatTableDesc(cubeDesc);
}
-
+
public static IJoinedFlatTableDesc getJoinedFlatTableDesc(CubeSegment newSegment) {
return batchEngine(newSegment).getJoinedFlatTableDesc(newSegment);
}
-
+
/** Build a new cube segment, typically its time range appends to the end of current cube. */
public static DefaultChainedExecutable createBatchCubingJob(CubeSegment newSegment, String submitter) {
return batchEngine(newSegment).createBatchCubingJob(newSegment, submitter);
http://git-wip-us.apache.org/repos/asf/kylin/blob/d659bade/core-job/src/main/java/org/apache/kylin/job/SchedulerFactory.java
----------------------------------------------------------------------
diff --git a/core-job/src/main/java/org/apache/kylin/job/SchedulerFactory.java b/core-job/src/main/java/org/apache/kylin/job/SchedulerFactory.java
index 4eb76d1..1bf8942 100644
--- a/core-job/src/main/java/org/apache/kylin/job/SchedulerFactory.java
+++ b/core-job/src/main/java/org/apache/kylin/job/SchedulerFactory.java
@@ -17,27 +17,20 @@
*/
package org.apache.kylin.job;
-import java.util.Map;
-
import org.apache.kylin.common.KylinConfig;
import org.apache.kylin.common.util.ImplementationSwitch;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-/**
- */
public class SchedulerFactory {
-
- private static final Logger logger = LoggerFactory.getLogger(SchedulerFactory.class);
- private static ImplementationSwitch<Scheduler> schedulers;
-
- static {
- Map<Integer, String> impls = KylinConfig.getInstanceFromEnv().getSchedulers();
- schedulers = new ImplementationSwitch<Scheduler>(impls, Scheduler.class);
- }
+ // Use thread-local because KylinConfig can be thread-local and implementation might be different among multiple threads.
+ private static ThreadLocal<ImplementationSwitch<Scheduler>> schedulers = new ThreadLocal<>();
public static Scheduler scheduler(int schedulerType) {
- return schedulers.get(schedulerType);
+ ImplementationSwitch<Scheduler> current = schedulers.get();
+ if (current == null) {
+ current = new ImplementationSwitch<>(KylinConfig.getInstanceFromEnv().getSchedulers(), Scheduler.class);
+ schedulers.set(current);
+ }
+ return current.get(schedulerType);
}
}
http://git-wip-us.apache.org/repos/asf/kylin/blob/d659bade/core-metadata/src/main/java/org/apache/kylin/source/SourceFactory.java
----------------------------------------------------------------------
diff --git a/core-metadata/src/main/java/org/apache/kylin/source/SourceFactory.java b/core-metadata/src/main/java/org/apache/kylin/source/SourceFactory.java
index 86f89b8..365b505 100644
--- a/core-metadata/src/main/java/org/apache/kylin/source/SourceFactory.java
+++ b/core-metadata/src/main/java/org/apache/kylin/source/SourceFactory.java
@@ -19,7 +19,6 @@
package org.apache.kylin.source;
import java.util.List;
-import java.util.Map;
import org.apache.kylin.common.KylinConfig;
import org.apache.kylin.common.util.ImplementationSwitch;
@@ -28,19 +27,24 @@ import org.apache.kylin.metadata.model.TableDesc;
public class SourceFactory {
- private static ImplementationSwitch<ISource> sources;
- static {
- Map<Integer, String> impls = KylinConfig.getInstanceFromEnv().getSourceEngines();
- sources = new ImplementationSwitch<>(impls, ISource.class);
+ // Use thread-local because KylinConfig can be thread-local and implementation might be different among multiple threads.
+ private static ThreadLocal<ImplementationSwitch<ISource>> sources = new ThreadLocal<>();
+
+ private static ISource getSource(int sourceType) {
+ ImplementationSwitch<ISource> current = sources.get();
+ if (current == null) {
+ current = new ImplementationSwitch<>(KylinConfig.getInstanceFromEnv().getSourceEngines(), ISource.class);
+ sources.set(current);
+ }
+ return current.get(sourceType);
}
-
+
public static ISource getDefaultSource() {
- KylinConfig config = KylinConfig.getInstanceFromEnv();
- return sources.get(config.getDefaultSource());
+ return getSource(KylinConfig.getInstanceFromEnv().getDefaultSource());
}
public static ISource getSource(ISourceAware aware) {
- return sources.get(aware.getSourceType());
+ return getSource(aware.getSourceType());
}
public static IReadableTable createReadableTable(TableDesc table) {
http://git-wip-us.apache.org/repos/asf/kylin/blob/d659bade/core-storage/src/main/java/org/apache/kylin/storage/StorageFactory.java
----------------------------------------------------------------------
diff --git a/core-storage/src/main/java/org/apache/kylin/storage/StorageFactory.java b/core-storage/src/main/java/org/apache/kylin/storage/StorageFactory.java
index e7dd53c..79b93fe 100644
--- a/core-storage/src/main/java/org/apache/kylin/storage/StorageFactory.java
+++ b/core-storage/src/main/java/org/apache/kylin/storage/StorageFactory.java
@@ -18,8 +18,6 @@
package org.apache.kylin.storage;
-import java.util.Map;
-
import org.apache.kylin.common.KylinConfig;
import org.apache.kylin.common.util.ImplementationSwitch;
import org.apache.kylin.metadata.model.IStorageAware;
@@ -29,14 +27,16 @@ import org.apache.kylin.metadata.realization.IRealization;
*/
public class StorageFactory {
- private static ImplementationSwitch<IStorage> storages;
- static {
- Map<Integer, String> impls = KylinConfig.getInstanceFromEnv().getStorageEngines();
- storages = new ImplementationSwitch<IStorage>(impls, IStorage.class);
- }
+ // Use thread-local because KylinConfig can be thread-local and implementation might be different among multiple threads.
+ private static ThreadLocal<ImplementationSwitch<IStorage>> storages = new ThreadLocal<>();
public static IStorage storage(IStorageAware aware) {
- return storages.get(aware.getStorageType());
+ ImplementationSwitch<IStorage> current = storages.get();
+ if (storages.get() == null) {
+ current = new ImplementationSwitch<>(KylinConfig.getInstanceFromEnv().getStorageEngines(), IStorage.class);
+ storages.set(current);
+ }
+ return current.get(aware.getStorageType());
}
public static IStorageQuery createQuery(IRealization realization) {
http://git-wip-us.apache.org/repos/asf/kylin/blob/d659bade/core-storage/src/test/java/org/apache/kylin/storage/StorageFactoryTest.java
----------------------------------------------------------------------
diff --git a/core-storage/src/test/java/org/apache/kylin/storage/StorageFactoryTest.java b/core-storage/src/test/java/org/apache/kylin/storage/StorageFactoryTest.java
new file mode 100644
index 0000000..c6ba032
--- /dev/null
+++ b/core-storage/src/test/java/org/apache/kylin/storage/StorageFactoryTest.java
@@ -0,0 +1,93 @@
+/*
+ * 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;
+
+import java.util.Properties;
+
+import org.apache.kylin.common.KylinConfig;
+import org.apache.kylin.metadata.model.IStorageAware;
+import org.apache.kylin.metadata.realization.IRealization;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class StorageFactoryTest {
+ @Before
+ public void setUp() throws Exception {
+ Properties props = new Properties();
+ props.setProperty("kylin.storage.provider.0", MockupStorageEngine.class.getName());
+
+ KylinConfig.setKylinConfigInEnvIfMissing(props);
+ }
+
+ @Test
+ public void testSingleThread() {
+ IStorage s1 = StorageFactory.storage(new MockupStorageAware());
+ IStorage s2 = StorageFactory.storage(new MockupStorageAware());
+
+ Assert.assertSame(s1, s2);
+ }
+
+ @Test
+ public void testMultipleThread() throws InterruptedException {
+ final IStorage[] s = new IStorage[2];
+
+ // thread 1
+ Thread t = new Thread(new Runnable() {
+ @Override
+ public void run() {
+ s[0] = StorageFactory.storage(new MockupStorageAware());
+ }
+ });
+ t.start();
+ t.join();
+
+ // thread 2
+ t = new Thread(new Runnable() {
+ @Override
+ public void run() {
+ s[1] = StorageFactory.storage(new MockupStorageAware());
+ }
+ });
+ t.start();
+ t.join();
+
+ Assert.assertNotSame(s[0], s[1]);
+ }
+
+ class MockupStorageAware implements IStorageAware {
+ @Override
+ public int getStorageType() {
+ return 0;
+ }
+ }
+
+ public static class MockupStorageEngine implements IStorage {
+
+ @Override
+ public IStorageQuery createQuery(IRealization realization) {
+ return null;
+ }
+
+ @Override
+ public <I> I adaptToBuildEngine(Class<I> engineInterface) {
+ return null;
+ }
+ }
+}