View Javadoc

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  package org.apache.hadoop.hbase.client;
21  
22  import java.io.IOException;
23  import java.util.Collections;
24  import java.util.HashMap;
25  import java.util.Map;
26  import java.util.Objects;
27  
28  import org.apache.hadoop.conf.Configuration;
29  import org.apache.hadoop.hbase.HConstants;
30  import org.apache.hadoop.hbase.ipc.RpcControllerFactory;
31  import org.apache.hadoop.hbase.security.User;
32  import org.apache.hadoop.hbase.security.UserProvider;
33  
34  /**
35   * Denotes a unique key to an {@link HConnection} instance.
36   *
37   * In essence, this class captures the properties in {@link Configuration}
38   * that may be used in the process of establishing a connection. In light of
39   * that, if any new such properties are introduced into the mix, they must be
40   * added to the {@link HConnectionKey#properties} list.
41   *
42   */
43  class HConnectionKey {
44    final static String[] CONNECTION_PROPERTIES = new String[] {
45        HConstants.ZOOKEEPER_QUORUM, HConstants.ZOOKEEPER_ZNODE_PARENT,
46        HConstants.ZOOKEEPER_CLIENT_PORT,
47        HConstants.ZOOKEEPER_RECOVERABLE_WAITTIME,
48        HConstants.HBASE_CLIENT_PAUSE, HConstants.HBASE_CLIENT_RETRIES_NUMBER,
49        HConstants.HBASE_RPC_TIMEOUT_KEY,
50        HConstants.HBASE_META_SCANNER_CACHING,
51        HConstants.HBASE_CLIENT_INSTANCE_ID,
52        HConstants.RPC_CODEC_CONF_KEY,
53        HConstants.USE_META_REPLICAS,
54        RpcControllerFactory.CUSTOM_CONTROLLER_CONF_KEY};
55  
56    private Map<String, String> properties;
57    private String username;
58  
59    HConnectionKey(Configuration conf) {
60      Map<String, String> m = new HashMap<String, String>();
61      if (conf != null) {
62        for (String property : CONNECTION_PROPERTIES) {
63          String value = conf.get(property);
64          if (value != null) {
65            m.put(property, value);
66          }
67        }
68      }
69      this.properties = Collections.unmodifiableMap(m);
70  
71      try {
72        UserProvider provider = UserProvider.instantiate(conf);
73        User currentUser = provider.getCurrent();
74        if (currentUser != null) {
75          username = currentUser.getName();
76        }
77      } catch (IOException ioe) {
78        ConnectionManager.LOG.warn(
79            "Error obtaining current user, skipping username in HConnectionKey", ioe);
80      }
81    }
82  
83    @Override
84    public int hashCode() {
85      final int prime = 31;
86      int result = 1;
87      if (username != null) {
88        result = username.hashCode();
89      }
90      for (String property : CONNECTION_PROPERTIES) {
91        String value = properties.get(property);
92        if (value != null) {
93          result = prime * result + value.hashCode();
94        }
95      }
96  
97      return result;
98    }
99  
100 
101   @edu.umd.cs.findbugs.annotations.SuppressWarnings (value="ES_COMPARING_STRINGS_WITH_EQ",
102       justification="Optimization")
103   @Override
104   public boolean equals(Object obj) {
105     if (this == obj)
106       return true;
107     if (obj == null)
108       return false;
109     if (getClass() != obj.getClass())
110       return false;
111     HConnectionKey that = (HConnectionKey) obj;
112     if (this.username != null && !this.username.equals(that.username)) {
113       return false;
114     } else if (this.username == null && that.username != null) {
115       return false;
116     }
117     if (this.properties == null) {
118       if (that.properties != null) {
119         return false;
120       }
121     } else {
122       if (that.properties == null) {
123         return false;
124       }
125       for (String property : CONNECTION_PROPERTIES) {
126         String thisValue = this.properties.get(property);
127         String thatValue = that.properties.get(property);
128         if (Objects.equals(thisValue, thatValue)) {
129           continue;
130         }
131         if (thisValue == null || !thisValue.equals(thatValue)) {
132           return false;
133         }
134       }
135     }
136     return true;
137   }
138 
139   @Override
140   public String toString() {
141     return "HConnectionKey{" +
142       "properties=" + properties +
143       ", username='" + username + '\'' +
144       '}';
145   }
146 }