View Javadoc

1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  
19  package org.apache.hadoop.hbase.security.token;
20  
21  import java.io.IOException;
22  
23  import org.apache.commons.logging.Log;
24  import org.apache.commons.logging.LogFactory;
25  import org.apache.hadoop.hbase.classification.InterfaceAudience;
26  import org.apache.hadoop.hbase.classification.InterfaceStability;
27  import org.apache.hadoop.fs.FileSystem;
28  import org.apache.hadoop.hbase.security.UserProvider;
29  import org.apache.hadoop.security.token.Token;
30  
31  /**
32   * Helper class to obtain a filesystem delegation token.
33   * Mainly used by Map-Reduce jobs that requires to read/write data to 
34   * a remote file-system (e.g. BulkLoad, ExportSnapshot).
35   */
36  @InterfaceAudience.Private
37  @InterfaceStability.Evolving
38  public class FsDelegationToken {
39    private static final Log LOG = LogFactory.getLog(FsDelegationToken.class);
40  
41    private final UserProvider userProvider;
42    private final String renewer;
43  
44    private boolean hasForwardedToken = false;
45    private Token<?> userToken = null;
46    private FileSystem fs = null;
47  
48    /*
49     * @param renewer the account name that is allowed to renew the token.
50     */
51    public FsDelegationToken(final UserProvider userProvider, final String renewer) {
52      this.userProvider = userProvider;
53      this.renewer = renewer;
54    }
55  
56    /**
57     * Acquire the delegation token for the specified filesytem.
58     * Before requesting a new delegation token, tries to find one already available.
59     *
60     * @param fs the filesystem that requires the delegation token
61     * @throws IOException on fs.getDelegationToken() failure
62     */
63    public void acquireDelegationToken(final FileSystem fs)
64        throws IOException {
65      if (userProvider.isHadoopSecurityEnabled()) {
66        this.fs = fs;
67        userToken = userProvider.getCurrent().getToken("HDFS_DELEGATION_TOKEN",
68                                                        fs.getCanonicalServiceName());
69        if (userToken == null) {
70          hasForwardedToken = false;
71          try {
72            userToken = fs.getDelegationToken(renewer);
73          } catch (NullPointerException npe) {
74            // we need to handle NullPointerException in case HADOOP-10009 is missing
75            LOG.error("Failed to get token for " + renewer);
76          }
77        } else {
78          hasForwardedToken = true;
79          LOG.info("Use the existing token: " + userToken);
80        }
81      }
82    }
83  
84    /**
85     * Releases a previously acquired delegation token.
86     */
87    public void releaseDelegationToken() {
88      if (userProvider.isHadoopSecurityEnabled()) {
89        if (userToken != null && !hasForwardedToken) {
90          try {
91            userToken.cancel(this.fs.getConf());
92          } catch (Exception e) {
93            LOG.warn("Failed to cancel HDFS delegation token: " + userToken, e);
94          }
95        }
96        this.userToken = null;
97        this.fs = null;
98      }
99    }
100 
101   public UserProvider getUserProvider() {
102     return userProvider;
103   }
104 
105   /**
106    * @return the account name that is allowed to renew the token.
107    */
108   public String getRenewer() {
109     return renewer;
110   }
111 
112   /**
113    * @return the delegation token acquired, or null in case it was not acquired
114    */
115   public Token<?> getUserToken() {
116     return userToken;
117   }
118 
119   public FileSystem getFileSystem() {
120     return fs;
121   }
122 }