Forráskód Böngészése

HDFS-949. Move DelegationToken into Common so that it can be used by
MapReduce. (omalley)


git-svn-id: https://svn.apache.org/repos/asf/hadoop/hdfs/trunk@907964 13f79535-47bb-0310-9956-ffa450edef68

Owen O'Malley 15 éve
szülő
commit
d52875c17f

+ 3 - 0
CHANGES.txt

@@ -60,6 +60,9 @@ Trunk (unreleased changes)
     HDFS-914. Refactor DFSOutputStream and DFSInputStream out of DFSClient.
     (Todd Lipcon via tomwhite)
 
+    HDFS-949. Move DelegationToken into Common so that it can be used by
+    MapReduce. (omalley)
+
   OPTIMIZATIONS
 
   BUG FIXES

+ 1 - 1
src/java/org/apache/hadoop/hdfs/DFSClient.java

@@ -70,7 +70,6 @@ import org.apache.hadoop.hdfs.protocol.FSConstants;
 import org.apache.hadoop.hdfs.protocol.LocatedBlock;
 import org.apache.hadoop.hdfs.protocol.LocatedBlocks;
 import org.apache.hadoop.hdfs.protocol.NSQuotaExceededException;
-import org.apache.hadoop.hdfs.security.token.DelegationTokenIdentifier;
 import org.apache.hadoop.hdfs.server.common.HdfsConstants;
 import org.apache.hadoop.hdfs.server.common.UpgradeStatusReport;
 import org.apache.hadoop.hdfs.server.datanode.DataNode;
@@ -92,6 +91,7 @@ import org.apache.hadoop.security.AccessControlException;
 import org.apache.hadoop.security.UserGroupInformation;
 import org.apache.hadoop.security.token.Token;
 import org.apache.hadoop.security.token.SecretManager.InvalidToken;
+import org.apache.hadoop.hdfs.security.token.delegation.DelegationTokenIdentifier;
 import org.apache.hadoop.util.Daemon;
 import org.apache.hadoop.util.Progressable;
 import org.apache.hadoop.util.StringUtils;

+ 1 - 2
src/java/org/apache/hadoop/hdfs/DistributedFileSystem.java

@@ -31,15 +31,14 @@ import org.apache.hadoop.hdfs.protocol.Block;
 import org.apache.hadoop.hdfs.protocol.LocatedBlock;
 import org.apache.hadoop.hdfs.protocol.FSConstants.DatanodeReportType;
 import org.apache.hadoop.hdfs.protocol.FSConstants.UpgradeAction;
-import org.apache.hadoop.hdfs.security.token.DelegationTokenIdentifier;
 import org.apache.hadoop.hdfs.server.common.UpgradeStatusReport;
 import org.apache.hadoop.hdfs.server.namenode.NameNode;
 import org.apache.hadoop.hdfs.DFSClient.DFSDataInputStream;
 import org.apache.hadoop.io.Text;
-import org.apache.hadoop.ipc.RemoteException;
 import org.apache.hadoop.security.AccessControlException;
 import org.apache.hadoop.security.token.Token;
 import org.apache.hadoop.security.token.SecretManager.InvalidToken;
+import org.apache.hadoop.hdfs.security.token.delegation.DelegationTokenIdentifier;
 import org.apache.hadoop.util.Progressable;
 import org.apache.hadoop.fs.Options;
 

+ 2 - 2
src/java/org/apache/hadoop/hdfs/protocol/ClientProtocol.java

@@ -29,8 +29,6 @@ import org.apache.hadoop.fs.Options;
 import org.apache.hadoop.fs.permission.FsPermission;
 import org.apache.hadoop.hdfs.DFSConfigKeys;
 import org.apache.hadoop.hdfs.protocol.FSConstants.UpgradeAction;
-import org.apache.hadoop.hdfs.security.token.DelegationTokenIdentifier;
-import org.apache.hadoop.hdfs.security.token.DelegationTokenSelector;
 import org.apache.hadoop.hdfs.server.common.UpgradeStatusReport;
 import org.apache.hadoop.io.EnumSetWritable;
 import org.apache.hadoop.io.Text;
@@ -39,6 +37,8 @@ import org.apache.hadoop.security.AccessControlException;
 import org.apache.hadoop.security.KerberosInfo;
 import org.apache.hadoop.security.token.Token;
 import org.apache.hadoop.security.token.TokenInfo;
+import org.apache.hadoop.hdfs.security.token.delegation.DelegationTokenIdentifier;
+import org.apache.hadoop.hdfs.security.token.delegation.DelegationTokenSelector;
 
 /**********************************************************************
  * ClientProtocol is used by user code via 

+ 0 - 84
src/java/org/apache/hadoop/hdfs/security/token/DelegationKey.java

@@ -1,84 +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.hadoop.hdfs.security.token;
-
-import java.io.DataInput;
-import java.io.DataOutput;
-import java.io.IOException;
-
-import javax.crypto.SecretKey;
-
-import org.apache.hadoop.io.Writable;
-import org.apache.hadoop.io.WritableUtils;
-
-/**
- * Key used for generating and verifying delegation tokens
- */
-public class DelegationKey implements Writable {
-  private int keyId;
-  private long expiryDate;
-  private SecretKey key;
-
-  public DelegationKey() {
-    this(0, 0L, null);
-  }
-
-  public DelegationKey(int keyId, long expiryDate, SecretKey key) {
-    this.keyId = keyId;
-    this.expiryDate = expiryDate;
-    this.key = key;
-  }
-
-  public int getKeyId() {
-    return keyId;
-  }
-
-  public long getExpiryDate() {
-    return expiryDate;
-  }
-
-  public SecretKey getKey() {
-    return key;
-  }
-
-  public void setExpiryDate(long expiryDate) {
-    this.expiryDate = expiryDate;
-  }
-
-  /**
-   */
-  public void write(DataOutput out) throws IOException {
-    WritableUtils.writeVInt(out, keyId);
-    WritableUtils.writeVLong(out, expiryDate);
-    byte[] keyBytes = key.getEncoded();
-    WritableUtils.writeVInt(out, keyBytes.length);
-    out.write(keyBytes);
-  }
-
-  /**
-   */
-  public void readFields(DataInput in) throws IOException {
-    keyId = WritableUtils.readVInt(in);
-    expiryDate = WritableUtils.readVLong(in);
-    int len = WritableUtils.readVInt(in);
-    byte[] keyBytes = new byte[len];
-    in.readFully(keyBytes);
-    key = DelegationTokenSecretManager.createSecretKey(keyBytes);
-  }
-}

+ 0 - 163
src/java/org/apache/hadoop/hdfs/security/token/DelegationTokenIdentifier.java

@@ -1,163 +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.hadoop.hdfs.security.token;
-
-import java.io.DataInput;
-import java.io.DataOutput;
-import java.io.IOException;
-
-import org.apache.hadoop.io.Text;
-import org.apache.hadoop.io.WritableUtils;
-import org.apache.hadoop.security.UserGroupInformation;
-import org.apache.hadoop.security.token.TokenIdentifier;
-
-public class DelegationTokenIdentifier extends TokenIdentifier {
-  static final Text KIND_NAME = new Text("HDFS_DELEGATION_TOKEN");
-
-  private Text owner;
-  private Text renewer;
-  private Text realUser;
-  private long issueDate;
-  private long maxDate;
-  private int sequenceNumber;
-  private int masterKeyId = 0;
-  
-  public DelegationTokenIdentifier() {
-    this(new Text(), new Text(), new Text());
-  }
-  
-  public DelegationTokenIdentifier(Text owner, Text renewer, Text realUser) {
-    this.owner = owner;
-    this.renewer = renewer;
-    if (realUser == null) {
-      this.realUser = new Text();
-    } else {
-      this.realUser = realUser;
-    }
-    issueDate = 0;
-    maxDate = 0;
-  }
-
-  @Override
-  public Text getKind() {
-    return KIND_NAME;
-  }
-  
-  /**
-   * Get the username encoded in the token identifier
-   * 
-   * @return the username or owner
-   */
-  public UserGroupInformation getUser() {
-    if ( (owner == null) || ("".equals(owner.toString()))) {
-      return null;
-    }
-    if ((realUser == null) || ("".equals(realUser.toString()))
-        || realUser.equals(owner)) {
-      return UserGroupInformation.createRemoteUser(owner.toString());
-    } else {
-      UserGroupInformation realUgi = UserGroupInformation
-          .createRemoteUser(realUser.toString());
-      return UserGroupInformation.createProxyUser(owner.toString(), realUgi);
-    }
-  }
-
-  public Text getRenewer() {
-    return renewer;
-  }
-  
-  public void setIssueDate(long issueDate) {
-    this.issueDate = issueDate;
-  }
-  
-  public long getIssueDate() {
-    return issueDate;
-  }
-  
-  public void setMaxDate(long maxDate) {
-    this.maxDate = maxDate;
-  }
-  
-  public long getMaxDate() {
-    return maxDate;
-  }
-
-  public void setSequenceNumber(int seqNum) {
-    this.sequenceNumber = seqNum;
-  }
-  
-  public int getSequenceNumber() {
-    return sequenceNumber;
-  }
-
-  public void setMasterKeyId(int newId) {
-    masterKeyId = newId;
-  }
-
-  public int getMasterKeyId() {
-    return masterKeyId;
-  }
-
-  static boolean isEqual(Object a, Object b) {
-    return a == null ? b == null : a.equals(b);
-  }
-  
-  /** {@inheritDoc} */
-  public boolean equals(Object obj) {
-    if (obj == this) {
-      return true;
-    }
-    if (obj instanceof DelegationTokenIdentifier) {
-      DelegationTokenIdentifier that = (DelegationTokenIdentifier) obj;
-      return this.sequenceNumber == that.sequenceNumber 
-          && this.issueDate == that.issueDate 
-          && this.maxDate == that.maxDate
-          && this.masterKeyId == that.masterKeyId
-          && isEqual(this.owner, that.owner) 
-          && isEqual(this.renewer, that.renewer)
-          && isEqual(this.realUser, that.realUser);
-    }
-    return false;
-  }
-
-  /** {@inheritDoc} */
-  public int hashCode() {
-    return this.sequenceNumber;
-  }
-  
-  public void readFields(DataInput in) throws IOException {
-    owner.readFields(in);
-    renewer.readFields(in);
-    realUser.readFields(in);
-    issueDate = WritableUtils.readVLong(in);
-    maxDate = WritableUtils.readVLong(in);
-    sequenceNumber = WritableUtils.readVInt(in);
-    masterKeyId = WritableUtils.readVInt(in);
-  }
-
-  public void write(DataOutput out) throws IOException {
-    owner.write(out);
-    renewer.write(out);
-    realUser.write(out);
-    WritableUtils.writeVLong(out, issueDate);
-    WritableUtils.writeVLong(out, maxDate);
-    WritableUtils.writeVInt(out, sequenceNumber);
-    WritableUtils.writeVInt(out, masterKeyId);
-  }
-}

+ 0 - 358
src/java/org/apache/hadoop/hdfs/security/token/DelegationTokenSecretManager.java

@@ -1,358 +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.hadoop.hdfs.security.token;
-
-import java.io.ByteArrayInputStream;
-import java.io.DataInputStream;
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-
-import javax.crypto.SecretKey;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.hadoop.io.Text;
-import org.apache.hadoop.security.token.Token;
-import org.apache.hadoop.security.token.SecretManager;
-import org.apache.hadoop.util.Daemon;
-import org.apache.hadoop.util.StringUtils;
-
-public class DelegationTokenSecretManager 
-   extends SecretManager<DelegationTokenIdentifier> {
-  private static final Log LOG = LogFactory
-      .getLog(DelegationTokenSecretManager.class);
-
-  /** 
-   * Cache of currently valid tokens, mapping from DelegationTokenIdentifier 
-   * to DelegationTokenInformation. Protected by its own lock.
-   */
-  private final Map<DelegationTokenIdentifier, DelegationTokenInformation> currentTokens 
-      = new HashMap<DelegationTokenIdentifier, DelegationTokenInformation>();
-  
-  /**
-   * Sequence number to create DelegationTokenIdentifier
-   */
-  private int delegationTokenSequenceNumber = 0;
-  
-  private final Map<Integer, DelegationKey> allKeys 
-      = new HashMap<Integer, DelegationKey>();
-  
-  /**
-   * Access to currentId and currentKey is protected by this object lock.
-   */
-  private int currentId = 0;
-  private DelegationKey currentKey;
-  
-  private long keyUpdateInterval;
-  private long tokenMaxLifetime;
-  private long tokenRemoverScanInterval;
-  private long tokenRenewInterval;
-  private Thread tokenRemoverThread;
-  private volatile boolean running;
-  
-
-  public DelegationTokenSecretManager(long delegationKeyUpdateInterval,
-      long delegationTokenMaxLifetime, long delegationTokenRenewInterval,
-      long delegationTokenRemoverScanInterval) {
-    this.keyUpdateInterval = delegationKeyUpdateInterval;
-    this.tokenMaxLifetime = delegationTokenMaxLifetime;
-    this.tokenRenewInterval = delegationTokenRenewInterval;
-    this.tokenRemoverScanInterval = delegationTokenRemoverScanInterval;
-  }
-  
-  /** should be called before this object is used */
-  public synchronized void startThreads() throws IOException {
-    updateCurrentKey();
-    running = true;
-    tokenRemoverThread = new Daemon(new ExpiredTokenRemover());
-    tokenRemoverThread.start();
-  }
-  
-  /** 
-   * Add a previously used master key to cache (when NN restarts), 
-   * should be called before activate().
-   * */
-  public synchronized void addKey(DelegationKey key) throws IOException {
-    if (running) // a safety check
-      throw new IOException("Can't add delegation key to a running SecretManager.");
-    if (key.getKeyId() > currentId) {
-      currentId = key.getKeyId();
-    }
-    allKeys.put(key.getKeyId(), key);
-  }
-
-  public synchronized DelegationKey[] getAllKeys() {
-    return allKeys.values().toArray(new DelegationKey[0]);
-  }
-  
-  /** Update the current master key */
-  private synchronized void updateCurrentKey() throws IOException {
-    LOG.info("Updating the current master key for generating delegation tokens");
-    /* Create a new currentKey with an estimated expiry date. */
-    currentId++;
-    currentKey = new DelegationKey(currentId, System.currentTimeMillis()
-        + keyUpdateInterval + tokenMaxLifetime, generateSecret());
-    allKeys.put(currentKey.getKeyId(), currentKey);
-  }
-  
-  /** Update the current master key for generating delegation tokens */
-  public synchronized void rollMasterKey() throws IOException {
-    removeExpiredKeys();
-    /* set final expiry date for retiring currentKey */
-    currentKey.setExpiryDate(System.currentTimeMillis() + tokenMaxLifetime);
-    /*
-     * currentKey might have been removed by removeExpiredKeys(), if
-     * updateMasterKey() isn't called at expected interval. Add it back to
-     * allKeys just in case.
-     */
-    allKeys.put(currentKey.getKeyId(), currentKey);
-    updateCurrentKey();
-  }
-
-  private synchronized void removeExpiredKeys() {
-    long now = System.currentTimeMillis();
-    for (Iterator<Map.Entry<Integer, DelegationKey>> it = allKeys.entrySet()
-        .iterator(); it.hasNext();) {
-      Map.Entry<Integer, DelegationKey> e = it.next();
-      if (e.getValue().getExpiryDate() < now) {
-        it.remove();
-      }
-    }
-  }
-  
-  @Override
-  protected byte[] createPassword(DelegationTokenIdentifier identifier) {
-    int sequenceNum;
-    int id;
-    DelegationKey key;
-    long now = System.currentTimeMillis();    
-    synchronized (this) {
-      id = currentId;
-      key = currentKey;
-      sequenceNum = ++delegationTokenSequenceNumber;
-    }
-    identifier.setIssueDate(now);
-    identifier.setMaxDate(now + tokenMaxLifetime);
-    identifier.setMasterKeyId(id);
-    identifier.setSequenceNumber(sequenceNum);
-    byte[] password = createPassword(identifier.getBytes(), key.getKey());
-    synchronized (currentTokens) {
-      currentTokens.put(identifier, new DelegationTokenInformation(now
-          + tokenRenewInterval, password));
-    }
-    return password;
-  }
-
-  @Override
-  public byte[] retrievePassword(DelegationTokenIdentifier identifier
-                                 ) throws InvalidToken {
-    DelegationTokenInformation info = null;
-    synchronized (currentTokens) {
-      info = currentTokens.get(identifier);
-    }
-    if (info == null) {
-      throw new InvalidToken("token is expired or doesn't exist");
-    }
-    long now = System.currentTimeMillis();
-    if (info.getRenewDate() < now) {
-      throw new InvalidToken("token is expired");
-    }
-    return info.getPassword();
-  }
-
-  /**
-   * Renew a delegation token. Canceled tokens are not renewed. Return true if
-   * the token is successfully renewed; false otherwise.
-   */
-  public Boolean renewToken(Token<DelegationTokenIdentifier> token,
-      String renewer) throws InvalidToken, IOException {
-    long now = System.currentTimeMillis();
-    ByteArrayInputStream buf = new ByteArrayInputStream(token.getIdentifier());
-    DataInputStream in = new DataInputStream(buf);
-    DelegationTokenIdentifier id = new DelegationTokenIdentifier();
-    id.readFields(in);
-    synchronized (currentTokens) {
-      if (currentTokens.get(id) == null) {
-        LOG.warn("Renewal request for unknown token");
-        return false;
-      }
-    }
-    if (id.getMaxDate() < now) {
-      LOG.warn("Client " + renewer + " tries to renew an expired token");
-      return false;
-    }
-    if (id.getRenewer() == null || !id.getRenewer().toString().equals(renewer)) {
-      LOG.warn("Client " + renewer + " tries to renew a token with "
-          + "renewer specified as " + id.getRenewer());
-      return false;
-    }
-    DelegationKey key = null;
-    synchronized (this) {
-      key = allKeys.get(id.getMasterKeyId());
-    }
-    if (key == null) {
-      LOG.warn("Unable to find master key for keyId=" + id.getMasterKeyId() 
-          + " from cache. Failed to renew an unexpired token with sequenceNumber=" 
-          + id.getSequenceNumber() + ", issued by this key");
-      return false;
-    }
-    byte[] password = createPassword(token.getIdentifier(), key.getKey());
-    if (!Arrays.equals(password, token.getPassword())) {
-      LOG.warn("Client " + renewer + " is trying to renew a token with wrong password");
-      return false;
-    }
-    DelegationTokenInformation info = new DelegationTokenInformation(
-        Math.min(id.getMaxDate(), now + tokenRenewInterval), password);
-    synchronized (currentTokens) {
-      currentTokens.put(id, info);
-    }
-    return true;
-  }
-  
-  /**
-   * Cancel a token by removing it from cache. Return true if 
-   * token exists in cache; false otherwise.
-   */
-  public Boolean cancelToken(Token<DelegationTokenIdentifier> token,
-      String canceller) throws IOException {
-    ByteArrayInputStream buf = new ByteArrayInputStream(token.getIdentifier());
-    DataInputStream in = new DataInputStream(buf);
-    DelegationTokenIdentifier id = new DelegationTokenIdentifier();
-    id.readFields(in);
-    if (id.getRenewer() == null) {
-      LOG.warn("Renewer is null: Invalid Identifier");
-      return false;
-    }
-    if (id.getUser() == null) {
-      LOG.warn("owner is null: Invalid Identifier");
-      return false;
-    }
-    String owner = id.getUser().getUserName();
-    String renewer = id.getRenewer().toString();
-    if (!canceller.equals(owner) && !canceller.equals(renewer)) {
-      LOG.warn(canceller + " is not authorized to cancel the token");
-      return false;
-    }
-    DelegationTokenInformation info = null;
-    synchronized (currentTokens) {
-      info = currentTokens.remove(id);
-    }
-    return info != null;
-  }
-  
-  /**
-   * Convert the byte[] to a secret key
-   * @param key the byte[] to create the secret key from
-   * @return the secret key
-   */
-  public static SecretKey createSecretKey(byte[] key) {
-    return SecretManager.createSecretKey(key);
-  }
-
-  /**
-   * Create an empty delegation token identifier
-   * @return a newly created empty delegation token identifier
-   */
-  @Override
-  public DelegationTokenIdentifier createIdentifier() {
-    return new DelegationTokenIdentifier();
-  }
-
-  /** Utility class to encapsulate a token's renew date and password. */
-  private static class DelegationTokenInformation {
-    long renewDate;
-    byte[] password;
-    DelegationTokenInformation(long renewDate, byte[] password) {
-      this.renewDate = renewDate;
-      this.password = password;
-    }
-    /** returns renew date */
-    long getRenewDate() {
-      return renewDate;
-    }
-    /** returns password */
-    byte[] getPassword() {
-      return password;
-    }
-  }
-  
-  /** Remove expired delegation tokens from cache */
-  private void removeExpiredToken() {
-    long now = System.currentTimeMillis();
-    synchronized (currentTokens) {
-      Iterator<DelegationTokenInformation> i = currentTokens.values().iterator();
-      while (i.hasNext()) {
-        long renewDate = i.next().getRenewDate();
-        if (now > renewDate) {
-          i.remove();
-        }
-      }
-    }
-  }
-
-  public synchronized void stopThreads() {
-    if (LOG.isDebugEnabled())
-      LOG.debug("Stopping expired delegation token remover thread");
-    running = false;
-    tokenRemoverThread.interrupt();
-  }
-  
-  private class ExpiredTokenRemover extends Thread {
-    private long lastMasterKeyUpdate;
-    private long lastTokenCacheCleanup;
-
-    public void run() {
-      LOG.info("Starting expired delegation token remover thread, "
-          + "tokenRemoverScanInterval=" + tokenRemoverScanInterval
-          / (60 * 1000) + " min(s)");
-      try {
-        while (running) {
-          long now = System.currentTimeMillis();
-          if (lastMasterKeyUpdate + keyUpdateInterval < now) {
-            try {
-              rollMasterKey();
-              lastMasterKeyUpdate = now;
-            } catch (IOException e) {
-              LOG.error("Master key updating failed. "
-                  + StringUtils.stringifyException(e));
-            }
-          }
-          if (lastTokenCacheCleanup + tokenRemoverScanInterval < now) {
-            removeExpiredToken();
-            lastTokenCacheCleanup = now;
-          }
-          try {
-            Thread.sleep(5000); // 5 seconds
-          } catch (InterruptedException ie) {
-            LOG
-            .error("InterruptedExcpetion recieved for ExpiredTokenRemover thread "
-                + ie);
-          }
-        }
-      } catch (Throwable t) {
-        LOG.error("ExpiredTokenRemover thread received unexpected exception. "
-            + t);
-        Runtime.getRuntime().exit(-1);
-      }
-    }
-  }
-}

+ 25 - 23
src/java/org/apache/hadoop/hdfs/security/token/DelegationTokenSelector.java → src/java/org/apache/hadoop/hdfs/security/token/delegation/DelegationTokenIdentifier.java

@@ -16,37 +16,39 @@
  * limitations under the License.
  */
 
-package org.apache.hadoop.hdfs.security.token;
-
-import java.util.Collection;
+package org.apache.hadoop.hdfs.security.token.delegation;
 
 import org.apache.hadoop.classification.InterfaceAudience;
 import org.apache.hadoop.io.Text;
-import org.apache.hadoop.security.token.Token;
-import org.apache.hadoop.security.token.TokenIdentifier;
-import org.apache.hadoop.security.token.TokenSelector;
+import org.apache.hadoop.security.token.delegation.AbstractDelegationTokenIdentifier;
 
 /**
- * Look through tokens to find the first delegation token that matches the
- * service and return it.
+ * A delegation token identifier that is specific to HDFS.
  */
 @InterfaceAudience.Private
-public class DelegationTokenSelector implements
-    TokenSelector<DelegationTokenIdentifier> {
+public class DelegationTokenIdentifier 
+    extends AbstractDelegationTokenIdentifier {
+  static final Text HDFS_DELEGATION_KIND = new Text("HDFS_DELEGATION_TOKEN");
+
+  /**
+   * Create an empty delegation token identifier for reading into.
+   */
+  public DelegationTokenIdentifier() {
+  }
+
+  /**
+   * Create a new delegation token identifier
+   * @param owner the effective username of the token owner
+   * @param renewer the username of the renewer
+   * @param realUser the real username of the token owner
+   */
+  public DelegationTokenIdentifier(Text owner, Text renewer, Text realUser) {
+    super(owner, renewer, realUser);
+  }
 
-  @SuppressWarnings("unchecked")
   @Override
-  public Token<DelegationTokenIdentifier> selectToken(Text service,
-      Collection<Token<? extends TokenIdentifier>> tokens) {
-    if (service == null) {
-      return null;
-    }
-    for (Token<? extends TokenIdentifier> token : tokens) {
-      if (DelegationTokenIdentifier.KIND_NAME.equals(token.getKind())
-          && service.equals(token.getService())) {
-        return (Token<DelegationTokenIdentifier>) token;
-      }
-    }
-    return null;
+  public Text getKind() {
+    return HDFS_DELEGATION_KIND;
   }
+
 }

+ 56 - 0
src/java/org/apache/hadoop/hdfs/security/token/delegation/DelegationTokenSecretManager.java

@@ -0,0 +1,56 @@
+/**
+ * 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.hdfs.security.token.delegation;
+
+import org.apache.hadoop.classification.InterfaceAudience;
+import org.apache.hadoop.security.token.delegation.AbstractDelegationTokenSecretManager;
+
+/**
+ * A HDFS specific delegation token secret manager.
+ * The secret manager is responsible for generating and accepting the password
+ * for each token.
+ */
+@InterfaceAudience.Private
+public class DelegationTokenSecretManager
+    extends AbstractDelegationTokenSecretManager<DelegationTokenIdentifier> {
+
+  /**
+   * Create a secret manager
+   * @param delegationKeyUpdateInterval the number of seconds for rolling new
+   *        secret keys.
+   * @param delegationTokenMaxLifetime the maximum lifetime of the delegation
+   *        tokens
+   * @param delegationTokenRenewInterval how often the tokens must be renewed
+   * @param delegationTokenRemoverScanInterval how often the tokens are scanned
+   *        for expired tokens
+   */
+  public DelegationTokenSecretManager(long delegationKeyUpdateInterval,
+                                      long delegationTokenMaxLifetime, 
+                                      long delegationTokenRenewInterval,
+                                      long delegationTokenRemoverScanInterval) {
+    super(delegationKeyUpdateInterval, delegationTokenMaxLifetime,
+          delegationTokenRenewInterval, delegationTokenRemoverScanInterval);
+  }
+
+  @Override
+  public DelegationTokenIdentifier createIdentifier() {
+    return new DelegationTokenIdentifier();
+  }
+
+}

+ 33 - 0
src/java/org/apache/hadoop/hdfs/security/token/delegation/DelegationTokenSelector.java

@@ -0,0 +1,33 @@
+/**
+ * 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.hdfs.security.token.delegation;
+
+import org.apache.hadoop.classification.InterfaceAudience;
+import org.apache.hadoop.security.token.delegation.AbstractDelegationTokenSelector;
+
+/**
+ * A delegation token that is specialized for HDFS
+ */
+@InterfaceAudience.Private
+public class DelegationTokenSelector
+    extends AbstractDelegationTokenSelector<DelegationTokenIdentifier>{
+
+  public DelegationTokenSelector() {
+    super(DelegationTokenIdentifier.HDFS_DELEGATION_KIND);
+  }
+}

+ 2 - 2
src/java/org/apache/hadoop/hdfs/server/namenode/FSNamesystem.java

@@ -36,8 +36,8 @@ import org.apache.hadoop.security.AccessControlException;
 import org.apache.hadoop.security.UserGroupInformation;
 import org.apache.hadoop.security.token.Token;
 import org.apache.hadoop.security.token.SecretManager.InvalidToken;
-import org.apache.hadoop.hdfs.security.token.DelegationTokenIdentifier;
-import org.apache.hadoop.hdfs.security.token.DelegationTokenSecretManager;
+import org.apache.hadoop.hdfs.security.token.delegation.DelegationTokenIdentifier;
+import org.apache.hadoop.hdfs.security.token.delegation.DelegationTokenSecretManager;
 import org.apache.hadoop.util.*;
 import org.apache.hadoop.metrics.util.MBeanUtil;
 import org.apache.hadoop.net.CachedDNSToSwitchMapping;

+ 1 - 2
src/java/org/apache/hadoop/hdfs/server/namenode/NameNode.java

@@ -86,8 +86,7 @@ import org.apache.hadoop.security.authorize.RefreshAuthorizationPolicyProtocol;
 import org.apache.hadoop.security.authorize.ServiceAuthorizationManager;
 import org.apache.hadoop.security.token.Token;
 import org.apache.hadoop.security.token.SecretManager.InvalidToken;
-import org.apache.hadoop.hdfs.security.token.DelegationTokenIdentifier;
-import org.apache.hadoop.util.ReflectionUtils;
+import org.apache.hadoop.hdfs.security.token.delegation.DelegationTokenIdentifier;
 import org.apache.hadoop.util.ServicePlugin;
 import org.apache.hadoop.util.StringUtils;
 

+ 1 - 1
src/test/hdfs/org/apache/hadoop/hdfs/TestDFSClientRetries.java

@@ -34,7 +34,6 @@ import org.apache.hadoop.fs.permission.FsPermission;
 import org.apache.hadoop.hdfs.DFSInputStream;
 import org.apache.hadoop.hdfs.protocol.*;
 import org.apache.hadoop.hdfs.protocol.FSConstants.UpgradeAction;
-import org.apache.hadoop.hdfs.security.token.DelegationTokenIdentifier;
 import org.apache.hadoop.hdfs.server.common.*;
 import org.apache.hadoop.hdfs.server.namenode.NotReplicatedYetException;
 import org.apache.hadoop.hdfs.server.namenode.NameNode;
@@ -44,6 +43,7 @@ import org.apache.hadoop.security.AccessControlException;
 import org.apache.hadoop.security.UserGroupInformation;
 import org.apache.hadoop.security.token.Token;
 import org.apache.hadoop.security.token.SecretManager.InvalidToken;
+import org.apache.hadoop.hdfs.security.token.delegation.DelegationTokenIdentifier;
 
 import junit.framework.TestCase;
 

+ 2 - 2
src/test/hdfs/org/apache/hadoop/hdfs/security/TestClientProtocolWithDelegationToken.java

@@ -38,10 +38,10 @@ import org.apache.hadoop.ipc.RPC;
 import org.apache.hadoop.ipc.Server;
 import org.apache.hadoop.hdfs.DFSConfigKeys;
 import org.apache.hadoop.hdfs.protocol.ClientProtocol;
-import org.apache.hadoop.hdfs.security.token.DelegationTokenIdentifier;
-import org.apache.hadoop.hdfs.security.token.DelegationTokenSecretManager;
 import org.apache.hadoop.net.NetUtils;
 import org.apache.hadoop.security.token.Token;
+import org.apache.hadoop.hdfs.security.token.delegation.DelegationTokenIdentifier;
+import org.apache.hadoop.hdfs.security.token.delegation.DelegationTokenSecretManager;
 import org.apache.hadoop.security.SaslInputStream;
 import org.apache.hadoop.security.SaslRpcClient;
 import org.apache.hadoop.security.SaslRpcServer;

+ 4 - 3
src/test/hdfs/org/apache/hadoop/security/TestDelegationToken.java → src/test/hdfs/org/apache/hadoop/hdfs/security/TestDelegationToken.java

@@ -16,7 +16,7 @@
  * limitations under the License.
  */
 
-package org.apache.hadoop.security;
+package org.apache.hadoop.hdfs.security;
 
 
 
@@ -34,10 +34,11 @@ import org.apache.hadoop.hdfs.DistributedFileSystem;
 import org.apache.hadoop.hdfs.HdfsConfiguration;
 import org.apache.hadoop.hdfs.MiniDFSCluster;
 import org.apache.hadoop.io.Text;
+import org.apache.hadoop.security.UserGroupInformation;
 import org.apache.hadoop.security.token.Token;
 import org.apache.hadoop.security.token.SecretManager.InvalidToken;
-import org.apache.hadoop.hdfs.security.token.DelegationTokenIdentifier;
-import org.apache.hadoop.hdfs.security.token.DelegationTokenSecretManager;
+import org.apache.hadoop.hdfs.security.token.delegation.DelegationTokenIdentifier;
+import org.apache.hadoop.hdfs.security.token.delegation.DelegationTokenSecretManager;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;