1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase.master.procedure;
20
21 import java.io.IOException;
22 import java.io.InterruptedIOException;
23 import java.util.concurrent.CountDownLatch;
24
25 import org.apache.hadoop.hbase.classification.InterfaceAudience;
26 import org.apache.hadoop.hbase.classification.InterfaceStability;
27 import org.apache.hadoop.hbase.ipc.RpcServer;
28 import org.apache.hadoop.hbase.ipc.RpcCallContext;
29 import org.apache.hadoop.hbase.procedure2.Procedure;
30 import org.apache.hadoop.hbase.protobuf.generated.RPCProtos.VersionInfo;
31
32
33
34
35
36 @InterfaceAudience.Private
37 @InterfaceStability.Evolving
38 public abstract class ProcedurePrepareLatch {
39 private static final NoopLatch noopLatch = new NoopLatch();
40
41 public static ProcedurePrepareLatch createLatch() {
42
43 return hasProcedureSupport() ? noopLatch : new CompatibilityLatch();
44 }
45
46 public static boolean hasProcedureSupport() {
47 return currentClientHasMinimumVersion(1, 1);
48 }
49
50 private static boolean currentClientHasMinimumVersion(int major, int minor) {
51 RpcCallContext call = RpcServer.getCurrentCall();
52 VersionInfo versionInfo = call != null ? call.getClientVersionInfo() : null;
53 if (versionInfo != null) {
54 String[] components = versionInfo.getVersion().split("\\.");
55
56 int clientMajor = components.length > 0 ? Integer.parseInt(components[0]) : 0;
57 if (clientMajor != major) {
58 return clientMajor > major;
59 }
60
61 int clientMinor = components.length > 1 ? Integer.parseInt(components[1]) : 0;
62 return clientMinor >= minor;
63 }
64 return false;
65 }
66
67 protected abstract void countDown(final Procedure proc);
68 public abstract void await() throws IOException;
69
70 protected static void releaseLatch(final ProcedurePrepareLatch latch, final Procedure proc) {
71 if (latch != null) {
72 latch.countDown(proc);
73 }
74 }
75
76 private static class NoopLatch extends ProcedurePrepareLatch {
77 protected void countDown(final Procedure proc) {}
78 public void await() throws IOException {}
79 }
80
81 protected static class CompatibilityLatch extends ProcedurePrepareLatch {
82 private final CountDownLatch latch = new CountDownLatch(1);
83
84 private IOException exception = null;
85
86 protected void countDown(final Procedure proc) {
87 if (proc.hasException()) {
88 exception = proc.getException().unwrapRemoteException();
89 }
90 latch.countDown();
91 }
92
93 public void await() throws IOException {
94 try {
95 latch.await();
96 } catch (InterruptedException e) {
97 throw (InterruptedIOException)new InterruptedIOException().initCause(e);
98 }
99
100 if (exception != null) {
101 throw exception;
102 }
103 }
104 }
105 }