1   /*
2    * Copyright The Apache Software Foundation
3    *
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *     http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing, software
15   * distributed under the License is distributed on an "AS IS" BASIS,
16   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17   * See the License for the specific language governing permissions and
18   * limitations under the License.
19   */
20  
21  package org.apache.hadoop.hbase.ipc;
22  
23  import org.apache.hadoop.classification.InterfaceAudience;
24  import org.apache.hadoop.hbase.security.User;
25  
26  import com.google.protobuf.BlockingService;
27  
28  import java.net.InetAddress;
29  
30  /**
31   * Represents client information (authenticated username, remote address, protocol)
32   * for the currently executing request within a RPC server handler thread.  If
33   * called outside the context of a RPC request, all values will be
34   * <code>null</code>.
35   */
36  @InterfaceAudience.Private
37  public class RequestContext {
38    private static ThreadLocal<RequestContext> instance =
39        new ThreadLocal<RequestContext>() {
40          protected RequestContext initialValue() {
41            return new RequestContext(null, null, null);
42          }
43        };
44  
45    public static RequestContext get() {
46      return instance.get();
47    }
48  
49  
50    /**
51     * Returns the user credentials associated with the current RPC request or
52     * <code>null</code> if no credentials were provided.
53     * @return A User
54     */
55    public static User getRequestUser() {
56      RequestContext ctx = instance.get();
57      if (ctx != null) {
58        return ctx.getUser();
59      }
60      return null;
61    }
62  
63    /**
64     * Returns the username for any user associated with the current RPC
65     * request or <code>null</code> if no user is set.
66     */
67    public static String getRequestUserName() {
68      User user = getRequestUser();
69      if (user != null) {
70        return user.getShortName();
71      }
72      return null;
73    }
74  
75    /**
76     * Indicates whether or not the current thread is within scope of executing
77     * an RPC request.
78     */
79    public static boolean isInRequestContext() {
80      RequestContext ctx = instance.get();
81      if (ctx != null) {
82        return ctx.isInRequest();
83      }
84      return false;
85    }
86  
87    /**
88     * Initializes the client credentials for the current request.
89     * @param user
90     * @param remoteAddress
91     * @param service
92     */
93    public static void set(User user,
94        InetAddress remoteAddress, BlockingService service) {
95      RequestContext ctx = instance.get();
96      ctx.user = user;
97      ctx.remoteAddress = remoteAddress;
98      ctx.service = service;
99      ctx.inRequest = true;
100   }
101 
102   /**
103    * Clears out the client credentials for a given request.
104    */
105   public static void clear() {
106     RequestContext ctx = instance.get();
107     ctx.user = null;
108     ctx.remoteAddress = null;
109     ctx.service = null;
110     ctx.inRequest = false;
111   }
112 
113   private User user;
114   private InetAddress remoteAddress;
115   private BlockingService service;
116   // indicates we're within a RPC request invocation
117   private boolean inRequest;
118 
119   private RequestContext(User user, InetAddress remoteAddr, BlockingService service) {
120     this.user = user;
121     this.remoteAddress = remoteAddr;
122     this.service = service;
123   }
124 
125   public User getUser() {
126     return user;
127   }
128 
129   public InetAddress getRemoteAddress() {
130     return remoteAddress;
131   }
132 
133   public BlockingService getService() {
134     return this.service;
135   }
136 
137   public boolean isInRequest() {
138     return inRequest;
139   }
140 }