1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.hadoop.hbase.zookeeper;
19
20 import org.apache.hadoop.hbase.classification.InterfaceAudience;
21 import org.apache.hadoop.hbase.Abortable;
22 import org.apache.hadoop.hbase.HConstants;
23 import org.apache.hadoop.hbase.ServerName;
24 import org.apache.hadoop.hbase.exceptions.DeserializationException;
25 import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
26 import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos;
27 import org.apache.hadoop.hbase.protobuf.generated.ZooKeeperProtos;
28 import org.apache.zookeeper.KeeperException;
29 import org.apache.zookeeper.data.Stat;
30
31 import java.io.IOException;
32 import java.io.InterruptedIOException;
33 import com.google.protobuf.InvalidProtocolBufferException;
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53 @InterfaceAudience.Private
54 public class MasterAddressTracker extends ZooKeeperNodeTracker {
55
56
57
58
59
60
61
62
63
64
65
66 public MasterAddressTracker(ZooKeeperWatcher watcher, Abortable abortable) {
67 super(watcher, watcher.getMasterAddressZNode(), abortable);
68 }
69
70
71
72
73
74
75 public ServerName getMasterAddress() {
76 return getMasterAddress(false);
77 }
78
79
80
81
82
83
84 public int getMasterInfoPort() {
85 try {
86 return parse(this.getData(false)).getInfoPort();
87 } catch (DeserializationException e) {
88 LOG.warn("Failed parse master zk node data", e);
89 return 0;
90 }
91 }
92
93
94
95
96
97
98 public int getBackupMasterInfoPort(final ServerName sn) {
99 String backupZNode = ZKUtil.joinZNode(watcher.backupMasterAddressesZNode, sn.toString());
100 try {
101 byte[] data = ZKUtil.getData(watcher, backupZNode);
102 return parse(data).getInfoPort();
103 } catch (Exception e) {
104 LOG.warn("Failed to get backup master: " + sn + "'s info port.", e);
105 return 0;
106 }
107 }
108
109
110
111
112
113
114
115
116
117 public ServerName getMasterAddress(final boolean refresh) {
118 try {
119 return ServerName.parseFrom(super.getData(refresh));
120 } catch (DeserializationException e) {
121 LOG.warn("Failed parse", e);
122 return null;
123 }
124 }
125
126
127
128
129
130
131
132
133
134
135
136 public static ServerName getMasterAddress(final ZooKeeperWatcher zkw)
137 throws KeeperException, IOException {
138 byte [] data;
139 try {
140 data = ZKUtil.getData(zkw, zkw.getMasterAddressZNode());
141 } catch (InterruptedException e) {
142 throw new InterruptedIOException();
143 }
144 if (data == null){
145 throw new IOException("Can't get master address from ZooKeeper; znode data == null");
146 }
147 try {
148 return ServerName.parseFrom(data);
149 } catch (DeserializationException e) {
150 KeeperException ke = new KeeperException.DataInconsistencyException();
151 ke.initCause(e);
152 throw ke;
153 }
154 }
155
156
157
158
159
160
161
162
163
164
165
166 public static int getMasterInfoPort(final ZooKeeperWatcher zkw) throws KeeperException,
167 IOException {
168 byte[] data;
169 try {
170 data = ZKUtil.getData(zkw, zkw.getMasterAddressZNode());
171 } catch (InterruptedException e) {
172 throw new InterruptedIOException();
173 }
174 if (data == null) {
175 throw new IOException("Can't get master address from ZooKeeper; znode data == null");
176 }
177 try {
178 return parse(data).getInfoPort();
179 } catch (DeserializationException e) {
180 KeeperException ke = new KeeperException.DataInconsistencyException();
181 ke.initCause(e);
182 throw ke;
183 }
184 }
185
186
187
188
189
190
191
192
193
194
195
196
197 public static boolean setMasterAddress(final ZooKeeperWatcher zkw,
198 final String znode, final ServerName master, int infoPort)
199 throws KeeperException {
200 return ZKUtil.createEphemeralNodeAndWatch(zkw, znode, toByteArray(master, infoPort));
201 }
202
203
204
205
206
207 public boolean hasMaster() {
208 return super.getData(false) != null;
209 }
210
211
212
213
214
215
216 static byte[] toByteArray(final ServerName sn, int infoPort) {
217 ZooKeeperProtos.Master.Builder mbuilder = ZooKeeperProtos.Master.newBuilder();
218 HBaseProtos.ServerName.Builder snbuilder = HBaseProtos.ServerName.newBuilder();
219 snbuilder.setHostName(sn.getHostname());
220 snbuilder.setPort(sn.getPort());
221 snbuilder.setStartCode(sn.getStartcode());
222 mbuilder.setMaster(snbuilder.build());
223 mbuilder.setRpcVersion(HConstants.RPC_CURRENT_VERSION);
224 mbuilder.setInfoPort(infoPort);
225 return ProtobufUtil.prependPBMagic(mbuilder.build().toByteArray());
226 }
227
228
229
230
231
232
233 public static ZooKeeperProtos.Master parse(byte[] data) throws DeserializationException {
234 int prefixLen = ProtobufUtil.lengthOfPBMagic();
235 try {
236 return ZooKeeperProtos.Master.PARSER.parseFrom(data, prefixLen, data.length - prefixLen);
237 } catch (InvalidProtocolBufferException e) {
238 throw new DeserializationException(e);
239 }
240 }
241
242
243
244 public static boolean deleteIfEquals(ZooKeeperWatcher zkw, final String content) {
245 if (content == null){
246 throw new IllegalArgumentException("Content must not be null");
247 }
248
249 try {
250 Stat stat = new Stat();
251 byte[] data = ZKUtil.getDataNoWatch(zkw, zkw.getMasterAddressZNode(), stat);
252 ServerName sn = ServerName.parseFrom(data);
253 if (sn != null && content.equals(sn.toString())) {
254 return (ZKUtil.deleteNode(zkw, zkw.getMasterAddressZNode(), stat.getVersion()));
255 }
256 } catch (KeeperException e) {
257 LOG.warn("Can't get or delete the master znode", e);
258 } catch (DeserializationException e) {
259 LOG.warn("Can't get or delete the master znode", e);
260 }
261
262 return false;
263 }
264 }