From cfa41a49af3f6aef530a99cdca573b535a6c7a1c Mon Sep 17 00:00:00 2001 From: Bharat Viswanadham Date: Tue, 3 Sep 2019 14:06:14 -0700 Subject: [PATCH] HDDS-2018. Handle Set DtService of token for OM HA. (#1371) --- .../ozone/om/ha/OMFailoverProxyProvider.java | 26 +++++- .../OzoneDelegationTokenSelector.java | 18 +++- .../TestOzoneDelegationTokenSelector.java | 87 +++++++++++++++++++ 3 files changed, 127 insertions(+), 4 deletions(-) create mode 100644 hadoop-ozone/common/src/test/java/org/apache/hadoop/ozone/security/TestOzoneDelegationTokenSelector.java diff --git a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/ha/OMFailoverProxyProvider.java b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/ha/OMFailoverProxyProvider.java index 0e5c3c6a883..35975bca672 100644 --- a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/ha/OMFailoverProxyProvider.java +++ b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/ha/OMFailoverProxyProvider.java @@ -68,6 +68,7 @@ public class OMFailoverProxyProvider implements private final Configuration conf; private final long omVersion; private final UserGroupInformation ugi; + private final Text delegationTokenService; public OMFailoverProxyProvider(OzoneConfiguration configuration, UserGroupInformation ugi) throws IOException { @@ -75,6 +76,7 @@ public class OMFailoverProxyProvider implements this.omVersion = RPC.getProtocolVersion(OzoneManagerProtocolPB.class); this.ugi = ugi; loadOMClientConfigs(conf); + this.delegationTokenService = computeDelegationTokenService(); currentProxyIndex = 0; currentProxyOMNodeId = omNodeIDList.get(currentProxyIndex); @@ -178,10 +180,30 @@ public class OMFailoverProxyProvider implements } } - public synchronized Text getCurrentProxyDelegationToken() { - return omProxyInfos.get(currentProxyOMNodeId).getDelegationTokenService(); + public Text getCurrentProxyDelegationToken() { + return delegationTokenService; } + private Text computeDelegationTokenService() { + // For HA, this will return "," separated address of all OM's. + StringBuilder rpcAddress = new StringBuilder(); + int count = 0; + for (Map.Entry omProxyInfoSet : + omProxyInfos.entrySet()) { + count++; + rpcAddress = + rpcAddress.append(omProxyInfoSet.getValue().toString()); + + if (omProxyInfos.size() != count) { + rpcAddress.append(","); + } + } + + return new Text(rpcAddress.toString()); + } + + + /** * Called whenever an error warrants failing over. It is determined by the * retry policy. diff --git a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/security/OzoneDelegationTokenSelector.java b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/security/OzoneDelegationTokenSelector.java index d1103839f36..dd2ab1fa2e5 100644 --- a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/security/OzoneDelegationTokenSelector.java +++ b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/security/OzoneDelegationTokenSelector.java @@ -41,13 +41,27 @@ public class OzoneDelegationTokenSelector .getLogger(OzoneDelegationTokenSelector.class); @Override - public Token selectToken(Text service, + public Token selectToken(Text service, Collection> tokens) { LOG.trace("Getting token for service {}", service); - Token token = super.selectToken(service, tokens); + Token token = getSelectedTokens(service, tokens); LOG.debug("Got tokens: {} for service {}", token, service); return token; } + private Token getSelectedTokens(Text service, + Collection> tokens) { + if (service == null) { + return null; + } + for (Token token : tokens) { + if (OzoneTokenIdentifier.KIND_NAME.equals(token.getKind()) + && token.getService().toString().contains(service.toString())) { + return (Token) token; + } + } + return null; + } + } diff --git a/hadoop-ozone/common/src/test/java/org/apache/hadoop/ozone/security/TestOzoneDelegationTokenSelector.java b/hadoop-ozone/common/src/test/java/org/apache/hadoop/ozone/security/TestOzoneDelegationTokenSelector.java new file mode 100644 index 00000000000..85ea03ea88d --- /dev/null +++ b/hadoop-ozone/common/src/test/java/org/apache/hadoop/ozone/security/TestOzoneDelegationTokenSelector.java @@ -0,0 +1,87 @@ +/** + * 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.hadoop.ozone.security; + +import org.apache.commons.lang3.RandomStringUtils; +import org.apache.hadoop.io.Text; +import org.apache.hadoop.security.token.Token; +import org.junit.Assert; +import org.junit.Test; + +import java.nio.charset.StandardCharsets; +import java.util.Collections; + +import static org.apache.hadoop.ozone.security.OzoneTokenIdentifier.KIND_NAME; + +/** + * Class to test OzoneDelegationTokenSelector. + */ +public class TestOzoneDelegationTokenSelector { + + + @Test + public void testTokenSelector() { + + // set dummy details for identifier and password in token. + byte[] identifier = + RandomStringUtils.randomAlphabetic(10) + .getBytes(StandardCharsets.UTF_8); + byte[] password = + RandomStringUtils.randomAlphabetic(10) + .getBytes(StandardCharsets.UTF_8); + + Token tokenIdentifierToken = + new Token<>(identifier, password, KIND_NAME, getService()); + + OzoneDelegationTokenSelector ozoneDelegationTokenSelector = + new OzoneDelegationTokenSelector(); + + Text service = new Text("om1:9862"); + + Token selectedToken = + ozoneDelegationTokenSelector.selectToken(service, + Collections.singletonList(tokenIdentifierToken)); + + + Assert.assertNotNull(selectedToken); + + + tokenIdentifierToken.setService(new Text("om1:9863")); + selectedToken = + ozoneDelegationTokenSelector.selectToken(service, + Collections.singletonList(tokenIdentifierToken)); + + Assert.assertNull(selectedToken); + + service = new Text("om1:9863"); + selectedToken = + ozoneDelegationTokenSelector.selectToken(service, + Collections.singletonList(tokenIdentifierToken)); + + Assert.assertNotNull(selectedToken); + + } + + + private Text getService() { + return new Text("om1:9862,om2:9862,om3:9862"); + } + + +}