This is an automated email from the ASF dual-hosted git repository.

xxyu pushed a commit to branch kylin5
in repository https://gitbox.apache.org/repos/asf/kylin.git

commit aeb44b823d194784be609b56bc37b8eeeeb51d9d
Author: sheng.huang <huangshen...@163.com>
AuthorDate: Tue Jul 4 12:22:08 2023 +0800

    KYLIN-5598 use zookeeper acl and auth in server discovery and global dict v2
    
    Co-authored-by: longfei.jiang <longfei.ji...@kyligence.io>
---
 .../org/apache/kylin/common/KylinConfigBase.java   |   2 +-
 .../apache/kylin/common/KylinConfigBaseTest.java   |  73 +++++++----
 .../kylin/job/lock/ZookeeperAclBuilderTest.java    |  97 --------------
 src/distributed-lock-ext/pom.xml                   |   2 +-
 .../java/org/apache/kylin/common/util/ZKUtil.java  |   5 +-
 .../kylin/common/util}/ZookeeperAclBuilder.java    |  57 +++++++--
 .../kylin/common/lock/ZookeeperAclBuilderTest.java | 141 +++++++++++++++++++++
 .../apache/kylin/rest/config/ZookeeperConfig.java  |  39 ++++++
 .../kylin/rest/config/ZookeeperConfigTest.java     |  82 ++++++++++++
 .../org/apache/kylin/tool/CuratorOperator.java     |   2 +-
 10 files changed, 361 insertions(+), 139 deletions(-)

diff --git 
a/src/core-common/src/main/java/org/apache/kylin/common/KylinConfigBase.java 
b/src/core-common/src/main/java/org/apache/kylin/common/KylinConfigBase.java
index 2306a701ee..4a852aa1e4 100644
--- a/src/core-common/src/main/java/org/apache/kylin/common/KylinConfigBase.java
+++ b/src/core-common/src/main/java/org/apache/kylin/common/KylinConfigBase.java
@@ -480,7 +480,7 @@ public abstract class KylinConfigBase implements 
Serializable {
     }
 
     public String getZKAuths() {
-        return getOptional("kylin.env.zookeeper.zk-auth", 
"digest:ADMIN:KYLIN");
+        return 
EncryptUtil.getDecryptedValue(getOptional("kylin.env.zookeeper.zk-auth", ""));
     }
 
     public String getZKAcls() {
diff --git 
a/src/core-common/src/test/java/org/apache/kylin/common/KylinConfigBaseTest.java
 
b/src/core-common/src/test/java/org/apache/kylin/common/KylinConfigBaseTest.java
index 364f918c5d..7c2c5949e6 100644
--- 
a/src/core-common/src/test/java/org/apache/kylin/common/KylinConfigBaseTest.java
+++ 
b/src/core-common/src/test/java/org/apache/kylin/common/KylinConfigBaseTest.java
@@ -36,7 +36,32 @@
 
 package org.apache.kylin.common;
 
-import lombok.val;
+import static org.apache.kylin.common.KylinConfigBase.PATH_DELIMITER;
+import static 
org.apache.kylin.common.KylinConfigBase.WRITING_CLUSTER_WORKING_DIR;
+import static 
org.apache.kylin.common.constant.Constants.KYLIN_SOURCE_JDBC_SOURCE_ENABLE_KEY;
+import static 
org.apache.kylin.common.constant.Constants.KYLIN_SOURCE_JDBC_SOURCE_NAME_KEY;
+import static org.apache.kylin.common.constant.Constants.SNAPSHOT_AUTO_REFRESH;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.time.ZoneId;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.TimeZone;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.commons.lang3.StringUtils;
 import org.apache.hadoop.fs.Path;
 import org.apache.hadoop.util.Shell;
 import org.apache.kylin.common.constant.NonCustomProjectLevelConfig;
@@ -57,30 +82,7 @@ import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.Timeout;
 import org.junitpioneer.jupiter.SetSystemProperty;
 
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.time.ZoneId;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-import java.util.TimeZone;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.TimeUnit;
-
-import static org.apache.kylin.common.KylinConfigBase.PATH_DELIMITER;
-import static 
org.apache.kylin.common.KylinConfigBase.WRITING_CLUSTER_WORKING_DIR;
-import static 
org.apache.kylin.common.constant.Constants.KYLIN_SOURCE_JDBC_SOURCE_ENABLE_KEY;
-import static 
org.apache.kylin.common.constant.Constants.KYLIN_SOURCE_JDBC_SOURCE_NAME_KEY;
-import static org.apache.kylin.common.constant.Constants.SNAPSHOT_AUTO_REFRESH;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertFalse;
-import static org.junit.jupiter.api.Assertions.assertTrue;
+import lombok.val;
 
 @MetadataInfo(onlyProps = true)
 class KylinConfigBaseTest {
@@ -632,6 +634,9 @@ class KylinConfigBaseTest {
         map.put("getJobMetadataPersistNotificationEnabled",
                 new 
PropertiesEntity("kylin.job.notification-on-metadata-persist", "false", false));
 
+        map.put("getJobErrorNotificationEnabled",
+                new PropertiesEntity("kylin.job.notification-on-job-error", 
"false", false));
+
         map.put("getStorageResourceSurvivalTimeThreshold",
                 new 
PropertiesEntity("kylin.storage.resource-survival-time-threshold", "7d", 7L * 
24 * 60 * 60 * 1000));
 
@@ -1333,6 +1338,16 @@ class KylinConfigBaseTest {
         config.setProperty(WRITING_CLUSTER_WORKING_DIR, "");
     }
 
+    @Test
+    void testGetWriteClusterWorkingDir() {
+        KylinConfig config = KylinConfig.getInstanceFromEnv();
+        assertTrue(config.getWriteClusterWorkingDir().isEmpty());
+        config.setProperty("kylin.env.write-hdfs-working-dir", 
"hdfs://writecluster/kylin");
+        assertEquals("hdfs://writecluster/kylin", 
config.getWriteClusterWorkingDir());
+        // Reset to prevent impacting other tests
+        config.setProperty("kylin.env.write-hdfs-working-dir", "");
+    }
+
     @Test
     void testGetWritingClusterWorkingDirWithSuffix() {
         KylinConfig config = KylinConfig.getInstanceFromEnv();
@@ -1465,6 +1480,14 @@ class KylinConfigBaseTest {
         assertEquals(10 * 60 * 1000, 
config.getKylinMultiTenantRouteTaskTimeOut());
     }
 
+    @Test
+    void testGetZKAuths() {
+        KylinConfig config = KylinConfig.getInstanceFromEnv();
+        assertTrue(StringUtils.isBlank(config.getZKAuths()));
+
+        config.setProperty("kylin.env.zookeeper.zk-auth", 
EncryptUtil.encryptWithPrefix("digest:ADMIN:KYLIN"));
+        assertEquals("digest:ADMIN:KYLIN", config.getZKAuths());
+    }
 }
 
 class EnvironmentUpdateUtils {
diff --git 
a/src/core-job/src/test/java/org/apache/kylin/job/lock/ZookeeperAclBuilderTest.java
 
b/src/core-job/src/test/java/org/apache/kylin/job/lock/ZookeeperAclBuilderTest.java
deleted file mode 100644
index 313c0f18c2..0000000000
--- 
a/src/core-job/src/test/java/org/apache/kylin/job/lock/ZookeeperAclBuilderTest.java
+++ /dev/null
@@ -1,97 +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.job.lock;
-
-import static junit.framework.TestCase.fail;
-
-import java.util.List;
-
-import org.apache.curator.framework.CuratorFrameworkFactory;
-import org.apache.curator.framework.CuratorFrameworkFactory.Builder;
-import org.apache.hadoop.util.ZKUtil;
-import org.apache.kylin.common.KylinConfig;
-import org.apache.kylin.common.util.NLocalFileMetadataTestCase;
-import org.apache.zookeeper.ZooDefs;
-import org.apache.zookeeper.data.ACL;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-
-import org.apache.kylin.guava30.shaded.common.collect.Lists;
-
-public class ZookeeperAclBuilderTest extends NLocalFileMetadataTestCase {
-
-    @Before
-    public void setupResource() throws Exception {
-        createTestMetadata();
-    }
-
-    @After
-    public void tearDownResource() {
-        cleanupTestMetadata();
-    }
-
-    @Test
-    public void testAclEnabled() {
-        KylinConfig testConfig = KylinConfig.getInstanceFromEnv();
-        testConfig.setProperty("kylin.env.zookeeper-acl-enabled", "true");
-
-        ZookeeperAclBuilder zookeeperAclBuilder = new 
ZookeeperAclBuilder().invoke();
-        Assert.assertNotNull(zookeeperAclBuilder);
-        Assert.assertTrue(zookeeperAclBuilder.isNeedAcl());
-
-        List<ACL> zkAcls = Lists.newArrayList();
-        try {
-            zkAcls = ZookeeperAclBuilder.getZKAcls();
-            Assert.assertFalse(zkAcls.isEmpty());
-        } catch (Exception e) {
-            fail("Couldn't read ACLs based on 'kylin.env.zookeeper.zk-acl' in 
kylin.properties");
-        }
-
-        List<ZKUtil.ZKAuthInfo> zkAuthInfo = Lists.newArrayList();
-        try {
-            zkAuthInfo = ZookeeperAclBuilder.getZKAuths();
-            Assert.assertFalse(zkAuthInfo.isEmpty());
-        } catch (Exception e) {
-            fail("Couldn't read Auth based on 'kylin.env.zookeeper.zk-auth' in 
kylin.properties");
-        }
-
-        Builder builder = 
zookeeperAclBuilder.setZKAclBuilder(CuratorFrameworkFactory.builder());
-        Assert.assertNotNull(builder);
-        Assert.assertEquals(zkAcls, builder.getAclProvider().getDefaultAcl());
-        Assert.assertNotNull(builder.getAuthInfos());
-    }
-
-    @Test
-    public void testAclDisabled() {
-        KylinConfig testConfig = KylinConfig.getInstanceFromEnv();
-        testConfig.setProperty("kylin.env.zookeeper-acl-enabled", "false");
-
-        ZookeeperAclBuilder zookeeperAclBuilder = new 
ZookeeperAclBuilder().invoke();
-        Assert.assertNotNull(zookeeperAclBuilder);
-        Assert.assertFalse(zookeeperAclBuilder.isNeedAcl());
-
-        Builder builder = 
zookeeperAclBuilder.setZKAclBuilder(CuratorFrameworkFactory.builder());
-        Assert.assertNotNull(builder);
-        Assert.assertEquals(ZooDefs.Ids.OPEN_ACL_UNSAFE, 
builder.getAclProvider().getDefaultAcl());
-        Assert.assertNull(builder.getAuthInfos());
-    }
-
-}
diff --git a/src/distributed-lock-ext/pom.xml b/src/distributed-lock-ext/pom.xml
index 26dcdfa993..c27b3086c9 100644
--- a/src/distributed-lock-ext/pom.xml
+++ b/src/distributed-lock-ext/pom.xml
@@ -73,7 +73,7 @@
         <dependency>
             <groupId>org.apache.hadoop</groupId>
             <artifactId>hadoop-common</artifactId>
-            <scope>test</scope>
+            <scope>provided</scope>
         </dependency>
         <dependency>
             <groupId>com.h2database</groupId>
diff --git 
a/src/distributed-lock-ext/src/main/java/org/apache/kylin/common/util/ZKUtil.java
 
b/src/distributed-lock-ext/src/main/java/org/apache/kylin/common/util/ZKUtil.java
index bdf7f157b3..327019dd3e 100644
--- 
a/src/distributed-lock-ext/src/main/java/org/apache/kylin/common/util/ZKUtil.java
+++ 
b/src/distributed-lock-ext/src/main/java/org/apache/kylin/common/util/ZKUtil.java
@@ -177,7 +177,10 @@ public class ZKUtil {
         }
         int sessionTimeout = ZookeeperConfig.geZKClientSessionTimeoutMs();
         int connectionTimeout = 
ZookeeperConfig.geZKClientConnectionTimeoutMs();
-        return CuratorFrameworkFactory.newClient(zkString, sessionTimeout, 
connectionTimeout, retryPolicy);
+        ZookeeperAclBuilder aclBuilder = new ZookeeperAclBuilder().invoke();
+        return 
aclBuilder.setZKAclBuilder(CuratorFrameworkFactory.builder()).connectString(zkString)
+                
.sessionTimeoutMs(sessionTimeout).connectionTimeoutMs(connectionTimeout).retryPolicy(retryPolicy)
+                .build();
     }
 
     public static boolean pathExisted(String path, KylinConfig kylinConfig) 
throws Exception {
diff --git 
a/src/core-job/src/main/java/org/apache/kylin/job/lock/ZookeeperAclBuilder.java 
b/src/distributed-lock-ext/src/main/java/org/apache/kylin/common/util/ZookeeperAclBuilder.java
similarity index 64%
rename from 
src/core-job/src/main/java/org/apache/kylin/job/lock/ZookeeperAclBuilder.java
rename to 
src/distributed-lock-ext/src/main/java/org/apache/kylin/common/util/ZookeeperAclBuilder.java
index 8f36496365..6ec1fb0d49 100644
--- 
a/src/core-job/src/main/java/org/apache/kylin/job/lock/ZookeeperAclBuilder.java
+++ 
b/src/distributed-lock-ext/src/main/java/org/apache/kylin/common/util/ZookeeperAclBuilder.java
@@ -16,7 +16,7 @@
  * limitations under the License.
  */
 
-package org.apache.kylin.job.lock;
+package org.apache.kylin.common.util;
 
 import java.util.Collections;
 import java.util.List;
@@ -27,31 +27,62 @@ import org.apache.hadoop.util.ZKUtil;
 import org.apache.kylin.common.KylinConfig;
 import org.apache.kylin.common.annotation.ThirdPartyDependencies;
 import org.apache.zookeeper.data.ACL;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+
+import lombok.extern.slf4j.Slf4j;
 
 /**
  * Created by peng.jianhua on 17-6-5.
  */
+@Slf4j
 @ThirdPartyDependencies({ 
@ThirdPartyDependencies.ThirdPartyDependent(repository = "static-user-manager", 
classes = {
         "AuthenticationClient" }) })
 public class ZookeeperAclBuilder {
-
-    private static Logger logger = 
LoggerFactory.getLogger(ZookeeperAclBuilder.class);
-
     private List<ACL> zkAcls;
     private List<ZKUtil.ZKAuthInfo> zkAuthInfo;
     private boolean isNeedAcl = 
KylinConfig.getInstanceFromEnv().isZookeeperAclEnabled();
 
-    public Builder setZKAclBuilder(Builder builder) {
-        Builder aclBuilder;
-        ACLProvider aclProvider;
+    /**
+     * Global Dict V2 Distributed Lock use this 
CuratorFrameworkFactory.Builder:
+     *   
org.apache.kylin.shaded.curator.org.apache.curator.framework.CuratorFrameworkFactory.Builder
+     */
+    public 
org.apache.kylin.shaded.curator.org.apache.curator.framework.CuratorFrameworkFactory.Builder
 setZKAclBuilder(
+            
org.apache.kylin.shaded.curator.org.apache.curator.framework.CuratorFrameworkFactory.Builder
 builder) {
+        if (!isNeedAcl()) {
+            return builder;
+        }
 
+        
org.apache.kylin.shaded.curator.org.apache.curator.framework.api.ACLProvider 
aclProvider = //
+                new 
org.apache.kylin.shaded.curator.org.apache.curator.framework.api.ACLProvider() {
+                    private List<ACL> acl;
+
+                    @Override
+                    public List<ACL> getDefaultAcl() {
+                        if (acl == null) {
+                            this.acl = zkAcls;
+                        }
+                        return acl;
+                    }
+
+                    @Override
+                    public List<ACL> getAclForPath(String path) {
+                        return acl;
+                    }
+                };
+
+        
org.apache.kylin.shaded.curator.org.apache.curator.framework.CuratorFrameworkFactory.Builder
 aclBuilder = //
+                builder.aclProvider(aclProvider);
+        for (ZKUtil.ZKAuthInfo auth : zkAuthInfo) {
+            aclBuilder = aclBuilder.authorization(auth.getScheme(), 
auth.getAuth());
+        }
+        return aclBuilder;
+    }
+
+    public Builder setZKAclBuilder(Builder builder) {
         if (!isNeedAcl()) {
             return builder;
         }
 
-        aclProvider = new ACLProvider() {
+        ACLProvider aclProvider = new ACLProvider() {
             private List<ACL> acl;
 
             @Override
@@ -68,7 +99,7 @@ public class ZookeeperAclBuilder {
             }
         };
 
-        aclBuilder = builder.aclProvider(aclProvider);
+        Builder aclBuilder = builder.aclProvider(aclProvider);
         for (ZKUtil.ZKAuthInfo auth : zkAuthInfo) {
             aclBuilder = aclBuilder.authorization(auth.getScheme(), 
auth.getAuth());
         }
@@ -99,7 +130,7 @@ public class ZookeeperAclBuilder {
                 return Collections.emptyList();
             }
         } catch (Exception e) {
-            logger.error("Couldn't read Auth based on 
'kylin.env.zookeeper.zk-auth' in kylin.properties");
+            log.error("Couldn't read Auth based on 
'kylin.env.zookeeper.zk-auth' in kylin.properties");
             throw e;
         }
     }
@@ -111,7 +142,7 @@ public class ZookeeperAclBuilder {
             zkAclConf = ZKUtil.resolveConfIndirection(zkAclConf);
             return ZKUtil.parseACLs(zkAclConf);
         } catch (Exception e) {
-            logger.error("Couldn't read ACLs based on 
'kylin.env.zookeeper.zk-acl' in kylin.properties");
+            log.error("Couldn't read ACLs based on 
'kylin.env.zookeeper.zk-acl' in kylin.properties");
             throw e;
         }
     }
diff --git 
a/src/distributed-lock-ext/src/test/java/org/apache/kylin/common/lock/ZookeeperAclBuilderTest.java
 
b/src/distributed-lock-ext/src/test/java/org/apache/kylin/common/lock/ZookeeperAclBuilderTest.java
new file mode 100644
index 0000000000..2a00378844
--- /dev/null
+++ 
b/src/distributed-lock-ext/src/test/java/org/apache/kylin/common/lock/ZookeeperAclBuilderTest.java
@@ -0,0 +1,141 @@
+/*
+ * 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.common.lock;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
+
+import java.util.List;
+
+import org.apache.curator.framework.CuratorFrameworkFactory;
+import org.apache.curator.framework.CuratorFrameworkFactory.Builder;
+import org.apache.hadoop.util.ZKUtil;
+import org.apache.kylin.common.KylinConfig;
+import org.apache.kylin.common.util.ZookeeperAclBuilder;
+import org.apache.kylin.guava30.shaded.common.collect.Lists;
+import org.apache.kylin.junit.annotation.MetadataInfo;
+import org.apache.zookeeper.ZooDefs;
+import org.apache.zookeeper.data.ACL;
+import org.junit.jupiter.api.Test;
+
+@MetadataInfo
+class ZookeeperAclBuilderTest {
+
+    @Test
+    void testAclEnabled() {
+        KylinConfig testConfig = KylinConfig.getInstanceFromEnv();
+        testConfig.setProperty("kylin.env.zookeeper-acl-enabled", "true");
+        testConfig.setProperty("kylin.env.zookeeper.zk-auth", "ADMIN:KYLIN");
+
+        ZookeeperAclBuilder zookeeperAclBuilder = new 
ZookeeperAclBuilder().invoke();
+        assertNotNull(zookeeperAclBuilder);
+        assertTrue(zookeeperAclBuilder.isNeedAcl());
+
+        List<ACL> zkAcls = Lists.newArrayList();
+        try {
+            zkAcls = ZookeeperAclBuilder.getZKAcls();
+            assertFalse(zkAcls.isEmpty());
+        } catch (Exception e) {
+            fail("Couldn't read ACLs based on 'kylin.env.zookeeper.zk-acl' in 
kylin.properties");
+        }
+
+        List<ZKUtil.ZKAuthInfo> zkAuthInfo = Lists.newArrayList();
+        try {
+            zkAuthInfo = ZookeeperAclBuilder.getZKAuths();
+            assertFalse(zkAuthInfo.isEmpty());
+        } catch (Exception e) {
+            fail("Couldn't read Auth based on 'kylin.env.zookeeper.zk-auth' in 
kylin.properties");
+        }
+
+        Builder builder = 
zookeeperAclBuilder.setZKAclBuilder(CuratorFrameworkFactory.builder());
+        assertNotNull(builder);
+        assertEquals(zkAcls, builder.getAclProvider().getDefaultAcl());
+        assertNotNull(builder.getAuthInfos());
+    }
+
+    @Test
+    void testAclDisabled() {
+        KylinConfig testConfig = KylinConfig.getInstanceFromEnv();
+        testConfig.setProperty("kylin.env.zookeeper-acl-enabled", "false");
+
+        ZookeeperAclBuilder zookeeperAclBuilder = new 
ZookeeperAclBuilder().invoke();
+        assertNotNull(zookeeperAclBuilder);
+        assertFalse(zookeeperAclBuilder.isNeedAcl());
+
+        Builder builder = 
zookeeperAclBuilder.setZKAclBuilder(CuratorFrameworkFactory.builder());
+        assertNotNull(builder);
+        assertEquals(ZooDefs.Ids.OPEN_ACL_UNSAFE, 
builder.getAclProvider().getDefaultAcl());
+        assertNull(builder.getAuthInfos());
+    }
+
+    @Test
+    void testShadedAclEnabled() {
+        KylinConfig testConfig = KylinConfig.getInstanceFromEnv();
+        testConfig.setProperty("kylin.env.zookeeper-acl-enabled", "true");
+        testConfig.setProperty("kylin.env.zookeeper.zk-auth", "ADMIN:KYLIN");
+
+        ZookeeperAclBuilder zookeeperAclBuilder = new 
ZookeeperAclBuilder().invoke();
+        assertNotNull(zookeeperAclBuilder);
+        assertTrue(zookeeperAclBuilder.isNeedAcl());
+
+        List<ACL> zkAcls = Lists.newArrayList();
+        try {
+            zkAcls = ZookeeperAclBuilder.getZKAcls();
+            assertFalse(zkAcls.isEmpty());
+        } catch (Exception e) {
+            fail("Couldn't read ACLs based on 'kylin.env.zookeeper.zk-acl' in 
kylin.properties");
+        }
+
+        List<ZKUtil.ZKAuthInfo> zkAuthInfo = Lists.newArrayList();
+        try {
+            zkAuthInfo = ZookeeperAclBuilder.getZKAuths();
+            assertFalse(zkAuthInfo.isEmpty());
+        } catch (Exception e) {
+            fail("Couldn't read Auth based on 'kylin.env.zookeeper.zk-auth' in 
kylin.properties");
+        }
+
+        
org.apache.kylin.shaded.curator.org.apache.curator.framework.CuratorFrameworkFactory.Builder
 builder = zookeeperAclBuilder
+                .setZKAclBuilder(
+                        
org.apache.kylin.shaded.curator.org.apache.curator.framework.CuratorFrameworkFactory.builder());
+        assertNotNull(builder);
+        assertEquals(zkAcls, builder.getAclProvider().getDefaultAcl());
+        assertNotNull(builder.getAuthInfos());
+    }
+
+    @Test
+    void testShadedAclDisabled() {
+        KylinConfig testConfig = KylinConfig.getInstanceFromEnv();
+        testConfig.setProperty("kylin.env.zookeeper-acl-enabled", "false");
+
+        ZookeeperAclBuilder zookeeperAclBuilder = new 
ZookeeperAclBuilder().invoke();
+        assertNotNull(zookeeperAclBuilder);
+        assertFalse(zookeeperAclBuilder.isNeedAcl());
+
+        
org.apache.kylin.shaded.curator.org.apache.curator.framework.CuratorFrameworkFactory.Builder
 builder = zookeeperAclBuilder
+                .setZKAclBuilder(
+                        
org.apache.kylin.shaded.curator.org.apache.curator.framework.CuratorFrameworkFactory.builder());
+        assertNotNull(builder);
+        assertEquals(ZooDefs.Ids.OPEN_ACL_UNSAFE, 
builder.getAclProvider().getDefaultAcl());
+        assertNull(builder.getAuthInfos());
+    }
+}
diff --git 
a/src/server/src/main/java/org/apache/kylin/rest/config/ZookeeperConfig.java 
b/src/server/src/main/java/org/apache/kylin/rest/config/ZookeeperConfig.java
new file mode 100644
index 0000000000..f93632b8f1
--- /dev/null
+++ b/src/server/src/main/java/org/apache/kylin/rest/config/ZookeeperConfig.java
@@ -0,0 +1,39 @@
+/*
+ * 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.config;
+
+import org.apache.curator.framework.CuratorFrameworkFactory;
+import org.apache.kylin.common.util.ZookeeperAclBuilder;
+import org.springframework.cloud.zookeeper.ConditionalOnZookeeperEnabled;
+import org.springframework.cloud.zookeeper.CuratorFrameworkCustomizer;
+import org.springframework.context.annotation.Configuration;
+
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+@Configuration(proxyBeanMethods = false)
+@ConditionalOnZookeeperEnabled
+public class ZookeeperConfig implements CuratorFrameworkCustomizer {
+
+    @Override
+    public void customize(CuratorFrameworkFactory.Builder builder) {
+        ZookeeperAclBuilder zookeeperAclBuilder = new 
ZookeeperAclBuilder().invoke();
+        zookeeperAclBuilder.setZKAclBuilder(builder);
+    }
+}
diff --git 
a/src/server/src/test/java/org/apache/kylin/rest/config/ZookeeperConfigTest.java
 
b/src/server/src/test/java/org/apache/kylin/rest/config/ZookeeperConfigTest.java
new file mode 100644
index 0000000000..c2601d393a
--- /dev/null
+++ 
b/src/server/src/test/java/org/apache/kylin/rest/config/ZookeeperConfigTest.java
@@ -0,0 +1,82 @@
+/*
+ * 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.config;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.nio.charset.StandardCharsets;
+import java.util.List;
+
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.curator.framework.AuthInfo;
+import org.apache.curator.framework.CuratorFramework;
+import org.apache.curator.framework.api.ACLProvider;
+import org.apache.hadoop.util.ZKUtil;
+import org.apache.kylin.common.util.ZookeeperAclBuilder;
+import org.apache.kylin.junit.annotation.MetadataInfo;
+import org.apache.kylin.junit.annotation.OverwriteProp;
+import org.apache.zookeeper.data.ACL;
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.autoconfigure.AutoConfigurations;
+import org.springframework.boot.test.context.runner.ApplicationContextRunner;
+import org.springframework.cloud.zookeeper.ZookeeperAutoConfiguration;
+import org.springframework.test.util.ReflectionTestUtils;
+
+import lombok.val;
+
+@MetadataInfo
+class ZookeeperConfigTest {
+
+    @Test
+    @OverwriteProp.OverwriteProps({ //
+            @OverwriteProp(key = "kylin.env.zookeeper-acl-enabled", value = 
"true"),
+            @OverwriteProp(key = "kylin.env.zookeeper.zk-auth", value = 
"digest:ADMIN:KYLIN"),
+            @OverwriteProp(key = "kylin.env.zookeeper.zk-acl", value = 
"world:anyone:rwcda") })
+    void customize() {
+        ApplicationContextRunner contextRunner = new ApplicationContextRunner()
+                .withPropertyValues("spring.cloud.zookeeper.enabled:true")
+                
.withConfiguration(AutoConfigurations.of(ZookeeperAutoConfiguration.class, 
ZookeeperConfig.class));
+        contextRunner.withUserConfiguration(ZookeeperAutoConfiguration.class, 
ZookeeperConfig.class).run((context) -> {
+            CuratorFramework client = context.getBean(CuratorFramework.class);
+
+            ZKUtil.ZKAuthInfo zkAuths = 
ZookeeperAclBuilder.getZKAuths().get(0);
+            List authInfos = ((List) ReflectionTestUtils.getField(client, 
"authInfos"));
+            assertTrue(CollectionUtils.isNotEmpty(authInfos));
+            val auth = authInfos.stream().findFirst();
+            assertTrue(auth.isPresent());
+            AuthInfo authInfo = (AuthInfo) auth.get();
+            assertEquals(zkAuths.getScheme(), authInfo.getScheme());
+            assertEquals("digest", authInfo.getScheme());
+            assertEquals(new String(zkAuths.getAuth(), StandardCharsets.UTF_8),
+                    new String(authInfo.getAuth(), StandardCharsets.UTF_8));
+            assertEquals("ADMIN:KYLIN", new String(authInfo.getAuth(), 
StandardCharsets.UTF_8));
+
+            ACL zkAcl = ZookeeperAclBuilder.getZKAcls().get(0);
+            ACLProvider aclProvider = ((ACLProvider) 
ReflectionTestUtils.getField(client, "aclProvider"));
+            List<ACL> acls = aclProvider.getDefaultAcl();
+            assertTrue(CollectionUtils.isNotEmpty(acls));
+            val aclOptional = acls.stream().findFirst();
+            assertTrue(aclOptional.isPresent());
+            ACL acl = aclOptional.get();
+            assertEquals(zkAcl.getId(), acl.getId());
+            assertEquals(zkAcl.getPerms(), acl.getPerms());
+        });
+    }
+}
\ No newline at end of file
diff --git a/src/tool/src/main/java/org/apache/kylin/tool/CuratorOperator.java 
b/src/tool/src/main/java/org/apache/kylin/tool/CuratorOperator.java
index ac54ef4069..4e0d88a9df 100644
--- a/src/tool/src/main/java/org/apache/kylin/tool/CuratorOperator.java
+++ b/src/tool/src/main/java/org/apache/kylin/tool/CuratorOperator.java
@@ -33,9 +33,9 @@ import org.apache.curator.x.discovery.ServiceInstance;
 import org.apache.curator.x.discovery.ServiceProvider;
 import org.apache.curator.x.discovery.strategies.RandomStrategy;
 import org.apache.kylin.common.KylinConfig;
-import org.apache.kylin.job.lock.ZookeeperAclBuilder;
 import org.apache.kylin.common.util.ClusterConstant;
 import org.apache.kylin.common.util.Unsafe;
+import org.apache.kylin.common.util.ZookeeperAclBuilder;
 import org.apache.kylin.tool.discovery.ServiceInstanceSerializer;
 import org.apache.kylin.tool.kerberos.KerberosLoginTask;
 import org.apache.zookeeper.data.Stat;

Reply via email to