HADOOP-13720. Add more info to the msgs printed in AbstractDelegationTokenSecretManager. Contributed by Yongjun Zhang.
This commit is contained in:
parent
470bdaa27a
commit
fd2f22adec
@ -53,6 +53,10 @@ class AbstractDelegationTokenSecretManager<TokenIdent
|
|||||||
private static final Log LOG = LogFactory
|
private static final Log LOG = LogFactory
|
||||||
.getLog(AbstractDelegationTokenSecretManager.class);
|
.getLog(AbstractDelegationTokenSecretManager.class);
|
||||||
|
|
||||||
|
private String formatTokenId(TokenIdent id) {
|
||||||
|
return "(" + id + ")";
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cache of currently valid tokens, mapping from DelegationTokenIdentifier
|
* Cache of currently valid tokens, mapping from DelegationTokenIdentifier
|
||||||
* to DelegationTokenInformation. Protected by this object lock.
|
* to DelegationTokenInformation. Protected by this object lock.
|
||||||
@ -312,7 +316,8 @@ public synchronized void addPersistedDelegationToken(
|
|||||||
int keyId = identifier.getMasterKeyId();
|
int keyId = identifier.getMasterKeyId();
|
||||||
DelegationKey dKey = allKeys.get(keyId);
|
DelegationKey dKey = allKeys.get(keyId);
|
||||||
if (dKey == null) {
|
if (dKey == null) {
|
||||||
LOG.warn("No KEY found for persisted identifier " + identifier.toString());
|
LOG.warn("No KEY found for persisted identifier "
|
||||||
|
+ formatTokenId(identifier));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
byte[] password = createPassword(identifier.getBytes(), dKey.getKey());
|
byte[] password = createPassword(identifier.getBytes(), dKey.getKey());
|
||||||
@ -323,7 +328,8 @@ public synchronized void addPersistedDelegationToken(
|
|||||||
currentTokens.put(identifier, new DelegationTokenInformation(renewDate,
|
currentTokens.put(identifier, new DelegationTokenInformation(renewDate,
|
||||||
password, getTrackingIdIfEnabled(identifier)));
|
password, getTrackingIdIfEnabled(identifier)));
|
||||||
} else {
|
} else {
|
||||||
throw new IOException("Same delegation token being added twice.");
|
throw new IOException("Same delegation token being added twice: "
|
||||||
|
+ formatTokenId(identifier));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -393,7 +399,7 @@ protected synchronized byte[] createPassword(TokenIdent identifier) {
|
|||||||
identifier.setMaxDate(now + tokenMaxLifetime);
|
identifier.setMaxDate(now + tokenMaxLifetime);
|
||||||
identifier.setMasterKeyId(currentKey.getKeyId());
|
identifier.setMasterKeyId(currentKey.getKeyId());
|
||||||
identifier.setSequenceNumber(sequenceNum);
|
identifier.setSequenceNumber(sequenceNum);
|
||||||
LOG.info("Creating password for identifier: " + identifier
|
LOG.info("Creating password for identifier: " + formatTokenId(identifier)
|
||||||
+ ", currentKey: " + currentKey.getKeyId());
|
+ ", currentKey: " + currentKey.getKeyId());
|
||||||
byte[] password = createPassword(identifier.getBytes(), currentKey.getKey());
|
byte[] password = createPassword(identifier.getBytes(), currentKey.getKey());
|
||||||
DelegationTokenInformation tokenInfo = new DelegationTokenInformation(now
|
DelegationTokenInformation tokenInfo = new DelegationTokenInformation(now
|
||||||
@ -401,7 +407,8 @@ protected synchronized byte[] createPassword(TokenIdent identifier) {
|
|||||||
try {
|
try {
|
||||||
storeToken(identifier, tokenInfo);
|
storeToken(identifier, tokenInfo);
|
||||||
} catch (IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
LOG.error("Could not store token !!", ioe);
|
LOG.error("Could not store token " + formatTokenId(identifier) + "!!",
|
||||||
|
ioe);
|
||||||
}
|
}
|
||||||
return password;
|
return password;
|
||||||
}
|
}
|
||||||
@ -418,11 +425,14 @@ protected DelegationTokenInformation checkToken(TokenIdent identifier)
|
|||||||
assert Thread.holdsLock(this);
|
assert Thread.holdsLock(this);
|
||||||
DelegationTokenInformation info = getTokenInfo(identifier);
|
DelegationTokenInformation info = getTokenInfo(identifier);
|
||||||
if (info == null) {
|
if (info == null) {
|
||||||
throw new InvalidToken("token (" + identifier.toString()
|
throw new InvalidToken("token " + formatTokenId(identifier)
|
||||||
+ ") can't be found in cache");
|
+ " can't be found in cache");
|
||||||
}
|
}
|
||||||
if (info.getRenewDate() < Time.now()) {
|
long now = Time.now();
|
||||||
throw new InvalidToken("token (" + identifier.toString() + ") is expired");
|
if (info.getRenewDate() < now) {
|
||||||
|
throw new InvalidToken("token " + formatTokenId(identifier) + " is " +
|
||||||
|
"expired, current time: " + Time.formatTime(now) +
|
||||||
|
" expected renewal time: " + Time.formatTime(info.getRenewDate()));
|
||||||
}
|
}
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
@ -458,8 +468,8 @@ public synchronized void verifyToken(TokenIdent identifier, byte[] password)
|
|||||||
throws InvalidToken {
|
throws InvalidToken {
|
||||||
byte[] storedPassword = retrievePassword(identifier);
|
byte[] storedPassword = retrievePassword(identifier);
|
||||||
if (!Arrays.equals(password, storedPassword)) {
|
if (!Arrays.equals(password, storedPassword)) {
|
||||||
throw new InvalidToken("token (" + identifier
|
throw new InvalidToken("token " + formatTokenId(identifier)
|
||||||
+ ") is invalid, password doesn't match");
|
+ " is invalid, password doesn't match");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -477,32 +487,39 @@ public synchronized long renewToken(Token<TokenIdent> token,
|
|||||||
DataInputStream in = new DataInputStream(buf);
|
DataInputStream in = new DataInputStream(buf);
|
||||||
TokenIdent id = createIdentifier();
|
TokenIdent id = createIdentifier();
|
||||||
id.readFields(in);
|
id.readFields(in);
|
||||||
LOG.info("Token renewal for identifier: " + id + "; total currentTokens "
|
LOG.info("Token renewal for identifier: " + formatTokenId(id)
|
||||||
+ currentTokens.size());
|
+ "; total currentTokens " + currentTokens.size());
|
||||||
|
|
||||||
long now = Time.now();
|
long now = Time.now();
|
||||||
if (id.getMaxDate() < now) {
|
if (id.getMaxDate() < now) {
|
||||||
throw new InvalidToken(renewer + " tried to renew an expired token");
|
throw new InvalidToken(renewer + " tried to renew an expired token "
|
||||||
|
+ formatTokenId(id) + " max expiration date: "
|
||||||
|
+ Time.formatTime(id.getMaxDate())
|
||||||
|
+ " currentTime: " + Time.formatTime(now));
|
||||||
}
|
}
|
||||||
if ((id.getRenewer() == null) || (id.getRenewer().toString().isEmpty())) {
|
if ((id.getRenewer() == null) || (id.getRenewer().toString().isEmpty())) {
|
||||||
throw new AccessControlException(renewer +
|
throw new AccessControlException(renewer +
|
||||||
" tried to renew a token without a renewer");
|
" tried to renew a token " + formatTokenId(id)
|
||||||
|
+ " without a renewer");
|
||||||
}
|
}
|
||||||
if (!id.getRenewer().toString().equals(renewer)) {
|
if (!id.getRenewer().toString().equals(renewer)) {
|
||||||
throw new AccessControlException(renewer +
|
throw new AccessControlException(renewer
|
||||||
" tries to renew a token with renewer " + id.getRenewer());
|
+ " tries to renew a token " + formatTokenId(id)
|
||||||
|
+ " with non-matching renewer " + id.getRenewer());
|
||||||
}
|
}
|
||||||
DelegationKey key = getDelegationKey(id.getMasterKeyId());
|
DelegationKey key = getDelegationKey(id.getMasterKeyId());
|
||||||
if (key == null) {
|
if (key == null) {
|
||||||
throw new InvalidToken("Unable to find master key for keyId="
|
throw new InvalidToken("Unable to find master key for keyId="
|
||||||
+ id.getMasterKeyId()
|
+ id.getMasterKeyId()
|
||||||
+ " from cache. Failed to renew an unexpired token"
|
+ " from cache. Failed to renew an unexpired token "
|
||||||
+ " with sequenceNumber=" + id.getSequenceNumber());
|
+ formatTokenId(id) + " with sequenceNumber="
|
||||||
|
+ id.getSequenceNumber());
|
||||||
}
|
}
|
||||||
byte[] password = createPassword(token.getIdentifier(), key.getKey());
|
byte[] password = createPassword(token.getIdentifier(), key.getKey());
|
||||||
if (!Arrays.equals(password, token.getPassword())) {
|
if (!Arrays.equals(password, token.getPassword())) {
|
||||||
throw new AccessControlException(renewer +
|
throw new AccessControlException(renewer
|
||||||
" is trying to renew a token with wrong password");
|
+ " is trying to renew a token "
|
||||||
|
+ formatTokenId(id) + " with wrong password");
|
||||||
}
|
}
|
||||||
long renewTime = Math.min(id.getMaxDate(), now + tokenRenewInterval);
|
long renewTime = Math.min(id.getMaxDate(), now + tokenRenewInterval);
|
||||||
String trackingId = getTrackingIdIfEnabled(id);
|
String trackingId = getTrackingIdIfEnabled(id);
|
||||||
@ -510,7 +527,8 @@ public synchronized long renewToken(Token<TokenIdent> token,
|
|||||||
password, trackingId);
|
password, trackingId);
|
||||||
|
|
||||||
if (getTokenInfo(id) == null) {
|
if (getTokenInfo(id) == null) {
|
||||||
throw new InvalidToken("Renewal request for unknown token");
|
throw new InvalidToken("Renewal request for unknown token "
|
||||||
|
+ formatTokenId(id));
|
||||||
}
|
}
|
||||||
updateToken(id, info);
|
updateToken(id, info);
|
||||||
return renewTime;
|
return renewTime;
|
||||||
@ -528,10 +546,11 @@ public synchronized TokenIdent cancelToken(Token<TokenIdent> token,
|
|||||||
DataInputStream in = new DataInputStream(buf);
|
DataInputStream in = new DataInputStream(buf);
|
||||||
TokenIdent id = createIdentifier();
|
TokenIdent id = createIdentifier();
|
||||||
id.readFields(in);
|
id.readFields(in);
|
||||||
LOG.info("Token cancellation requested for identifier: " + id);
|
LOG.info("Token cancellation requested for identifier: "
|
||||||
|
+ formatTokenId(id));
|
||||||
|
|
||||||
if (id.getUser() == null) {
|
if (id.getUser() == null) {
|
||||||
throw new InvalidToken("Token with no owner");
|
throw new InvalidToken("Token with no owner " + formatTokenId(id));
|
||||||
}
|
}
|
||||||
String owner = id.getUser().getUserName();
|
String owner = id.getUser().getUserName();
|
||||||
Text renewer = id.getRenewer();
|
Text renewer = id.getRenewer();
|
||||||
@ -541,11 +560,11 @@ public synchronized TokenIdent cancelToken(Token<TokenIdent> token,
|
|||||||
&& (renewer == null || renewer.toString().isEmpty() || !cancelerShortName
|
&& (renewer == null || renewer.toString().isEmpty() || !cancelerShortName
|
||||||
.equals(renewer.toString()))) {
|
.equals(renewer.toString()))) {
|
||||||
throw new AccessControlException(canceller
|
throw new AccessControlException(canceller
|
||||||
+ " is not authorized to cancel the token");
|
+ " is not authorized to cancel the token " + formatTokenId(id));
|
||||||
}
|
}
|
||||||
DelegationTokenInformation info = currentTokens.remove(id);
|
DelegationTokenInformation info = currentTokens.remove(id);
|
||||||
if (info == null) {
|
if (info == null) {
|
||||||
throw new InvalidToken("Token not found");
|
throw new InvalidToken("Token not found " + formatTokenId(id));
|
||||||
}
|
}
|
||||||
removeStoredToken(id);
|
removeStoredToken(id);
|
||||||
return id;
|
return id;
|
||||||
|
@ -17,6 +17,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.hadoop.util;
|
package org.apache.hadoop.util;
|
||||||
|
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
|
||||||
import org.apache.hadoop.classification.InterfaceAudience;
|
import org.apache.hadoop.classification.InterfaceAudience;
|
||||||
import org.apache.hadoop.classification.InterfaceStability;
|
import org.apache.hadoop.classification.InterfaceStability;
|
||||||
|
|
||||||
@ -32,6 +34,14 @@ public final class Time {
|
|||||||
*/
|
*/
|
||||||
private static final long NANOSECONDS_PER_MILLISECOND = 1000000;
|
private static final long NANOSECONDS_PER_MILLISECOND = 1000000;
|
||||||
|
|
||||||
|
private static final ThreadLocal<SimpleDateFormat> DATE_FORMAT =
|
||||||
|
new ThreadLocal<SimpleDateFormat>() {
|
||||||
|
@Override
|
||||||
|
protected SimpleDateFormat initialValue() {
|
||||||
|
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss,SSSZ");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Current system time. Do not use this to calculate a duration or interval
|
* Current system time. Do not use this to calculate a duration or interval
|
||||||
* to sleep, because it will be broken by settimeofday. Instead, use
|
* to sleep, because it will be broken by settimeofday. Instead, use
|
||||||
@ -54,4 +64,12 @@ public static long now() {
|
|||||||
public static long monotonicNow() {
|
public static long monotonicNow() {
|
||||||
return System.nanoTime() / NANOSECONDS_PER_MILLISECOND;
|
return System.nanoTime() / NANOSECONDS_PER_MILLISECOND;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert time in millisecond to human readable format.
|
||||||
|
* @return a human readable string for the input time
|
||||||
|
*/
|
||||||
|
public static String formatTime(long millis) {
|
||||||
|
return DATE_FORMAT.get().format(millis);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,8 +17,6 @@
|
|||||||
package org.apache.hadoop.io.file.tfile;
|
package org.apache.hadoop.io.file.tfile;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.text.DateFormat;
|
|
||||||
import java.text.SimpleDateFormat;
|
|
||||||
|
|
||||||
import org.apache.hadoop.util.Time;
|
import org.apache.hadoop.util.Time;
|
||||||
|
|
||||||
@ -30,36 +28,34 @@
|
|||||||
public class Timer {
|
public class Timer {
|
||||||
long startTimeEpoch;
|
long startTimeEpoch;
|
||||||
long finishTimeEpoch;
|
long finishTimeEpoch;
|
||||||
private DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
|
||||||
|
|
||||||
public void startTime() throws IOException {
|
public void startTime() throws IOException {
|
||||||
startTimeEpoch = Time.now();
|
startTimeEpoch = Time.now();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void stopTime() throws IOException {
|
public void stopTime() throws IOException {
|
||||||
finishTimeEpoch = Time.now();
|
finishTimeEpoch = Time.now();
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getIntervalMillis() throws IOException {
|
public long getIntervalMillis() throws IOException {
|
||||||
return finishTimeEpoch - startTimeEpoch;
|
return finishTimeEpoch - startTimeEpoch;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void printlnWithTimestamp(String message) throws IOException {
|
public void printlnWithTimestamp(String message) throws IOException {
|
||||||
System.out.println(formatCurrentTime() + " " + message);
|
System.out.println(formatCurrentTime() + " " + message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String formatTime(long millis) {
|
public String formatTime(long millis) {
|
||||||
return formatter.format(millis);
|
return Time.formatTime(millis);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getIntervalString() throws IOException {
|
public String getIntervalString() throws IOException {
|
||||||
long time = getIntervalMillis();
|
long time = getIntervalMillis();
|
||||||
return formatTime(time);
|
return formatTime(time);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String formatCurrentTime() {
|
|
||||||
return formatTime(Time.now());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
public String formatCurrentTime() {
|
||||||
|
return formatTime(Time.now());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,50 @@
|
|||||||
|
/**
|
||||||
|
* 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.util;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A JUnit test to test {@link Time}.
|
||||||
|
*/
|
||||||
|
public class TestTime {
|
||||||
|
|
||||||
|
private static final ThreadLocal<SimpleDateFormat> DATE_FORMAT =
|
||||||
|
new ThreadLocal<SimpleDateFormat>() {
|
||||||
|
@Override
|
||||||
|
protected SimpleDateFormat initialValue() {
|
||||||
|
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss,SSSZ");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test formatTime.
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testFormatTime() {
|
||||||
|
long time = Time.now();
|
||||||
|
assertEquals(Time.formatTime(time),
|
||||||
|
DATE_FORMAT.get().format(time));
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user