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.lang.reflect.Constructor;
23 import java.util.concurrent.ExecutorService;
24
25 import org.apache.hadoop.hbase.classification.InterfaceAudience;
26 import org.apache.hadoop.hbase.classification.InterfaceStability;
27 import org.apache.hadoop.conf.Configuration;
28 import org.apache.hadoop.hbase.HBaseConfiguration;
29 import org.apache.hadoop.hbase.security.User;
30 import org.apache.hadoop.hbase.security.UserProvider;
31
32
33 /**
34 * A non-instantiable class that manages creation of {@link Connection}s.
35 * Managing the lifecycle of the {@link Connection}s to the cluster is the responsibility of
36 * the caller.
37 * From a {@link Connection}, {@link Table} implementations are retrieved
38 * with {@link Connection#getTable(TableName)}. Example:
39 * <pre>
40 * Connection connection = ConnectionFactory.createConnection(config);
41 * Table table = connection.getTable(TableName.valueOf("table1"));
42 * try {
43 * // Use the table as needed, for a single operation and a single thread
44 * } finally {
45 * table.close();
46 * connection.close();
47 * }
48 * </pre>
49 *
50 * Similarly, {@link Connection} also returns {@link Admin} and {@link RegionLocator}
51 * implementations.
52 *
53 * This class replaces {@link HConnectionManager}, which is now deprecated.
54 * @see Connection
55 * @since 0.99.0
56 */
57 @InterfaceAudience.Public
58 @InterfaceStability.Evolving
59 public class ConnectionFactory {
60
61 /** No public c.tors */
62 protected ConnectionFactory() {
63 }
64
65 /**
66 * Create a new Connection instance using default HBaseConfiguration. Connection
67 * encapsulates all housekeeping for a connection to the cluster. All tables and interfaces
68 * created from returned connection share zookeeper connection, meta cache, and connections
69 * to region servers and masters.
70 * <br>
71 * The caller is responsible for calling {@link Connection#close()} on the returned
72 * connection instance.
73 *
74 * Typical usage:
75 * <pre>
76 * Connection connection = ConnectionFactory.createConnection();
77 * Table table = connection.getTable(TableName.valueOf("mytable"));
78 * try {
79 * table.get(...);
80 * ...
81 * } finally {
82 * table.close();
83 * connection.close();
84 * }
85 * </pre>
86 *
87 * @return Connection object for <code>conf</code>
88 */
89 public static Connection createConnection() throws IOException {
90 return createConnection(HBaseConfiguration.create(), null, null);
91 }
92
93 /**
94 * Create a new Connection instance using the passed <code>conf</code> instance. Connection
95 * encapsulates all housekeeping for a connection to the cluster. All tables and interfaces
96 * created from returned connection share zookeeper connection, meta cache, and connections
97 * to region servers and masters.
98 * <br>
99 * The caller is responsible for calling {@link Connection#close()} on the returned
100 * connection instance.
101 *
102 * Typical usage:
103 * <pre>
104 * Connection connection = ConnectionFactory.createConnection(conf);
105 * Table table = connection.getTable(TableName.valueOf("mytable"));
106 * try {
107 * table.get(...);
108 * ...
109 * } finally {
110 * table.close();
111 * connection.close();
112 * }
113 * </pre>
114 *
115 * @param conf configuration
116 * @return Connection object for <code>conf</code>
117 */
118 public static Connection createConnection(Configuration conf) throws IOException {
119 return createConnection(conf, null, null);
120 }
121
122 /**
123 * Create a new Connection instance using the passed <code>conf</code> instance. Connection
124 * encapsulates all housekeeping for a connection to the cluster. All tables and interfaces
125 * created from returned connection share zookeeper connection, meta cache, and connections
126 * to region servers and masters.
127 * <br>
128 * The caller is responsible for calling {@link Connection#close()} on the returned
129 * connection instance.
130 *
131 * Typical usage:
132 * <pre>
133 * Connection connection = ConnectionFactory.createConnection(conf);
134 * Table table = connection.getTable(TableName.valueOf("mytable"));
135 * try {
136 * table.get(...);
137 * ...
138 * } finally {
139 * table.close();
140 * connection.close();
141 * }
142 * </pre>
143 *
144 * @param conf configuration
145 * @param pool the thread pool to use for batch operations
146 * @return Connection object for <code>conf</code>
147 */
148 public static Connection createConnection(Configuration conf, ExecutorService pool)
149 throws IOException {
150 return createConnection(conf, pool, null);
151 }
152
153 /**
154 * Create a new Connection instance using the passed <code>conf</code> instance. Connection
155 * encapsulates all housekeeping for a connection to the cluster. All tables and interfaces
156 * created from returned connection share zookeeper connection, meta cache, and connections
157 * to region servers and masters.
158 * <br>
159 * The caller is responsible for calling {@link Connection#close()} on the returned
160 * connection instance.
161 *
162 * Typical usage:
163 * <pre>
164 * Connection connection = ConnectionFactory.createConnection(conf);
165 * Table table = connection.getTable(TableName.valueOf("table1"));
166 * try {
167 * table.get(...);
168 * ...
169 * } finally {
170 * table.close();
171 * connection.close();
172 * }
173 * </pre>
174 *
175 * @param conf configuration
176 * @param user the user the connection is for
177 * @return Connection object for <code>conf</code>
178 */
179 public static Connection createConnection(Configuration conf, User user)
180 throws IOException {
181 return createConnection(conf, null, user);
182 }
183
184 /**
185 * Create a new Connection instance using the passed <code>conf</code> instance. Connection
186 * encapsulates all housekeeping for a connection to the cluster. All tables and interfaces
187 * created from returned connection share zookeeper connection, meta cache, and connections
188 * to region servers and masters.
189 * <br>
190 * The caller is responsible for calling {@link Connection#close()} on the returned
191 * connection instance.
192 *
193 * Typical usage:
194 * <pre>
195 * Connection connection = ConnectionFactory.createConnection(conf);
196 * Table table = connection.getTable(TableName.valueOf("table1"));
197 * try {
198 * table.get(...);
199 * ...
200 * } finally {
201 * table.close();
202 * connection.close();
203 * }
204 * </pre>
205 *
206 * @param conf configuration
207 * @param user the user the connection is for
208 * @param pool the thread pool to use for batch operations
209 * @return Connection object for <code>conf</code>
210 */
211 public static Connection createConnection(Configuration conf, ExecutorService pool, User user)
212 throws IOException {
213 if (user == null) {
214 UserProvider provider = UserProvider.instantiate(conf);
215 user = provider.getCurrent();
216 }
217
218 return createConnection(conf, false, pool, user);
219 }
220
221 static Connection createConnection(final Configuration conf, final boolean managed,
222 final ExecutorService pool, final User user)
223 throws IOException {
224 String className = conf.get(HConnection.HBASE_CLIENT_CONNECTION_IMPL,
225 ConnectionManager.HConnectionImplementation.class.getName());
226 Class<?> clazz = null;
227 try {
228 clazz = Class.forName(className);
229 } catch (ClassNotFoundException e) {
230 throw new IOException(e);
231 }
232 try {
233 // Default HCM#HCI is not accessible; make it so before invoking.
234 Constructor<?> constructor =
235 clazz.getDeclaredConstructor(Configuration.class,
236 boolean.class, ExecutorService.class, User.class);
237 constructor.setAccessible(true);
238 return (Connection) constructor.newInstance(conf, managed, pool, user);
239 } catch (Exception e) {
240 throw new IOException(e);
241 }
242 }
243 }