001    /**
002     * Licensed to the Apache Software Foundation (ASF) under one
003     * or more contributor license agreements.  See the NOTICE file
004     * distributed with this work for additional information
005     * regarding copyright ownership.  The ASF licenses this file
006     * to you under the Apache License, Version 2.0 (the
007     * "License"); you may not use this file except in compliance
008     * with the License.  You may obtain a copy of the License at
009     *
010     *     http://www.apache.org/licenses/LICENSE-2.0
011     *
012     * Unless required by applicable law or agreed to in writing, software
013     * distributed under the License is distributed on an "AS IS" BASIS,
014     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015     * See the License for the specific language governing permissions and
016     * limitations under the License.
017     */
018    package org.apache.hadoop.hdfs.security.token.block;
019    
020    import java.io.IOException;
021    import java.util.EnumSet;
022    import java.util.HashMap;
023    import java.util.Map;
024    
025    import org.apache.hadoop.hdfs.protocol.ExtendedBlock;
026    import org.apache.hadoop.hdfs.security.token.block.BlockTokenSecretManager.AccessMode;
027    import org.apache.hadoop.security.token.SecretManager;
028    import org.apache.hadoop.security.token.Token;
029    
030    import com.google.common.annotations.VisibleForTesting;
031    
032    /**
033     * Manages a {@link BlockTokenSecretManager} per block pool. Routes the requests
034     * given a block pool Id to corresponding {@link BlockTokenSecretManager}
035     */
036    public class BlockPoolTokenSecretManager extends
037        SecretManager<BlockTokenIdentifier> {
038      
039      private final Map<String, BlockTokenSecretManager> map = 
040        new HashMap<String, BlockTokenSecretManager>();
041    
042      /**
043       * Add a block pool Id and corresponding {@link BlockTokenSecretManager} to map
044       * @param bpid block pool Id
045       * @param secretMgr {@link BlockTokenSecretManager}
046       */
047      public synchronized void addBlockPool(String bpid,
048          BlockTokenSecretManager secretMgr) {
049        map.put(bpid, secretMgr);
050      }
051    
052      synchronized BlockTokenSecretManager get(String bpid) {
053        BlockTokenSecretManager secretMgr = map.get(bpid);
054        if (secretMgr == null) {
055          throw new IllegalArgumentException("Block pool " + bpid
056              + " is not found");
057        }
058        return secretMgr;
059      }
060      
061      public synchronized boolean isBlockPoolRegistered(String bpid) {
062        return map.containsKey(bpid);
063      }
064    
065      /** Return an empty BlockTokenIdentifer */
066      @Override
067      public BlockTokenIdentifier createIdentifier() {
068        return new BlockTokenIdentifier();
069      }
070    
071      @Override
072      public byte[] createPassword(BlockTokenIdentifier identifier) {
073        return get(identifier.getBlockPoolId()).createPassword(identifier);
074      }
075    
076      @Override
077      public byte[] retrievePassword(BlockTokenIdentifier identifier)
078          throws InvalidToken {
079        return get(identifier.getBlockPoolId()).retrievePassword(identifier);
080      }
081    
082      /**
083       * See {@link BlockTokenSecretManager#checkAccess(BlockTokenIdentifier, 
084       *                String, ExtendedBlock, AccessMode)}
085       */
086      public void checkAccess(BlockTokenIdentifier id, String userId,
087          ExtendedBlock block, AccessMode mode) throws InvalidToken {
088        get(block.getBlockPoolId()).checkAccess(id, userId, block, mode);
089      }
090    
091      /**
092       * See {@link BlockTokenSecretManager#checkAccess(Token, String, 
093       *                ExtendedBlock, AccessMode)}
094       */
095      public void checkAccess(Token<BlockTokenIdentifier> token,
096          String userId, ExtendedBlock block, AccessMode mode) throws InvalidToken {
097        get(block.getBlockPoolId()).checkAccess(token, userId, block, mode);
098      }
099    
100      /**
101       * See {@link BlockTokenSecretManager#addKeys(ExportedBlockKeys)}
102       */
103      public void addKeys(String bpid, ExportedBlockKeys exportedKeys)
104          throws IOException {
105        get(bpid).addKeys(exportedKeys);
106      }
107    
108      /**
109       * See {@link BlockTokenSecretManager#generateToken(ExtendedBlock, EnumSet)}
110       */
111      public Token<BlockTokenIdentifier> generateToken(ExtendedBlock b,
112          EnumSet<AccessMode> of) throws IOException {
113        return get(b.getBlockPoolId()).generateToken(b, of);
114      }
115      
116      @VisibleForTesting
117      public void clearAllKeysForTesting() {
118        for (BlockTokenSecretManager btsm : map.values()) {
119          btsm.clearAllKeysForTesting();
120        }
121      }
122    
123      public DataEncryptionKey generateDataEncryptionKey(String blockPoolId) {
124        return get(blockPoolId).generateDataEncryptionKey();
125      }
126      
127      public byte[] retrieveDataEncryptionKey(int keyId, String blockPoolId,
128          byte[] nonce) throws IOException {
129        return get(blockPoolId).retrieveDataEncryptionKey(keyId, nonce);
130      }
131    }