1616package com .google .cloud .bigtable .hbase1_x ;
1717
1818import com .google .api .core .InternalApi ;
19+ import com .google .common .base .Throwables ;
1920import com .google .common .collect .ImmutableList ;
2021import com .google .common .util .concurrent .Futures ;
2122import java .io .IOException ;
23+ import java .lang .reflect .InvocationTargetException ;
2224import java .util .ArrayList ;
2325import java .util .Collection ;
2426import java .util .Collections ;
2527import java .util .List ;
26- import java .util .Map ;
27- import java .util .Set ;
28- import java .util .concurrent .Future ;
2928import java .util .concurrent .TimeUnit ;
3029import java .util .regex .Pattern ;
30+ import net .bytebuddy .ByteBuddy ;
31+ import net .bytebuddy .implementation .InvocationHandlerAdapter ;
32+ import net .bytebuddy .matcher .ElementMatchers ;
3133import org .apache .hadoop .hbase .ClusterStatus ;
32- import org .apache .hadoop .hbase .ProcedureInfo ;
3334import org .apache .hadoop .hbase .ServerName ;
3435import org .apache .hadoop .hbase .TableExistsException ;
3536import org .apache .hadoop .hbase .TableName ;
3637import org .apache .hadoop .hbase .client .AbstractBigtableAdmin ;
38+ import org .apache .hadoop .hbase .client .Admin ;
3739import org .apache .hadoop .hbase .client .CommonConnection ;
38- import org .apache .hadoop .hbase .client .LogEntry ;
39- import org .apache .hadoop .hbase .client .ServerType ;
40- import org .apache .hadoop .hbase .client .security .SecurityCapability ;
41- import org .apache .hadoop .hbase .protobuf .generated .AdminProtos ;
4240import org .apache .hadoop .hbase .protobuf .generated .HBaseProtos ;
43- import org .apache .hadoop .hbase .protobuf .generated .HBaseProtos .SnapshotDescription ;
4441import org .apache .hadoop .hbase .protobuf .generated .MasterProtos ;
45- import org .apache .hadoop .hbase .quotas .QuotaFilter ;
46- import org .apache .hadoop .hbase .quotas .QuotaRetriever ;
47- import org .apache .hadoop .hbase .quotas .QuotaSettings ;
48- import org .apache .hadoop .hbase .snapshot .HBaseSnapshotException ;
4942import org .apache .hadoop .hbase .snapshot .RestoreSnapshotException ;
5043import org .apache .hadoop .hbase .snapshot .SnapshotCreationException ;
51- import org .apache .hadoop .hbase .snapshot .UnknownSnapshotException ;
5244
5345/**
5446 * This is an hbase 1.x implementation of {@link AbstractBigtableAdmin}. Most methods in this class
5850 */
5951@ InternalApi ("For internal usage only" )
6052@ SuppressWarnings ("deprecation" )
61- public class BigtableAdmin extends AbstractBigtableAdmin {
53+ public abstract class BigtableAdmin extends AbstractBigtableAdmin {
6254
6355 public BigtableAdmin (CommonConnection connection ) throws IOException {
6456 super (connection );
@@ -83,32 +75,12 @@ public void disableTableAsync(TableName tableName) throws IOException {
8375 disableTable (tableName );
8476 }
8577
86- @ Override
87- public Map <ServerName , Boolean > compactionSwitch (boolean b , List <String > list )
88- throws IOException {
89- throw new UnsupportedOperationException ("not implemented" );
90- }
91-
9278 /** {@inheritDoc} */
9379 @ Override
9480 public void enableTableAsync (TableName tableName ) throws IOException {
9581 enableTable (tableName );
9682 }
9783
98- /** {@inheritDoc} */
99- @ Override
100- public AdminProtos .GetRegionInfoResponse .CompactionState getCompactionState (TableName tableName )
101- throws IOException {
102- throw new UnsupportedOperationException ("getCompactionState" );
103- }
104-
105- /** {@inheritDoc} */
106- @ Override
107- public AdminProtos .GetRegionInfoResponse .CompactionState getCompactionStateForRegion (byte [] bytes )
108- throws IOException {
109- throw new UnsupportedOperationException ("getCompactionStateForRegion" );
110- }
111-
11284 /**
11385 * {@inheritDoc}
11486 *
@@ -123,33 +95,13 @@ public void snapshot(
12395 snapshot (snapshotId , tableName );
12496 }
12597
126- @ Override
127- public void snapshot (
128- String s , TableName tableName , SnapshotDescription .Type type , Map <String , Object > map )
129- throws IOException , SnapshotCreationException , IllegalArgumentException {
130- throw new UnsupportedOperationException ("not implemented" );
131- }
132-
13398 /** {@inheritDoc} */
13499 @ Override
135100 public void snapshot (HBaseProtos .SnapshotDescription snapshot )
136101 throws IOException , SnapshotCreationException , IllegalArgumentException {
137102 snapshot (snapshot .getName (), TableName .valueOf (snapshot .getTable ()));
138103 }
139104
140- /** {@inheritDoc} */
141- @ Override
142- public boolean isSnapshotFinished (HBaseProtos .SnapshotDescription snapshot )
143- throws IOException , HBaseSnapshotException , UnknownSnapshotException {
144- throw new UnsupportedOperationException ("isSnapshotFinished" ); // TODO
145- }
146-
147- @ Override
148- public void restoreSnapshot (String s , boolean b , boolean b1 )
149- throws IOException , RestoreSnapshotException {
150- throw new UnsupportedOperationException ("restoreSnapshot" ); // TODO
151- }
152-
153105 @ Override
154106 public void cloneSnapshot (String s , TableName tableName , boolean b )
155107 throws IOException , TableExistsException , RestoreSnapshotException {
@@ -196,152 +148,6 @@ public List<HBaseProtos.SnapshotDescription> listSnapshots(Pattern pattern) thro
196148 return response ;
197149 }
198150
199- @ Override
200- public List <SnapshotDescription > listTableSnapshots (
201- String tableNameRegex , String snapshotNameRegex ) throws IOException {
202- throw new UnsupportedOperationException ("Unsupported - please use listSnapshots" );
203- }
204-
205- @ Override
206- public List <SnapshotDescription > listTableSnapshots (
207- Pattern tableNamePattern , Pattern snapshotNamePattern ) throws IOException {
208- throw new UnsupportedOperationException ("Unsupported - please use listSnapshots" );
209- }
210-
211- @ Override
212- public boolean isBalancerEnabled () throws IOException {
213- throw new UnsupportedOperationException ("isBalancerEnabled" ); // TODO
214- }
215-
216- @ Override
217- public long getLastMajorCompactionTimestamp (TableName tableName ) throws IOException {
218- throw new UnsupportedOperationException ("getLastMajorCompactionTimestamp" ); // TODO
219- }
220-
221- @ Override
222- public long getLastMajorCompactionTimestampForRegion (byte [] regionName ) throws IOException {
223- throw new UnsupportedOperationException ("getLastMajorCompactionTimestampForRegion" ); // TODO
224- }
225-
226- @ Override
227- public void setQuota (QuotaSettings quota ) throws IOException {
228- throw new UnsupportedOperationException ("setQuota" ); // TODO
229- }
230-
231- @ Override
232- public QuotaRetriever getQuotaRetriever (QuotaFilter filter ) throws IOException {
233- throw new UnsupportedOperationException ("getQuotaRetriever" ); // TODO
234- }
235-
236- @ Override
237- public ServerName getMaster () throws IOException {
238- throw new UnsupportedOperationException ("not implemented" );
239- }
240-
241- @ Override
242- public boolean normalize () throws IOException {
243- throw new UnsupportedOperationException ("normalize" ); // TODO
244- }
245-
246- @ Override
247- public boolean isNormalizerEnabled () throws IOException {
248- throw new UnsupportedOperationException ("isNormalizerEnabled" ); // TODO
249- }
250-
251- @ Override
252- public boolean setNormalizerRunning (boolean on ) throws IOException {
253- throw new UnsupportedOperationException ("setNormalizerRunning" ); // TODO
254- }
255-
256- @ Override
257- public boolean setCleanerChoreRunning (boolean b ) throws IOException {
258- throw new UnsupportedOperationException ("setCleanerChoreRunning" ); // TODO
259- }
260-
261- @ Override
262- public boolean runCleanerChore () throws IOException {
263- throw new UnsupportedOperationException ("runCleanerChore" ); // TODO
264- }
265-
266- @ Override
267- public boolean isCleanerChoreEnabled () throws IOException {
268- throw new UnsupportedOperationException ("isCleanerChoreEnabled" ); // TODO
269- }
270-
271- @ Override
272- public boolean isMasterInMaintenanceMode () throws IOException {
273- throw new UnsupportedOperationException ("isMasterInMaintenanceMode" ); // TODO
274- }
275-
276- @ Override
277- public boolean abortProcedure (long procId , boolean mayInterruptIfRunning ) throws IOException {
278- throw new UnsupportedOperationException ("abortProcedure" ); // TODO
279- }
280-
281- @ Override
282- public ProcedureInfo [] listProcedures () throws IOException {
283- throw new UnsupportedOperationException ("listProcedures" ); // TODO
284- }
285-
286- @ Override
287- public Future <Boolean > abortProcedureAsync (long procId , boolean mayInterruptIfRunning )
288- throws IOException {
289- throw new UnsupportedOperationException ("abortProcedureAsync" ); // TODO
290- }
291-
292- @ Override
293- public List <SecurityCapability > getSecurityCapabilities () throws IOException {
294- throw new UnsupportedOperationException ("getSecurityCapabilities" ); // TODO
295- }
296-
297- @ Override
298- public boolean balancer (boolean arg0 ) throws IOException {
299- throw new UnsupportedOperationException ("balancer" ); // TODO
300- }
301-
302- @ Override
303- public boolean isSplitOrMergeEnabled (MasterSwitchType arg0 ) throws IOException {
304- throw new UnsupportedOperationException ("isSplitOrMergeEnabled" ); // TODO
305- }
306-
307- @ Override
308- public List <ServerName > listDeadServers () throws IOException {
309- throw new UnsupportedOperationException ("listDeadServers" ); // TODO
310- }
311-
312- @ Override
313- public List <ServerName > clearDeadServers (List <ServerName > list ) throws IOException {
314- throw new UnsupportedOperationException ("clearDeadServers" ); // TODO
315- }
316-
317- @ Override
318- public boolean snapshotCleanupSwitch (boolean b , boolean b1 ) throws IOException {
319- throw new UnsupportedOperationException ("not implemented" );
320- }
321-
322- @ Override
323- public boolean isSnapshotCleanupEnabled () throws IOException {
324- throw new UnsupportedOperationException ("not implemented" );
325- }
326-
327- @ Override
328- public List <Boolean > clearSlowLogResponses (Set <ServerName > set ) throws IOException {
329- throw new UnsupportedOperationException ("not implemented" );
330- }
331-
332- @ Override
333- public List <LogEntry > getLogEntries (
334- Set <ServerName > set , String s , ServerType serverType , int i , Map <String , Object > map )
335- throws IOException {
336- throw new UnsupportedOperationException ("not implemented" );
337- }
338-
339- @ Override
340- public boolean [] setSplitOrMergeEnabled (boolean arg0 , boolean arg1 , MasterSwitchType ... arg2 )
341- throws IOException {
342- throw new UnsupportedOperationException ("setSplitOrMergeEnabled" ); // TODO
343- }
344-
345151 @ Override
346152 public ClusterStatus getClusterStatus () throws IOException {
347153 return new ClusterStatus () {
@@ -352,8 +158,43 @@ public Collection<ServerName> getServers() {
352158 };
353159 }
354160
355- @ Override
356- public String [] listNamespaces () throws IOException {
357- throw new UnsupportedOperationException ("not implemented" );
161+ private static Class <? extends BigtableAdmin > adminClass = null ;
162+
163+ /**
164+ * This is a workaround for incompatible changes in hbase minor versions. Dynamically generates a
165+ * class that extends BigtableAdmin so incompatible methods won't be accessed unless the methods
166+ * are called. If a method is implemented by BigtableAdmin, the generated class will invoke the
167+ * implementation in BigtableAdmin. Otherwise it'll throw {@link UnsupportedOperationException}.
168+ */
169+ private static synchronized Class <? extends BigtableAdmin > getSubclass () {
170+ if (adminClass == null ) {
171+ adminClass =
172+ new ByteBuddy ()
173+ .subclass (BigtableAdmin .class )
174+ .method (ElementMatchers .isAbstract ())
175+ .intercept (
176+ InvocationHandlerAdapter .of (
177+ new AbstractBigtableAdmin .UnsupportedOperationsHandler ()))
178+ .make ()
179+ .load (BigtableAdmin .class .getClassLoader ())
180+ .getLoaded ();
181+ }
182+ return adminClass ;
183+ }
184+
185+ public static Admin createInstance (CommonConnection connection ) throws IOException {
186+ try {
187+ return getSubclass ().getDeclaredConstructor (CommonConnection .class ).newInstance (connection );
188+ } catch (InvocationTargetException e ) {
189+ // Unwrap and throw IOException or RuntimeException as is, and convert all other exceptions to
190+ // IOException because
191+ // org.apache.hadoop.hbase.client.Connection#getAdmin() only throws
192+ // IOException
193+ Throwables .throwIfInstanceOf (e .getTargetException (), IOException .class );
194+ Throwables .throwIfInstanceOf (e .getTargetException (), RuntimeException .class );
195+ throw new IOException (e );
196+ } catch (Exception e ) {
197+ throw new IOException (e );
198+ }
358199 }
359200}
0 commit comments