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;