Skip to content

Commit d33ee67

Browse files
Hadoop-18520. Backport HADOOP-18427 and HADOOP-18452 to branch-3.3 (#5118)
* HADOOP-18427. Improve ZKDelegationTokenSecretManager#startThead With recommended methods. (#4812) * HADOOP-18452. Fix TestKMS#testKMSHAZooKeeperDelegationToken Failed By Hadoop-18427. (#4885) Co-authored-by: slfan1989 <[email protected]>
1 parent 02aedd7 commit d33ee67

File tree

2 files changed

+77
-4
lines changed

2 files changed

+77
-4
lines changed

hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/token/delegation/ZKDelegationTokenSecretManager.java

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@
4242
import org.apache.curator.framework.recipes.shared.SharedCount;
4343
import org.apache.curator.framework.recipes.shared.VersionedValue;
4444
import org.apache.curator.retry.RetryNTimes;
45-
import org.apache.curator.utils.EnsurePath;
4645
import org.apache.hadoop.classification.InterfaceAudience;
4746
import org.apache.hadoop.classification.InterfaceAudience.Private;
4847
import org.apache.hadoop.classification.InterfaceStability.Unstable;
@@ -60,6 +59,7 @@
6059
import org.apache.zookeeper.client.ZKClientConfig;
6160
import org.apache.zookeeper.data.ACL;
6261
import org.apache.zookeeper.data.Id;
62+
import org.apache.zookeeper.data.Stat;
6363
import org.slf4j.Logger;
6464
import org.slf4j.LoggerFactory;
6565

@@ -134,6 +134,11 @@ public static void setCurator(CuratorFramework curator) {
134134
CURATOR_TL.set(curator);
135135
}
136136

137+
@VisibleForTesting
138+
protected static CuratorFramework getCurator() {
139+
return CURATOR_TL.get();
140+
}
141+
137142
private final boolean isExternalClient;
138143
protected final CuratorFramework zkClient;
139144
private SharedCount delTokSeqCounter;
@@ -260,10 +265,12 @@ public void startThreads() throws IOException {
260265
// If namespace parents are implicitly created, they won't have ACLs.
261266
// So, let's explicitly create them.
262267
CuratorFramework nullNsFw = zkClient.usingNamespace(null);
263-
EnsurePath ensureNs =
264-
nullNsFw.newNamespaceAwareEnsurePath("/" + zkClient.getNamespace());
265268
try {
266-
ensureNs.ensure(nullNsFw.getZookeeperClient());
269+
String nameSpace = "/" + zkClient.getNamespace();
270+
Stat stat = nullNsFw.checkExists().forPath(nameSpace);
271+
if (stat == null) {
272+
nullNsFw.create().creatingParentContainersIfNeeded().forPath(nameSpace);
273+
}
267274
} catch (Exception e) {
268275
throw new IOException("Could not create namespace", e);
269276
}

hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/token/delegation/TestZKDelegationTokenSecretManager.java

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
import org.apache.curator.framework.CuratorFramework;
2828
import org.apache.curator.framework.CuratorFrameworkFactory;
2929
import org.apache.curator.framework.api.ACLProvider;
30+
import org.apache.curator.framework.api.CreateBuilder;
31+
import org.apache.curator.framework.api.ProtectACLCreateModeStatPathAndBytesable;
3032
import org.apache.curator.retry.ExponentialBackoffRetry;
3133
import org.apache.curator.test.TestingServer;
3234
import org.apache.hadoop.conf.Configuration;
@@ -37,9 +39,12 @@
3739
import org.apache.hadoop.security.token.delegation.web.DelegationTokenIdentifier;
3840
import org.apache.hadoop.security.token.delegation.web.DelegationTokenManager;
3941
import org.apache.hadoop.test.GenericTestUtils;
42+
import org.apache.hadoop.test.LambdaTestUtils;
43+
import org.apache.zookeeper.KeeperException;
4044
import org.apache.zookeeper.ZooDefs;
4145
import org.apache.zookeeper.data.ACL;
4246
import org.apache.zookeeper.data.Id;
47+
import org.apache.zookeeper.data.Stat;
4348
import org.apache.zookeeper.server.auth.DigestAuthenticationProvider;
4449
import org.junit.After;
4550
import org.junit.Assert;
@@ -506,4 +511,65 @@ public Boolean get() {
506511
}
507512
}, 1000, 5000);
508513
}
514+
515+
@Test
516+
public void testCreatingParentContainersIfNeeded() throws Exception {
517+
518+
String connectString = zkServer.getConnectString();
519+
RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
520+
Configuration conf = getSecretConf(connectString);
521+
CuratorFramework curatorFramework =
522+
CuratorFrameworkFactory.builder()
523+
.connectString(connectString)
524+
.retryPolicy(retryPolicy)
525+
.build();
526+
curatorFramework.start();
527+
ZKDelegationTokenSecretManager.setCurator(curatorFramework);
528+
DelegationTokenManager tm1 = new DelegationTokenManager(conf, new Text("foo"));
529+
530+
// When the init method is called,
531+
// the ZKDelegationTokenSecretManager#startThread method will be called,
532+
// and the creatingParentContainersIfNeeded will be called to create the nameSpace.
533+
tm1.init();
534+
535+
String workingPath = "/" + conf.get(ZKDelegationTokenSecretManager.ZK_DTSM_ZNODE_WORKING_PATH,
536+
ZKDelegationTokenSecretManager.ZK_DTSM_ZNODE_WORKING_PATH_DEAFULT) + "/ZKDTSMRoot";
537+
538+
// Check if the created NameSpace exists.
539+
Stat stat = curatorFramework.checkExists().forPath(workingPath);
540+
Assert.assertNotNull(stat);
541+
542+
tm1.destroy();
543+
curatorFramework.close();
544+
}
545+
546+
@Test
547+
public void testCreateNameSpaceRepeatedly() throws Exception {
548+
549+
String connectString = zkServer.getConnectString();
550+
RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
551+
Configuration conf = getSecretConf(connectString);
552+
CuratorFramework curatorFramework =
553+
CuratorFrameworkFactory.builder().
554+
connectString(connectString).
555+
retryPolicy(retryPolicy).
556+
build();
557+
curatorFramework.start();
558+
559+
String workingPath = "/" + conf.get(ZKDelegationTokenSecretManager.ZK_DTSM_ZNODE_WORKING_PATH,
560+
ZKDelegationTokenSecretManager.ZK_DTSM_ZNODE_WORKING_PATH_DEAFULT) + "/ZKDTSMRoot-Test";
561+
CreateBuilder createBuilder = curatorFramework.create();
562+
ProtectACLCreateModeStatPathAndBytesable<String> createModeStat =
563+
createBuilder.creatingParentContainersIfNeeded();
564+
createModeStat.forPath(workingPath);
565+
566+
// Check if the created NameSpace exists.
567+
Stat stat = curatorFramework.checkExists().forPath(workingPath);
568+
Assert.assertNotNull(stat);
569+
570+
// Repeated creation will throw NodeExists exception
571+
LambdaTestUtils.intercept(KeeperException.class,
572+
"KeeperErrorCode = NodeExists for "+workingPath,
573+
() -> createModeStat.forPath(workingPath));
574+
}
509575
}

0 commit comments

Comments
 (0)