Skip to content

Commit cc22f2f

Browse files
feat: use concrete classes for hbase.client.registry.impl (#4043) (#4188)
Previously we used runtime bytecode generation which prevented endusers from using hbase-site.xml to target bigtable in hbase 2 applications. This PR will create a concrete implementation for both AsyncRegistry for (hbase < 2.3) and ConnectionRegistry (for hbase >= 2.3). To accomplish this, we use a local copy of the AsyncRegistry interface from HBase 2.2 that we use as a compile time target and then strip it from the resulting jar. After this change end users should be able to use async apis in hbase 2 using hbase-site.xml. Examples: ```xml <configuration> <property> <name>hbase.client.connection.impl</name> <value>com.google.cloud.bigtable.hbase2_x.BigtableConnection</value> </property> <property> <name>hbase.client.async.connection.impl</name> <value>org.apache.hadoop.hbase.client.BigtableAsyncConnection</value> </property> <property> <name>hbase.client.registry.impl</name> <!-- When using hbase >= 2.3, use this --> <value>org.apache.hadoop.hbase.client.BigtableConnectionRegistry</value> <!-- When using hbase < 2.3, use this --> <!-- <value>org.apache.hadoop.hbase.client.BigtableAsyncRegistry</value> --> </property> <property> <name>google.bigtable.project.id</name> <value>my-project</value> </property> <property> <name>google.bigtable.instance.id</name> <value>my-instance</value> </property> <property> <name>google.bigtable.app_profile.id</name> <value>my-app-profile</value> </property> </configuration> ``` ```java AsyncConnection asyncConnection = ConnectionFactory.createAsyncConnection().get(); ```
1 parent ab4c790 commit cc22f2f

File tree

12 files changed

+930
-167
lines changed

12 files changed

+930
-167
lines changed

bigtable-client-core-parent/bigtable-hbase/pom.xml

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -176,12 +176,6 @@ limitations under the License.
176176
<scope>runtime</scope>
177177
</dependency>
178178

179-
<dependency>
180-
<groupId>net.bytebuddy</groupId>
181-
<artifactId>byte-buddy</artifactId>
182-
<version>${byte.buddy.version}</version>
183-
</dependency>
184-
185179
<!-- Test -->
186180
<dependency>
187181
<groupId>com.google.cloud.bigtable</groupId>

bigtable-client-core-parent/bigtable-hbase/src/main/java/com/google/cloud/bigtable/hbase/BigtableConfiguration.java

Lines changed: 49 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
import com.google.auth.Credentials;
2121
import com.google.common.base.Preconditions;
2222
import org.apache.hadoop.conf.Configuration;
23-
import org.apache.hadoop.hbase.client.BigtableAsyncRegistry;
2423
import org.apache.hadoop.hbase.client.Connection;
2524

2625
/** This class provides a simplified mechanism of creating a programmatic Bigtable Connection. */
@@ -35,34 +34,20 @@ public class BigtableConfiguration {
3534
public static final String HBASE_CLIENT_ASYNC_CONNECTION_IMPL =
3635
"hbase.client.async.connection.impl";
3736

37+
// The value of this field can implement 2 different interfaces depending on the HBase version
38+
// For 2.0 - 2.2 the value must implement AsyncRegistry
39+
// For 2.3 onwards the value must implement ConnectionRegistry
40+
// bigable-hbase-2x contains implementations for both, this helper will use classpath probing to
41+
// guess the correct impl.
3842
/** For internal use only - public for technical reasons. */
3943
@InternalApi("For internal usage only")
4044
public static final String HBASE_CLIENT_ASYNC_REGISTRY_IMPL = "hbase.client.registry.impl";
4145

42-
/** For internal use only - public for technical reasons. */
43-
@InternalApi("For internal usage only")
44-
public static final String BIGTABLE_HBASE_CLIENT_ASYNC_CONNECTION_CLASS =
45-
"org.apache.hadoop.hbase.client.BigtableAsyncConnection";
46-
47-
/** For internal use only - public for technical reasons. */
48-
@InternalApi("For internal usage only")
49-
public static final String BIGTABLE_HBASE_CLIENT_ASYNC_REGISTRY_CLASS =
50-
"org.apache.hadoop.hbase.client.BigtableAsyncRegistry";
51-
52-
private static final String HBASE_ASYNC_CONNECTION_CLASS =
53-
"org.apache.hadoop.hbase.client.AsyncConnection";
54-
5546
private static final String[] CONNECTION_CLASS_NAMES = {
5647
"com.google.cloud.bigtable.hbase1_x.BigtableConnection",
5748
"com.google.cloud.bigtable.hbase2_x.BigtableConnection",
5849
};
5950

60-
private static final String[] ASYNC_CONNECTION_CLASS_NAMES = {
61-
BIGTABLE_HBASE_CLIENT_ASYNC_CONNECTION_CLASS,
62-
BIGTABLE_HBASE_CLIENT_ASYNC_REGISTRY_CLASS,
63-
HBASE_ASYNC_CONNECTION_CLASS
64-
};
65-
6651
private static final Class<? extends Connection> CONNECTION_CLASS = chooseConnectionClass();
6752

6853
@SuppressWarnings("unchecked")
@@ -91,24 +76,57 @@ public static Class<? extends Connection> getConnectionClass() {
9176
return CONNECTION_CLASS;
9277
}
9378

79+
private static Class<?> getConnectionRegistryClass() {
80+
try {
81+
Class.forName("org.apache.hadoop.hbase.client.ConnectionRegistry");
82+
return Class.forName("org.apache.hadoop.hbase.client.BigtableConnectionRegistry");
83+
} catch (ClassNotFoundException e) {
84+
// noop
85+
}
86+
87+
try {
88+
Class.forName("org.apache.hadoop.hbase.client.AsyncRegistry");
89+
return Class.forName("org.apache.hadoop.hbase.client.BigtableAsyncRegistry");
90+
} catch (ClassNotFoundException e) {
91+
// noop
92+
}
93+
94+
return null;
95+
}
96+
97+
private static Class<?> getAsyncConnectionClass() {
98+
try {
99+
// Make sure HBase interface is present
100+
Class.forName("org.apache.hadoop.hbase.client.AsyncConnection");
101+
} catch (ClassNotFoundException e) {
102+
return null;
103+
}
104+
105+
try {
106+
// then try loading our implementation
107+
return Class.forName("org.apache.hadoop.hbase.client.BigtableAsyncConnection");
108+
} catch (ClassNotFoundException e) {
109+
return null;
110+
}
111+
}
112+
94113
/**
95114
* Set up connection impl classes. If Bigtable and HBase async connection classes exist, set up
96115
* async connection impl class as well.
97116
*/
98117
private static Configuration injectBigtableImpls(Configuration configuration) {
118+
// HBase 1x & 2x sync connection
99119
configuration.set(HBASE_CLIENT_CONNECTION_IMPL, getConnectionClass().getCanonicalName());
100-
try {
101-
// Set up HBase async registry impl if async connection classes exist
102-
for (String className : ASYNC_CONNECTION_CLASS_NAMES) {
103-
Class.forName(className);
104-
}
105-
configuration.set(
106-
HBASE_CLIENT_ASYNC_CONNECTION_IMPL, BIGTABLE_HBASE_CLIENT_ASYNC_CONNECTION_CLASS);
107-
configuration.set(
108-
HBASE_CLIENT_ASYNC_REGISTRY_IMPL, BigtableAsyncRegistry.getSubClass().getName());
109-
} catch (ClassNotFoundException ignored) {
110-
// Skip if any of the async connection class doesn't exist
120+
121+
// HBase 2x async
122+
Class<?> asyncConnectionClass = getAsyncConnectionClass();
123+
Class<?> connectionRegistryClass = getConnectionRegistryClass();
124+
125+
if (asyncConnectionClass != null && connectionRegistryClass != null) {
126+
configuration.set(HBASE_CLIENT_ASYNC_CONNECTION_IMPL, asyncConnectionClass.getName());
127+
configuration.set(HBASE_CLIENT_ASYNC_REGISTRY_IMPL, connectionRegistryClass.getName());
111128
}
129+
112130
return configuration;
113131
}
114132

@@ -179,25 +197,6 @@ public static Configuration withCredentials(Configuration conf, Credentials cred
179197
return new BigtableExtendedConfiguration(conf, credentials);
180198
}
181199

182-
/**
183-
* Configuration for getting a org.apache.hadoop.hbase.client.AsyncConnection.
184-
*
185-
* @param conf a {@link org.apache.hadoop.conf.Configuration} object to configure.
186-
* @return the modified {@link org.apache.hadoop.conf.Configuration} object.
187-
* @deprecated For HBase 2.x async connections, please use {@link #configure(String, String)}
188-
* directly.
189-
* <pre>{@code
190-
* Configure config = BigtableConfiguration.configure(projectId, instanceId);
191-
* AsyncConnection asyncConnection = ConnectionFactory.createAsyncConnection(config).get();
192-
* }</pre>
193-
*/
194-
@Deprecated
195-
public static Configuration asyncConfigure(Configuration conf) {
196-
conf.set(HBASE_CLIENT_ASYNC_CONNECTION_IMPL, BIGTABLE_HBASE_CLIENT_ASYNC_CONNECTION_CLASS);
197-
conf.set(HBASE_CLIENT_ASYNC_REGISTRY_IMPL, BigtableAsyncRegistry.getSubClass().getName());
198-
return conf;
199-
}
200-
201200
/**
202201
* connect.
203202
*

bigtable-client-core-parent/bigtable-hbase/src/main/java/org/apache/hadoop/hbase/client/BigtableAsyncRegistry.java

Lines changed: 0 additions & 111 deletions
This file was deleted.

bigtable-hbase-2.x-parent/bigtable-hbase-2.x-hadoop/pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,7 @@ limitations under the License.
251251
<classEntry>org/apache/hadoop/hbase/client/AbstractBigtableAdmin</classEntry>
252252
<classEntry>org/apache/hadoop/hbase/client/AbstractBigtableConnection</classEntry>
253253
<classEntry>org/apache/hadoop/hbase/client/BigtableAsyncConnection</classEntry>
254+
<classEntry>org/apache/hadoop/hbase/client/BigtableConnectionRegistry</classEntry>
254255
<classEntry>org/apache/hadoop/hbase/client/BigtableAsyncRegistry</classEntry>
255256
<classEntry>org/apache/hadoop/hbase/client/CommonConnection</classEntry>
256257
</allowedJarClassEntries>

bigtable-hbase-2.x-parent/bigtable-hbase-2.x-shaded/pom.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,8 +431,10 @@ limitations under the License.
431431
<classEntry>org/apache/hadoop/hbase/client/AbstractBigtableAdmin</classEntry>
432432
<classEntry>org/apache/hadoop/hbase/client/AbstractBigtableConnection</classEntry>
433433
<classEntry>org/apache/hadoop/hbase/client/BigtableAsyncConnection</classEntry>
434+
<classEntry>org/apache/hadoop/hbase/client/BigtableConnectionRegistry</classEntry>
434435
<classEntry>org/apache/hadoop/hbase/client/BigtableAsyncRegistry</classEntry>
435436
<classEntry>org/apache/hadoop/hbase/client/CommonConnection</classEntry>
437+
<classEntry>org/apache/hadoop/hbase/client/BigtableConnectionRegistry</classEntry>
436438
</allowedJarClassEntries>
437439
</configuration>
438440
</execution>

bigtable-hbase-2.x-parent/bigtable-hbase-2.x/pom.xml

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,22 @@ limitations under the License.
194194
</dependency>
195195
</dependencies>
196196
<build>
197+
<pluginManagement>
198+
<plugins>
199+
<!-- AsyncRegistry was an interface that existed in hbase 2.0-2.2. It's no longer shipped. To ensure
200+
compatibility we vendored it in this project to compile against, but do not want to ship it our binary -->
201+
<plugin>
202+
<groupId>org.apache.maven.plugins</groupId>
203+
<artifactId>maven-jar-plugin</artifactId>
204+
<configuration>
205+
<excludes>
206+
<exclude>org/apache/hadoop/hbase/client/AsyncRegistry.class</exclude>
207+
</excludes>
208+
</configuration>
209+
</plugin>
210+
</plugins>
211+
</pluginManagement>
212+
197213
<plugins>
198214
<plugin>
199215
<groupId>org.apache.maven.plugins</groupId>
@@ -205,6 +221,9 @@ limitations under the License.
205221
See bigtable-hbase-1.x pom.xml for more details-->
206222
<ignoredNonTestScopedDependency>*</ignoredNonTestScopedDependency>
207223
</ignoredNonTestScopedDependencies>
224+
<ignoredDependencies>
225+
<dependency>*</dependency>
226+
</ignoredDependencies>
208227
</configuration>
209228
</plugin>
210229
<plugin>
@@ -215,6 +234,25 @@ limitations under the License.
215234
<skip>true</skip>
216235
</configuration>
217236
</plugin>
237+
238+
<plugin>
239+
<groupId>org.codehaus.mojo</groupId>
240+
<artifactId>build-helper-maven-plugin</artifactId>
241+
<executions>
242+
<execution>
243+
<id>add-source</id>
244+
<phase>generate-sources</phase>
245+
<goals>
246+
<goal>add-source</goal>
247+
</goals>
248+
<configuration>
249+
<sources>
250+
<source>../../third_party/third_party_hbase_client_pre23/src/main/java</source>
251+
</sources>
252+
</configuration>
253+
</execution>
254+
</executions>
255+
</plugin>
218256
</plugins>
219257
</build>
220258
</project>

0 commit comments

Comments
 (0)