1 /**
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 */
19 package org.apache.hadoop.hbase.client;
20
21 import java.io.IOException;
22 import java.util.concurrent.ExecutorService;
23 import org.apache.commons.logging.Log;
24 import org.apache.hadoop.hbase.classification.InterfaceAudience;
25 import org.apache.hadoop.hbase.classification.InterfaceStability;
26 import org.apache.hadoop.conf.Configuration;
27 import org.apache.hadoop.hbase.security.User;
28
29 /**
30 * A non-instantiable class that manages creation of {@link HConnection}s.
31 * <p>The simplest way to use this class is by using {@link #createConnection(Configuration)}.
32 * This creates a new {@link HConnection} to the cluster that is managed by the caller.
33 * From this {@link HConnection} {@link HTableInterface} implementations are retrieved
34 * with {@link HConnection#getTable(byte[])}. Example:
35 * <pre>
36 * HConnection connection = HConnectionManager.createConnection(config);
37 * HTableInterface table = connection.getTable(TableName.valueOf("table1"));
38 * try {
39 * // Use the table as needed, for a single operation and a single thread
40 * } finally {
41 * table.close();
42 * connection.close();
43 * }
44 * </pre>
45 * <p>This class has a static Map of {@link HConnection} instances keyed by
46 * {@link HConnectionKey}; A {@link HConnectionKey} is identified by a set of
47 * {@link Configuration} properties. Invocations of {@link #getConnection(Configuration)}
48 * that pass the same {@link Configuration} instance will return the same
49 * {@link HConnection} instance ONLY WHEN the set of properties are the same
50 * (i.e. if you change properties in your {@link Configuration} instance, such as RPC timeout,
51 * the codec used, HBase will create a new {@link HConnection} instance. For more details on
52 * how this is done see {@link HConnectionKey}).
53 * <p>Sharing {@link HConnection} instances is usually what you want; all clients
54 * of the {@link HConnection} instances share the HConnections' cache of Region
55 * locations rather than each having to discover for itself the location of meta, etc.
56 * But sharing connections makes clean up of {@link HConnection} instances a little awkward.
57 * Currently, clients cleanup by calling {@link #deleteConnection(Configuration)}. This will
58 * shutdown the zookeeper connection the HConnection was using and clean up all
59 * HConnection resources as well as stopping proxies to servers out on the
60 * cluster. Not running the cleanup will not end the world; it'll
61 * just stall the closeup some and spew some zookeeper connection failed
62 * messages into the log. Running the cleanup on a {@link HConnection} that is
63 * subsequently used by another will cause breakage so be careful running
64 * cleanup.
65 * <p>To create a {@link HConnection} that is not shared by others, you can
66 * set property "hbase.client.instance.id" to a unique value for your {@link Configuration}
67 * instance, like the following:
68 * <pre>
69 * {@code
70 * conf.set("hbase.client.instance.id", "12345");
71 * HConnection connection = HConnectionManager.getConnection(conf);
72 * // Use the connection to your hearts' delight and then when done...
73 * conf.set("hbase.client.instance.id", "12345");
74 * HConnectionManager.deleteConnection(conf, true);
75 * }
76 * </pre>
77 * <p>Cleanup used to be done inside in a shutdown hook. On startup we'd
78 * register a shutdown hook that called {@link #deleteAllConnections()}
79 * on its way out but the order in which shutdown hooks run is not defined so
80 * were problematic for clients of HConnection that wanted to register their
81 * own shutdown hooks so we removed ours though this shifts the onus for
82 * cleanup to the client.
83 * @deprecated Please use ConnectionFactory instead
84 */
85 @InterfaceAudience.Public
86 @InterfaceStability.Evolving
87 @Deprecated
88 public class HConnectionManager extends ConnectionFactory {
89
90 @Deprecated
91 public static final String RETRIES_BY_SERVER_KEY =
92 ConnectionManager.RETRIES_BY_SERVER_KEY;
93
94 @Deprecated
95 public static final int MAX_CACHED_CONNECTION_INSTANCES =
96 ConnectionManager.MAX_CACHED_CONNECTION_INSTANCES;
97
98 /*
99 * Non-instantiable.
100 */
101 private HConnectionManager() {
102 super();
103 }
104
105 /**
106 * Get the connection that goes with the passed <code>conf</code> configuration instance.
107 * If no current connection exists, method creates a new connection and keys it using
108 * connection-specific properties from the passed {@link Configuration}; see
109 * {@link HConnectionKey}.
110 * @param conf configuration
111 * @return HConnection object for <code>conf</code>
112 * @throws ZooKeeperConnectionException
113 */
114 @Deprecated
115 public static HConnection getConnection(final Configuration conf) throws IOException {
116 return ConnectionManager.getConnectionInternal(conf);
117 }
118
119 /**
120 * Create a new HConnection instance using the passed <code>conf</code> instance.
121 * <p>Note: This bypasses the usual HConnection life cycle management done by
122 * {@link #getConnection(Configuration)}. The caller is responsible for
123 * calling {@link HConnection#close()} on the returned connection instance.
124 *
125 * This is the recommended way to create HConnections.
126 * <pre>
127 * HConnection connection = HConnectionManager.createConnection(conf);
128 * HTableInterface table = connection.getTable("mytable");
129 * try {
130 * table.get(...);
131 * ...
132 * } finally {
133 * table.close();
134 * connection.close();
135 * }
136 * </pre>
137 *
138 * @param conf configuration
139 * @return HConnection object for <code>conf</code>
140 * @throws ZooKeeperConnectionException
141 */
142 @Deprecated
143 public static HConnection createConnection(Configuration conf) throws IOException {
144 return ConnectionManager.createConnectionInternal(conf);
145 }
146
147
148 /**
149 * Create a new HConnection instance using the passed <code>conf</code> instance.
150 * <p>Note: This bypasses the usual HConnection life cycle management done by
151 * {@link #getConnection(Configuration)}. The caller is responsible for
152 * calling {@link HConnection#close()} on the returned connection instance.
153 * This is the recommended way to create HConnections.
154 * <pre>
155 * ExecutorService pool = ...;
156 * HConnection connection = HConnectionManager.createConnection(conf, pool);
157 * HTableInterface table = connection.getTable("mytable");
158 * table.get(...);
159 * ...
160 * table.close();
161 * connection.close();
162 * </pre>
163 * @param conf configuration
164 * @param pool the thread pool to use for batch operation in HTables used via this HConnection
165 * @return HConnection object for <code>conf</code>
166 * @throws ZooKeeperConnectionException
167 */
168 @Deprecated
169 public static HConnection createConnection(Configuration conf, ExecutorService pool)
170 throws IOException {
171 return ConnectionManager.createConnection(conf, pool);
172 }
173
174 /**
175 * Create a new HConnection instance using the passed <code>conf</code> instance.
176 * <p>Note: This bypasses the usual HConnection life cycle management done by
177 * {@link #getConnection(Configuration)}. The caller is responsible for
178 * calling {@link HConnection#close()} on the returned connection instance.
179 * This is the recommended way to create HConnections.
180 * <pre>
181 * ExecutorService pool = ...;
182 * HConnection connection = HConnectionManager.createConnection(conf, pool);
183 * HTableInterface table = connection.getTable("mytable");
184 * table.get(...);
185 * ...
186 * table.close();
187 * connection.close();
188 * </pre>
189 * @param conf configuration
190 * @param user the user the connection is for
191 * @return HConnection object for <code>conf</code>
192 * @throws ZooKeeperConnectionException
193 */
194 @Deprecated
195 public static HConnection createConnection(Configuration conf, User user)
196 throws IOException {
197 return ConnectionManager.createConnection(conf, user);
198 }
199
200 /**
201 * Create a new HConnection instance using the passed <code>conf</code> instance.
202 * <p>Note: This bypasses the usual HConnection life cycle management done by
203 * {@link #getConnection(Configuration)}. The caller is responsible for
204 * calling {@link HConnection#close()} on the returned connection instance.
205 * This is the recommended way to create HConnections.
206 * <pre>
207 * ExecutorService pool = ...;
208 * HConnection connection = HConnectionManager.createConnection(conf, pool);
209 * HTableInterface table = connection.getTable("mytable");
210 * table.get(...);
211 * ...
212 * table.close();
213 * connection.close();
214 * </pre>
215 * @param conf configuration
216 * @param pool the thread pool to use for batch operation in HTables used via this HConnection
217 * @param user the user the connection is for
218 * @return HConnection object for <code>conf</code>
219 * @throws ZooKeeperConnectionException
220 */
221 @Deprecated
222 public static HConnection createConnection(Configuration conf, ExecutorService pool, User user)
223 throws IOException {
224 return ConnectionManager.createConnection(conf, pool, user);
225 }
226
227 @Deprecated
228 static HConnection createConnection(final Configuration conf, final boolean managed)
229 throws IOException {
230 return ConnectionManager.createConnection(conf, managed);
231 }
232
233 @Deprecated
234 static ClusterConnection createConnection(final Configuration conf, final boolean managed,
235 final ExecutorService pool, final User user) throws IOException {
236 return ConnectionManager.createConnection(conf, managed, pool, user);
237 }
238
239 /**
240 * Delete connection information for the instance specified by passed configuration.
241 * If there are no more references to the designated connection connection, this method will
242 * then close connection to the zookeeper ensemble and let go of all associated resources.
243 *
244 * @param conf configuration whose identity is used to find {@link HConnection} instance.
245 * @deprecated
246 */
247 @Deprecated
248 public static void deleteConnection(Configuration conf) {
249 ConnectionManager.deleteConnection(conf);
250 }
251
252 /**
253 * Cleanup a known stale connection.
254 * This will then close connection to the zookeeper ensemble and let go of all resources.
255 *
256 * @param connection
257 * @deprecated
258 */
259 @Deprecated
260 public static void deleteStaleConnection(HConnection connection) {
261 ConnectionManager.deleteStaleConnection(connection);
262 }
263
264 /**
265 * Delete information for all connections. Close or not the connection, depending on the
266 * staleConnection boolean and the ref count. By default, you should use it with
267 * staleConnection to true.
268 * @deprecated
269 */
270 @Deprecated
271 public static void deleteAllConnections(boolean staleConnection) {
272 ConnectionManager.deleteAllConnections(staleConnection);
273 }
274
275 /**
276 * Delete information for all connections..
277 * @deprecated kept for backward compatibility, but the behavior is broken. HBASE-8983
278 */
279 @Deprecated
280 public static void deleteAllConnections() {
281 ConnectionManager.deleteAllConnections();
282 }
283
284 /**
285 * This convenience method invokes the given {@link HConnectable#connect}
286 * implementation using a {@link HConnection} instance that lasts just for the
287 * duration of the invocation.
288 *
289 * @param <T> the return type of the connect method
290 * @param connectable the {@link HConnectable} instance
291 * @return the value returned by the connect method
292 * @throws IOException
293 * @deprecated Internal method, do not use thru HConnectionManager.
294 */
295 @InterfaceAudience.Private
296 @Deprecated
297 public static <T> T execute(HConnectable<T> connectable) throws IOException {
298 return ConnectionManager.execute(connectable);
299 }
300
301 /**
302 * Set the number of retries to use serverside when trying to communicate
303 * with another server over {@link HConnection}. Used updating catalog
304 * tables, etc. Call this method before we create any Connections.
305 * @param c The Configuration instance to set the retries into.
306 * @param log Used to log what we set in here.
307 * @deprecated Internal method, do not use.
308 */
309 @InterfaceAudience.Private
310 @Deprecated
311 public static void setServerSideHConnectionRetries(
312 final Configuration c, final String sn, final Log log) {
313 ConnectionUtils.setServerSideHConnectionRetriesConfig(c, sn, log);
314 }
315 }