1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase.zookeeper;
20
21 import java.io.BufferedReader;
22 import java.io.IOException;
23 import java.io.InputStreamReader;
24 import java.io.PrintWriter;
25 import java.net.InetSocketAddress;
26 import java.net.Socket;
27 import java.util.ArrayList;
28 import java.util.Arrays;
29 import java.util.HashMap;
30 import java.util.LinkedList;
31 import java.util.List;
32 import java.util.Map;
33 import java.util.Properties;
34
35 import javax.security.auth.login.AppConfigurationEntry;
36 import javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag;
37
38 import org.apache.hadoop.hbase.util.ByteStringer;
39 import org.apache.commons.lang.StringUtils;
40 import org.apache.commons.logging.Log;
41 import org.apache.commons.logging.LogFactory;
42 import org.apache.hadoop.hbase.classification.InterfaceAudience;
43 import org.apache.hadoop.conf.Configuration;
44 import org.apache.hadoop.hbase.HConstants;
45 import org.apache.hadoop.hbase.ServerName;
46 import org.apache.hadoop.hbase.exceptions.DeserializationException;
47 import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
48 import org.apache.hadoop.hbase.protobuf.generated.ZooKeeperProtos;
49 import org.apache.hadoop.hbase.protobuf.generated.ZooKeeperProtos.RegionStoreSequenceIds;
50 import org.apache.hadoop.hbase.util.Bytes;
51 import org.apache.hadoop.hbase.util.Threads;
52 import org.apache.hadoop.hbase.zookeeper.ZKUtil.ZKUtilOp.CreateAndFailSilent;
53 import org.apache.hadoop.hbase.zookeeper.ZKUtil.ZKUtilOp.DeleteNodeFailSilent;
54 import org.apache.hadoop.hbase.zookeeper.ZKUtil.ZKUtilOp.SetData;
55 import org.apache.hadoop.security.SecurityUtil;
56 import org.apache.hadoop.security.authentication.util.KerberosUtil;
57 import org.apache.zookeeper.AsyncCallback;
58 import org.apache.zookeeper.CreateMode;
59 import org.apache.zookeeper.KeeperException;
60 import org.apache.zookeeper.KeeperException.NoNodeException;
61 import org.apache.zookeeper.Op;
62 import org.apache.zookeeper.Watcher;
63 import org.apache.zookeeper.ZooDefs.Ids;
64 import org.apache.zookeeper.ZooDefs.Perms;
65 import org.apache.zookeeper.ZooKeeper;
66 import org.apache.zookeeper.client.ZooKeeperSaslClient;
67 import org.apache.zookeeper.data.ACL;
68 import org.apache.zookeeper.data.Id;
69 import org.apache.zookeeper.data.Stat;
70 import org.apache.zookeeper.proto.CreateRequest;
71 import org.apache.zookeeper.proto.DeleteRequest;
72 import org.apache.zookeeper.proto.SetDataRequest;
73 import org.apache.zookeeper.server.ZooKeeperSaslServer;
74
75 import com.google.protobuf.InvalidProtocolBufferException;
76
77
78
79
80
81
82
83
84
85
86 @InterfaceAudience.Private
87 public class ZKUtil {
88 private static final Log LOG = LogFactory.getLog(ZKUtil.class);
89
90
91 public static final char ZNODE_PATH_SEPARATOR = '/';
92 private static int zkDumpConnectionTimeOut;
93
94
95
96
97
98
99
100
101
102
103
104
105 public static RecoverableZooKeeper connect(Configuration conf, Watcher watcher)
106 throws IOException {
107 Properties properties = ZKConfig.makeZKProps(conf);
108 String ensemble = ZKConfig.getZKQuorumServersString(properties);
109 return connect(conf, ensemble, watcher);
110 }
111
112 public static RecoverableZooKeeper connect(Configuration conf, String ensemble,
113 Watcher watcher)
114 throws IOException {
115 return connect(conf, ensemble, watcher, null);
116 }
117
118 public static RecoverableZooKeeper connect(Configuration conf, String ensemble,
119 Watcher watcher, final String identifier)
120 throws IOException {
121 if(ensemble == null) {
122 throw new IOException("Unable to determine ZooKeeper ensemble");
123 }
124 int timeout = conf.getInt(HConstants.ZK_SESSION_TIMEOUT,
125 HConstants.DEFAULT_ZK_SESSION_TIMEOUT);
126 if (LOG.isTraceEnabled()) {
127 LOG.trace(identifier + " opening connection to ZooKeeper ensemble=" + ensemble);
128 }
129 int retry = conf.getInt("zookeeper.recovery.retry", 3);
130 int retryIntervalMillis =
131 conf.getInt("zookeeper.recovery.retry.intervalmill", 1000);
132 zkDumpConnectionTimeOut = conf.getInt("zookeeper.dump.connection.timeout",
133 1000);
134 return new RecoverableZooKeeper(ensemble, timeout, watcher,
135 retry, retryIntervalMillis, identifier);
136 }
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152 public static void loginServer(Configuration conf, String keytabFileKey,
153 String userNameKey, String hostname) throws IOException {
154 login(conf, keytabFileKey, userNameKey, hostname,
155 ZooKeeperSaslServer.LOGIN_CONTEXT_NAME_KEY,
156 JaasConfiguration.SERVER_KEYTAB_KERBEROS_CONFIG_NAME);
157 }
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173 public static void loginClient(Configuration conf, String keytabFileKey,
174 String userNameKey, String hostname) throws IOException {
175 login(conf, keytabFileKey, userNameKey, hostname,
176 ZooKeeperSaslClient.LOGIN_CONTEXT_NAME_KEY,
177 JaasConfiguration.CLIENT_KEYTAB_KERBEROS_CONFIG_NAME);
178 }
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196 private static void login(Configuration conf, String keytabFileKey,
197 String userNameKey, String hostname,
198 String loginContextProperty, String loginContextName)
199 throws IOException {
200 if (!isSecureZooKeeper(conf))
201 return;
202
203
204
205 if (System.getProperty("java.security.auth.login.config") != null)
206 return;
207
208
209 String keytabFilename = conf.get(keytabFileKey);
210 if (keytabFilename == null) {
211 LOG.warn("no keytab specified for: " + keytabFileKey);
212 return;
213 }
214
215 String principalConfig = conf.get(userNameKey, System.getProperty("user.name"));
216 String principalName = SecurityUtil.getServerPrincipal(principalConfig, hostname);
217
218
219
220
221 JaasConfiguration jaasConf = new JaasConfiguration(loginContextName,
222 principalName, keytabFilename);
223 javax.security.auth.login.Configuration.setConfiguration(jaasConf);
224 System.setProperty(loginContextProperty, loginContextName);
225 }
226
227
228
229
230 private static class JaasConfiguration extends javax.security.auth.login.Configuration {
231 private static final String SERVER_KEYTAB_KERBEROS_CONFIG_NAME =
232 "zookeeper-server-keytab-kerberos";
233 private static final String CLIENT_KEYTAB_KERBEROS_CONFIG_NAME =
234 "zookeeper-client-keytab-kerberos";
235
236 private static final Map<String, String> BASIC_JAAS_OPTIONS =
237 new HashMap<String,String>();
238 static {
239 String jaasEnvVar = System.getenv("HBASE_JAAS_DEBUG");
240 if (jaasEnvVar != null && "true".equalsIgnoreCase(jaasEnvVar)) {
241 BASIC_JAAS_OPTIONS.put("debug", "true");
242 }
243 }
244
245 private static final Map<String,String> KEYTAB_KERBEROS_OPTIONS =
246 new HashMap<String,String>();
247 static {
248 KEYTAB_KERBEROS_OPTIONS.put("doNotPrompt", "true");
249 KEYTAB_KERBEROS_OPTIONS.put("storeKey", "true");
250 KEYTAB_KERBEROS_OPTIONS.put("refreshKrb5Config", "true");
251 KEYTAB_KERBEROS_OPTIONS.putAll(BASIC_JAAS_OPTIONS);
252 }
253
254 private static final AppConfigurationEntry KEYTAB_KERBEROS_LOGIN =
255 new AppConfigurationEntry(KerberosUtil.getKrb5LoginModuleName(),
256 LoginModuleControlFlag.REQUIRED,
257 KEYTAB_KERBEROS_OPTIONS);
258
259 private static final AppConfigurationEntry[] KEYTAB_KERBEROS_CONF =
260 new AppConfigurationEntry[]{KEYTAB_KERBEROS_LOGIN};
261
262 private javax.security.auth.login.Configuration baseConfig;
263 private final String loginContextName;
264 private final boolean useTicketCache;
265 private final String keytabFile;
266 private final String principal;
267
268 public JaasConfiguration(String loginContextName, String principal) {
269 this(loginContextName, principal, null, true);
270 }
271
272 public JaasConfiguration(String loginContextName, String principal, String keytabFile) {
273 this(loginContextName, principal, keytabFile, keytabFile == null || keytabFile.length() == 0);
274 }
275
276 private JaasConfiguration(String loginContextName, String principal,
277 String keytabFile, boolean useTicketCache) {
278 try {
279 this.baseConfig = javax.security.auth.login.Configuration.getConfiguration();
280 } catch (SecurityException e) {
281 this.baseConfig = null;
282 }
283 this.loginContextName = loginContextName;
284 this.useTicketCache = useTicketCache;
285 this.keytabFile = keytabFile;
286 this.principal = principal;
287 LOG.info("JaasConfiguration loginContextName=" + loginContextName +
288 " principal=" + principal + " useTicketCache=" + useTicketCache +
289 " keytabFile=" + keytabFile);
290 }
291
292 @Override
293 public AppConfigurationEntry[] getAppConfigurationEntry(String appName) {
294 if (loginContextName.equals(appName)) {
295 if (!useTicketCache) {
296 KEYTAB_KERBEROS_OPTIONS.put("keyTab", keytabFile);
297 KEYTAB_KERBEROS_OPTIONS.put("useKeyTab", "true");
298 }
299 KEYTAB_KERBEROS_OPTIONS.put("principal", principal);
300 KEYTAB_KERBEROS_OPTIONS.put("useTicketCache", useTicketCache ? "true" : "false");
301 return KEYTAB_KERBEROS_CONF;
302 }
303 if (baseConfig != null) return baseConfig.getAppConfigurationEntry(appName);
304 return(null);
305 }
306 }
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322 public static String joinZNode(String prefix, String suffix) {
323 return prefix + ZNODE_PATH_SEPARATOR + suffix;
324 }
325
326
327
328
329
330
331 public static String getParent(String node) {
332 int idx = node.lastIndexOf(ZNODE_PATH_SEPARATOR);
333 return idx <= 0 ? null : node.substring(0, idx);
334 }
335
336
337
338
339
340
341 public static String getNodeName(String path) {
342 return path.substring(path.lastIndexOf("/")+1);
343 }
344
345
346
347
348
349
350
351 public static String getZooKeeperClusterKey(Configuration conf) {
352 return getZooKeeperClusterKey(conf, null);
353 }
354
355
356
357
358
359
360
361
362 public static String getZooKeeperClusterKey(Configuration conf, String name) {
363 String ensemble = conf.get(HConstants.ZOOKEEPER_QUORUM.replaceAll(
364 "[\\t\\n\\x0B\\f\\r]", ""));
365 StringBuilder builder = new StringBuilder(ensemble);
366 builder.append(":");
367 builder.append(conf.get(HConstants.ZOOKEEPER_CLIENT_PORT));
368 builder.append(":");
369 builder.append(conf.get(HConstants.ZOOKEEPER_ZNODE_PARENT));
370 if (name != null && !name.isEmpty()) {
371 builder.append(",");
372 builder.append(name);
373 }
374 return builder.toString();
375 }
376
377
378
379
380
381
382
383
384 public static void applyClusterKeyToConf(Configuration conf, String key)
385 throws IOException{
386 String[] parts = transformClusterKey(key);
387 conf.set(HConstants.ZOOKEEPER_QUORUM, parts[0]);
388 conf.set(HConstants.ZOOKEEPER_CLIENT_PORT, parts[1]);
389 conf.set(HConstants.ZOOKEEPER_ZNODE_PARENT, parts[2]);
390 }
391
392
393
394
395
396
397
398
399
400 public static String[] transformClusterKey(String key) throws IOException {
401 String[] parts = key.split(":");
402 if (parts.length != 3) {
403 throw new IOException("Cluster key passed " + key + " is invalid, the format should be:" +
404 HConstants.ZOOKEEPER_QUORUM + ":hbase.zookeeper.client.port:"
405 + HConstants.ZOOKEEPER_ZNODE_PARENT);
406 }
407 return parts;
408 }
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424 public static boolean watchAndCheckExists(ZooKeeperWatcher zkw, String znode)
425 throws KeeperException {
426 try {
427 Stat s = zkw.getRecoverableZooKeeper().exists(znode, zkw);
428 boolean exists = s != null ? true : false;
429 if (exists) {
430 LOG.debug(zkw.prefix("Set watcher on existing znode=" + znode));
431 } else {
432 LOG.debug(zkw.prefix("Set watcher on znode that does not yet exist, " + znode));
433 }
434 return exists;
435 } catch (KeeperException e) {
436 LOG.warn(zkw.prefix("Unable to set watcher on znode " + znode), e);
437 zkw.keeperException(e);
438 return false;
439 } catch (InterruptedException e) {
440 LOG.warn(zkw.prefix("Unable to set watcher on znode " + znode), e);
441 zkw.interruptedException(e);
442 return false;
443 }
444 }
445
446
447
448
449
450
451
452
453
454
455
456 public static boolean setWatchIfNodeExists(ZooKeeperWatcher zkw, String znode)
457 throws KeeperException {
458 try {
459 zkw.getRecoverableZooKeeper().getData(znode, true, null);
460 return true;
461 } catch (NoNodeException e) {
462 return false;
463 } catch (InterruptedException e) {
464 LOG.warn(zkw.prefix("Unable to set watcher on znode " + znode), e);
465 zkw.interruptedException(e);
466 return false;
467 }
468 }
469
470
471
472
473
474
475
476
477
478 public static int checkExists(ZooKeeperWatcher zkw, String znode)
479 throws KeeperException {
480 try {
481 Stat s = zkw.getRecoverableZooKeeper().exists(znode, null);
482 return s != null ? s.getVersion() : -1;
483 } catch (KeeperException e) {
484 LOG.warn(zkw.prefix("Unable to set watcher on znode (" + znode + ")"), e);
485 zkw.keeperException(e);
486 return -1;
487 } catch (InterruptedException e) {
488 LOG.warn(zkw.prefix("Unable to set watcher on znode (" + znode + ")"), e);
489 zkw.interruptedException(e);
490 return -1;
491 }
492 }
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514 public static List<String> listChildrenAndWatchForNewChildren(
515 ZooKeeperWatcher zkw, String znode)
516 throws KeeperException {
517 try {
518 List<String> children = zkw.getRecoverableZooKeeper().getChildren(znode, zkw);
519 return children;
520 } catch(KeeperException.NoNodeException ke) {
521 LOG.debug(zkw.prefix("Unable to list children of znode " + znode + " " +
522 "because node does not exist (not an error)"));
523 return null;
524 } catch (KeeperException e) {
525 LOG.warn(zkw.prefix("Unable to list children of znode " + znode + " "), e);
526 zkw.keeperException(e);
527 return null;
528 } catch (InterruptedException e) {
529 LOG.warn(zkw.prefix("Unable to list children of znode " + znode + " "), e);
530 zkw.interruptedException(e);
531 return null;
532 }
533 }
534
535
536
537
538
539
540
541
542
543
544 public static List<String> listChildrenAndWatchThem(ZooKeeperWatcher zkw,
545 String znode) throws KeeperException {
546 List<String> children = listChildrenAndWatchForNewChildren(zkw, znode);
547 if (children == null) {
548 return null;
549 }
550 for (String child : children) {
551 watchAndCheckExists(zkw, joinZNode(znode, child));
552 }
553 return children;
554 }
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570 public static List<String> listChildrenNoWatch(ZooKeeperWatcher zkw, String znode)
571 throws KeeperException {
572 List<String> children = null;
573 try {
574
575 children = zkw.getRecoverableZooKeeper().getChildren(znode, null);
576 } catch(KeeperException.NoNodeException nne) {
577 return null;
578 } catch(InterruptedException ie) {
579 zkw.interruptedException(ie);
580 }
581 return children;
582 }
583
584
585
586
587
588 @Deprecated
589 public static class NodeAndData {
590 private String node;
591 private byte [] data;
592 public NodeAndData(String node, byte [] data) {
593 this.node = node;
594 this.data = data;
595 }
596 public String getNode() {
597 return node;
598 }
599 public byte [] getData() {
600 return data;
601 }
602 @Override
603 public String toString() {
604 return node;
605 }
606 public boolean isEmpty() {
607 return (data.length == 0);
608 }
609 }
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627 public static boolean nodeHasChildren(ZooKeeperWatcher zkw, String znode)
628 throws KeeperException {
629 try {
630 return !zkw.getRecoverableZooKeeper().getChildren(znode, null).isEmpty();
631 } catch(KeeperException.NoNodeException ke) {
632 LOG.debug(zkw.prefix("Unable to list children of znode " + znode + " " +
633 "because node does not exist (not an error)"));
634 return false;
635 } catch (KeeperException e) {
636 LOG.warn(zkw.prefix("Unable to list children of znode " + znode), e);
637 zkw.keeperException(e);
638 return false;
639 } catch (InterruptedException e) {
640 LOG.warn(zkw.prefix("Unable to list children of znode " + znode), e);
641 zkw.interruptedException(e);
642 return false;
643 }
644 }
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659 public static int getNumberOfChildren(ZooKeeperWatcher zkw, String znode)
660 throws KeeperException {
661 try {
662 Stat stat = zkw.getRecoverableZooKeeper().exists(znode, null);
663 return stat == null ? 0 : stat.getNumChildren();
664 } catch(KeeperException e) {
665 LOG.warn(zkw.prefix("Unable to get children of node " + znode));
666 zkw.keeperException(e);
667 } catch(InterruptedException e) {
668 zkw.interruptedException(e);
669 }
670 return 0;
671 }
672
673
674
675
676
677
678
679
680
681
682 public static byte [] getData(ZooKeeperWatcher zkw, String znode)
683 throws KeeperException {
684 try {
685 byte [] data = zkw.getRecoverableZooKeeper().getData(znode, null, null);
686 logRetrievedMsg(zkw, znode, data, false);
687 return data;
688 } catch (KeeperException.NoNodeException e) {
689 LOG.debug(zkw.prefix("Unable to get data of znode " + znode + " " +
690 "because node does not exist (not an error)"));
691 return null;
692 } catch (KeeperException e) {
693 LOG.warn(zkw.prefix("Unable to get data of znode " + znode), e);
694 zkw.keeperException(e);
695 return null;
696 } catch (InterruptedException e) {
697 LOG.warn(zkw.prefix("Unable to get data of znode " + znode), e);
698 zkw.interruptedException(e);
699 return null;
700 }
701 }
702
703
704
705
706
707
708
709
710
711
712
713
714 public static byte [] getDataAndWatch(ZooKeeperWatcher zkw, String znode)
715 throws KeeperException {
716 return getDataInternal(zkw, znode, null, true);
717 }
718
719
720
721
722
723
724
725
726
727
728
729
730
731 public static byte[] getDataAndWatch(ZooKeeperWatcher zkw, String znode,
732 Stat stat) throws KeeperException {
733 return getDataInternal(zkw, znode, stat, true);
734 }
735
736 private static byte[] getDataInternal(ZooKeeperWatcher zkw, String znode, Stat stat,
737 boolean watcherSet)
738 throws KeeperException {
739 try {
740 byte [] data = zkw.getRecoverableZooKeeper().getData(znode, zkw, stat);
741 logRetrievedMsg(zkw, znode, data, watcherSet);
742 return data;
743 } catch (KeeperException.NoNodeException e) {
744
745
746 LOG.trace(zkw.prefix("Unable to get data of znode " + znode + " " +
747 "because node does not exist (not an error)"));
748 return null;
749 } catch (KeeperException e) {
750 LOG.warn(zkw.prefix("Unable to get data of znode " + znode), e);
751 zkw.keeperException(e);
752 return null;
753 } catch (InterruptedException e) {
754 LOG.warn(zkw.prefix("Unable to get data of znode " + znode), e);
755 zkw.interruptedException(e);
756 return null;
757 }
758 }
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775 public static byte [] getDataNoWatch(ZooKeeperWatcher zkw, String znode,
776 Stat stat)
777 throws KeeperException {
778 try {
779 byte [] data = zkw.getRecoverableZooKeeper().getData(znode, null, stat);
780 logRetrievedMsg(zkw, znode, data, false);
781 return data;
782 } catch (KeeperException.NoNodeException e) {
783 LOG.debug(zkw.prefix("Unable to get data of znode " + znode + " " +
784 "because node does not exist (not necessarily an error)"));
785 return null;
786 } catch (KeeperException e) {
787 LOG.warn(zkw.prefix("Unable to get data of znode " + znode), e);
788 zkw.keeperException(e);
789 return null;
790 } catch (InterruptedException e) {
791 LOG.warn(zkw.prefix("Unable to get data of znode " + znode), e);
792 zkw.interruptedException(e);
793 return null;
794 }
795 }
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814 public static List<NodeAndData> getChildDataAndWatchForNewChildren(
815 ZooKeeperWatcher zkw, String baseNode) throws KeeperException {
816 List<String> nodes =
817 ZKUtil.listChildrenAndWatchForNewChildren(zkw, baseNode);
818 List<NodeAndData> newNodes = new ArrayList<NodeAndData>();
819 if (nodes != null) {
820 for (String node : nodes) {
821 String nodePath = ZKUtil.joinZNode(baseNode, node);
822 byte[] data = ZKUtil.getDataAndWatch(zkw, nodePath);
823 newNodes.add(new NodeAndData(nodePath, data));
824 }
825 }
826 return newNodes;
827 }
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845 public static void updateExistingNodeData(ZooKeeperWatcher zkw, String znode,
846 byte [] data, int expectedVersion)
847 throws KeeperException {
848 try {
849 zkw.getRecoverableZooKeeper().setData(znode, data, expectedVersion);
850 } catch(InterruptedException ie) {
851 zkw.interruptedException(ie);
852 }
853 }
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879 public static boolean setData(ZooKeeperWatcher zkw, String znode,
880 byte [] data, int expectedVersion)
881 throws KeeperException, KeeperException.NoNodeException {
882 try {
883 return zkw.getRecoverableZooKeeper().setData(znode, data, expectedVersion) != null;
884 } catch (InterruptedException e) {
885 zkw.interruptedException(e);
886 return false;
887 }
888 }
889
890
891
892
893
894
895
896
897
898
899 public static void createSetData(final ZooKeeperWatcher zkw, final String znode,
900 final byte [] data)
901 throws KeeperException {
902 if (checkExists(zkw, znode) == -1) {
903 ZKUtil.createWithParents(zkw, znode, data);
904 } else {
905 ZKUtil.setData(zkw, znode, data);
906 }
907 }
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925 public static void setData(ZooKeeperWatcher zkw, String znode, byte [] data)
926 throws KeeperException, KeeperException.NoNodeException {
927 setData(zkw, (SetData)ZKUtilOp.setData(znode, data));
928 }
929
930 private static void setData(ZooKeeperWatcher zkw, SetData setData)
931 throws KeeperException, KeeperException.NoNodeException {
932 SetDataRequest sd = (SetDataRequest)toZooKeeperOp(zkw, setData).toRequestRecord();
933 setData(zkw, sd.getPath(), sd.getData(), sd.getVersion());
934 }
935
936
937
938
939
940
941 public static boolean isSecureZooKeeper(Configuration conf) {
942
943
944 try {
945 javax.security.auth.login.Configuration testConfig =
946 javax.security.auth.login.Configuration.getConfiguration();
947 if (testConfig.getAppConfigurationEntry("Client") == null
948 && testConfig.getAppConfigurationEntry(
949 JaasConfiguration.CLIENT_KEYTAB_KERBEROS_CONFIG_NAME) == null
950 && testConfig.getAppConfigurationEntry(
951 JaasConfiguration.SERVER_KEYTAB_KERBEROS_CONFIG_NAME) == null) {
952 return false;
953 }
954 } catch(Exception e) {
955
956 return false;
957 }
958
959
960 return "kerberos".equalsIgnoreCase(conf.get("hbase.security.authentication"));
961 }
962
963 private static ArrayList<ACL> createACL(ZooKeeperWatcher zkw, String node) {
964 return createACL(zkw, node, isSecureZooKeeper(zkw.getConfiguration()));
965 }
966
967 public static ArrayList<ACL> createACL(ZooKeeperWatcher zkw, String node,
968 boolean isSecureZooKeeper) {
969 if (!node.startsWith(zkw.baseZNode)) {
970 return Ids.OPEN_ACL_UNSAFE;
971 }
972 if (isSecureZooKeeper) {
973 String superUser = zkw.getConfiguration().get("hbase.superuser");
974 ArrayList<ACL> acls = new ArrayList<ACL>();
975
976 if (superUser != null) {
977 acls.add(new ACL(Perms.ALL, new Id("auth", superUser)));
978 }
979
980
981 if (zkw.isClientReadable(node)) {
982 acls.addAll(Ids.CREATOR_ALL_ACL);
983 acls.addAll(Ids.READ_ACL_UNSAFE);
984 } else {
985 acls.addAll(Ids.CREATOR_ALL_ACL);
986 }
987 return acls;
988 } else {
989 return Ids.OPEN_ACL_UNSAFE;
990 }
991 }
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015 public static boolean createEphemeralNodeAndWatch(ZooKeeperWatcher zkw,
1016 String znode, byte [] data)
1017 throws KeeperException {
1018 boolean ret = true;
1019 try {
1020 zkw.getRecoverableZooKeeper().create(znode, data, createACL(zkw, znode),
1021 CreateMode.EPHEMERAL);
1022 } catch (KeeperException.NodeExistsException nee) {
1023 ret = false;
1024 } catch (InterruptedException e) {
1025 LOG.info("Interrupted", e);
1026 Thread.currentThread().interrupt();
1027 }
1028 if(!watchAndCheckExists(zkw, znode)) {
1029
1030 return createEphemeralNodeAndWatch(zkw, znode, data);
1031 }
1032 return ret;
1033 }
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055 public static boolean createNodeIfNotExistsAndWatch(
1056 ZooKeeperWatcher zkw, String znode, byte [] data)
1057 throws KeeperException {
1058 boolean ret = true;
1059 try {
1060 zkw.getRecoverableZooKeeper().create(znode, data, createACL(zkw, znode),
1061 CreateMode.PERSISTENT);
1062 } catch (KeeperException.NodeExistsException nee) {
1063 ret = false;
1064 } catch (InterruptedException e) {
1065 zkw.interruptedException(e);
1066 return false;
1067 }
1068 try {
1069 zkw.getRecoverableZooKeeper().exists(znode, zkw);
1070 } catch (InterruptedException e) {
1071 zkw.interruptedException(e);
1072 return false;
1073 }
1074 return ret;
1075 }
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091 public static String createNodeIfNotExistsNoWatch(ZooKeeperWatcher zkw, String znode,
1092 byte[] data, CreateMode createMode) throws KeeperException {
1093
1094 String createdZNode = null;
1095 try {
1096 createdZNode = zkw.getRecoverableZooKeeper().create(znode, data,
1097 createACL(zkw, znode), createMode);
1098 } catch (KeeperException.NodeExistsException nee) {
1099 return znode;
1100 } catch (InterruptedException e) {
1101 zkw.interruptedException(e);
1102 return null;
1103 }
1104 return createdZNode;
1105 }
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123 public static int createAndWatch(ZooKeeperWatcher zkw,
1124 String znode, byte [] data)
1125 throws KeeperException, KeeperException.NodeExistsException {
1126 try {
1127 zkw.getRecoverableZooKeeper().create(znode, data, createACL(zkw, znode),
1128 CreateMode.PERSISTENT);
1129 Stat stat = zkw.getRecoverableZooKeeper().exists(znode, zkw);
1130 if (stat == null){
1131
1132 throw KeeperException.create(KeeperException.Code.SYSTEMERROR,
1133 "ZK.exists returned null (i.e.: znode does not exist) for znode=" + znode);
1134 }
1135 return stat.getVersion();
1136 } catch (InterruptedException e) {
1137 zkw.interruptedException(e);
1138 return -1;
1139 }
1140 }
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157 public static void asyncCreate(ZooKeeperWatcher zkw,
1158 String znode, byte [] data, final AsyncCallback.StringCallback cb,
1159 final Object ctx) {
1160 zkw.getRecoverableZooKeeper().getZooKeeper().create(znode, data,
1161 createACL(zkw, znode), CreateMode.PERSISTENT, cb, ctx);
1162 }
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174 public static void createAndFailSilent(ZooKeeperWatcher zkw,
1175 String znode) throws KeeperException {
1176 createAndFailSilent(zkw, znode, new byte[0]);
1177 }
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190 public static void createAndFailSilent(ZooKeeperWatcher zkw,
1191 String znode, byte[] data)
1192 throws KeeperException {
1193 createAndFailSilent(zkw,
1194 (CreateAndFailSilent)ZKUtilOp.createAndFailSilent(znode, data));
1195 }
1196
1197 private static void createAndFailSilent(ZooKeeperWatcher zkw, CreateAndFailSilent cafs)
1198 throws KeeperException {
1199 CreateRequest create = (CreateRequest)toZooKeeperOp(zkw, cafs).toRequestRecord();
1200 String znode = create.getPath();
1201 try {
1202 RecoverableZooKeeper zk = zkw.getRecoverableZooKeeper();
1203 if (zk.exists(znode, false) == null) {
1204 zk.create(znode, create.getData(), create.getAcl(), CreateMode.fromFlag(create.getFlags()));
1205 }
1206 } catch(KeeperException.NodeExistsException nee) {
1207 } catch(KeeperException.NoAuthException nee){
1208 try {
1209 if (null == zkw.getRecoverableZooKeeper().exists(znode, false)) {
1210
1211 throw(nee);
1212 }
1213 } catch (InterruptedException ie) {
1214 zkw.interruptedException(ie);
1215 }
1216
1217 } catch(InterruptedException ie) {
1218 zkw.interruptedException(ie);
1219 }
1220 }
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233 public static void createWithParents(ZooKeeperWatcher zkw, String znode)
1234 throws KeeperException {
1235 createWithParents(zkw, znode, new byte[0]);
1236 }
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251 public static void createWithParents(ZooKeeperWatcher zkw, String znode, byte[] data)
1252 throws KeeperException {
1253 try {
1254 if(znode == null) {
1255 return;
1256 }
1257 zkw.getRecoverableZooKeeper().create(znode, data, createACL(zkw, znode),
1258 CreateMode.PERSISTENT);
1259 } catch(KeeperException.NodeExistsException nee) {
1260 return;
1261 } catch(KeeperException.NoNodeException nne) {
1262 createWithParents(zkw, getParent(znode));
1263 createWithParents(zkw, znode, data);
1264 } catch(InterruptedException ie) {
1265 zkw.interruptedException(ie);
1266 }
1267 }
1268
1269
1270
1271
1272
1273
1274
1275
1276 public static void deleteNode(ZooKeeperWatcher zkw, String node)
1277 throws KeeperException {
1278 deleteNode(zkw, node, -1);
1279 }
1280
1281
1282
1283
1284
1285 public static boolean deleteNode(ZooKeeperWatcher zkw, String node,
1286 int version)
1287 throws KeeperException {
1288 try {
1289 zkw.getRecoverableZooKeeper().delete(node, version);
1290 return true;
1291 } catch(KeeperException.BadVersionException bve) {
1292 return false;
1293 } catch(InterruptedException ie) {
1294 zkw.interruptedException(ie);
1295 return false;
1296 }
1297 }
1298
1299
1300
1301
1302
1303
1304
1305 public static void deleteNodeFailSilent(ZooKeeperWatcher zkw, String node)
1306 throws KeeperException {
1307 deleteNodeFailSilent(zkw,
1308 (DeleteNodeFailSilent)ZKUtilOp.deleteNodeFailSilent(node));
1309 }
1310
1311 private static void deleteNodeFailSilent(ZooKeeperWatcher zkw,
1312 DeleteNodeFailSilent dnfs) throws KeeperException {
1313 DeleteRequest delete = (DeleteRequest)toZooKeeperOp(zkw, dnfs).toRequestRecord();
1314 try {
1315 zkw.getRecoverableZooKeeper().delete(delete.getPath(), delete.getVersion());
1316 } catch(KeeperException.NoNodeException nne) {
1317 } catch(InterruptedException ie) {
1318 zkw.interruptedException(ie);
1319 }
1320 }
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331 public static void deleteNodeRecursively(ZooKeeperWatcher zkw, String node)
1332 throws KeeperException {
1333 try {
1334 List<String> children = ZKUtil.listChildrenNoWatch(zkw, node);
1335
1336 if (children == null) return;
1337
1338 if(!children.isEmpty()) {
1339 for(String child : children) {
1340 deleteNodeRecursively(zkw, joinZNode(node, child));
1341 }
1342 }
1343
1344
1345 if (zkw.getRecoverableZooKeeper().exists(node, zkw) != null){
1346 zkw.getRecoverableZooKeeper().delete(node, -1);
1347 }
1348 } catch(InterruptedException ie) {
1349 zkw.interruptedException(ie);
1350 }
1351 }
1352
1353
1354
1355
1356
1357
1358
1359 public static void deleteChildrenRecursively(ZooKeeperWatcher zkw, String node)
1360 throws KeeperException {
1361 List<String> children = ZKUtil.listChildrenNoWatch(zkw, node);
1362 if (children == null || children.isEmpty()) return;
1363 for(String child : children) {
1364 deleteNodeRecursively(zkw, joinZNode(node, child));
1365 }
1366 }
1367
1368
1369
1370
1371
1372
1373 public abstract static class ZKUtilOp {
1374 private String path;
1375
1376 private ZKUtilOp(String path) {
1377 this.path = path;
1378 }
1379
1380
1381
1382
1383 public static ZKUtilOp createAndFailSilent(String path, byte[] data) {
1384 return new CreateAndFailSilent(path, data);
1385 }
1386
1387
1388
1389
1390 public static ZKUtilOp deleteNodeFailSilent(String path) {
1391 return new DeleteNodeFailSilent(path);
1392 }
1393
1394
1395
1396
1397 public static ZKUtilOp setData(String path, byte [] data) {
1398 return new SetData(path, data);
1399 }
1400
1401
1402
1403
1404 public String getPath() {
1405 return path;
1406 }
1407
1408
1409
1410
1411
1412 public static class CreateAndFailSilent extends ZKUtilOp {
1413 private byte [] data;
1414
1415 private CreateAndFailSilent(String path, byte [] data) {
1416 super(path);
1417 this.data = data;
1418 }
1419
1420 public byte[] getData() {
1421 return data;
1422 }
1423
1424 @Override
1425 public boolean equals(Object o) {
1426 if (this == o) return true;
1427 if (!(o instanceof CreateAndFailSilent)) return false;
1428
1429 CreateAndFailSilent op = (CreateAndFailSilent) o;
1430 return getPath().equals(op.getPath()) && Arrays.equals(data, op.data);
1431 }
1432
1433 @Override
1434 public int hashCode() {
1435 int ret = 17 + getPath().hashCode() * 31;
1436 return ret * 31 + Bytes.hashCode(data);
1437 }
1438 }
1439
1440
1441
1442
1443
1444 public static class DeleteNodeFailSilent extends ZKUtilOp {
1445 private DeleteNodeFailSilent(String path) {
1446 super(path);
1447 }
1448
1449 @Override
1450 public boolean equals(Object o) {
1451 if (this == o) return true;
1452 if (!(o instanceof DeleteNodeFailSilent)) return false;
1453
1454 return super.equals(o);
1455 }
1456
1457 @Override
1458 public int hashCode() {
1459 return getPath().hashCode();
1460 }
1461 }
1462
1463
1464
1465
1466 public static class SetData extends ZKUtilOp {
1467 private byte [] data;
1468
1469 private SetData(String path, byte [] data) {
1470 super(path);
1471 this.data = data;
1472 }
1473
1474 public byte[] getData() {
1475 return data;
1476 }
1477
1478 @Override
1479 public boolean equals(Object o) {
1480 if (this == o) return true;
1481 if (!(o instanceof SetData)) return false;
1482
1483 SetData op = (SetData) o;
1484 return getPath().equals(op.getPath()) && Arrays.equals(data, op.data);
1485 }
1486
1487 @Override
1488 public int hashCode() {
1489 int ret = getPath().hashCode();
1490 return ret * 31 + Bytes.hashCode(data);
1491 }
1492 }
1493 }
1494
1495
1496
1497
1498 private static Op toZooKeeperOp(ZooKeeperWatcher zkw, ZKUtilOp op)
1499 throws UnsupportedOperationException {
1500 if(op == null) return null;
1501
1502 if (op instanceof CreateAndFailSilent) {
1503 CreateAndFailSilent cafs = (CreateAndFailSilent)op;
1504 return Op.create(cafs.getPath(), cafs.getData(), createACL(zkw, cafs.getPath()),
1505 CreateMode.PERSISTENT);
1506 } else if (op instanceof DeleteNodeFailSilent) {
1507 DeleteNodeFailSilent dnfs = (DeleteNodeFailSilent)op;
1508 return Op.delete(dnfs.getPath(), -1);
1509 } else if (op instanceof SetData) {
1510 SetData sd = (SetData)op;
1511 return Op.setData(sd.getPath(), sd.getData(), -1);
1512 } else {
1513 throw new UnsupportedOperationException("Unexpected ZKUtilOp type: "
1514 + op.getClass().getName());
1515 }
1516 }
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539 public static void multiOrSequential(ZooKeeperWatcher zkw, List<ZKUtilOp> ops,
1540 boolean runSequentialOnMultiFailure) throws KeeperException {
1541 if (ops == null) return;
1542 boolean useMulti = zkw.getConfiguration().getBoolean(HConstants.ZOOKEEPER_USEMULTI, false);
1543
1544 if (useMulti) {
1545 List<Op> zkOps = new LinkedList<Op>();
1546 for (ZKUtilOp op : ops) {
1547 zkOps.add(toZooKeeperOp(zkw, op));
1548 }
1549 try {
1550 zkw.getRecoverableZooKeeper().multi(zkOps);
1551 } catch (KeeperException ke) {
1552 switch (ke.code()) {
1553 case NODEEXISTS:
1554 case NONODE:
1555 case BADVERSION:
1556 case NOAUTH:
1557
1558
1559 if (runSequentialOnMultiFailure) {
1560 LOG.info("On call to ZK.multi, received exception: " + ke.toString() + "."
1561 + " Attempting to run operations sequentially because"
1562 + " runSequentialOnMultiFailure is: " + runSequentialOnMultiFailure + ".");
1563 processSequentially(zkw, ops);
1564 break;
1565 }
1566 default:
1567 throw ke;
1568 }
1569 } catch (InterruptedException ie) {
1570 zkw.interruptedException(ie);
1571 }
1572 } else {
1573
1574 processSequentially(zkw, ops);
1575 }
1576
1577 }
1578
1579 private static void processSequentially(ZooKeeperWatcher zkw, List<ZKUtilOp> ops)
1580 throws KeeperException, NoNodeException {
1581 for (ZKUtilOp op : ops) {
1582 if (op instanceof CreateAndFailSilent) {
1583 createAndFailSilent(zkw, (CreateAndFailSilent) op);
1584 } else if (op instanceof DeleteNodeFailSilent) {
1585 deleteNodeFailSilent(zkw, (DeleteNodeFailSilent) op);
1586 } else if (op instanceof SetData) {
1587 setData(zkw, (SetData) op);
1588 } else {
1589 throw new UnsupportedOperationException("Unexpected ZKUtilOp type: "
1590 + op.getClass().getName());
1591 }
1592 }
1593 }
1594
1595
1596
1597
1598
1599
1600 public static String dump(ZooKeeperWatcher zkw) {
1601 StringBuilder sb = new StringBuilder();
1602 try {
1603 sb.append("HBase is rooted at ").append(zkw.baseZNode);
1604 sb.append("\nActive master address: ");
1605 try {
1606 sb.append(MasterAddressTracker.getMasterAddress(zkw));
1607 } catch (IOException e) {
1608 sb.append("<<FAILED LOOKUP: " + e.getMessage() + ">>");
1609 }
1610 sb.append("\nBackup master addresses:");
1611 for (String child : listChildrenNoWatch(zkw,
1612 zkw.backupMasterAddressesZNode)) {
1613 sb.append("\n ").append(child);
1614 }
1615 sb.append("\nRegion server holding hbase:meta: " + MetaRegionTracker.getMetaRegionLocation(zkw));
1616 sb.append("\nRegion servers:");
1617 for (String child : listChildrenNoWatch(zkw, zkw.rsZNode)) {
1618 sb.append("\n ").append(child);
1619 }
1620 try {
1621 getReplicationZnodesDump(zkw, sb);
1622 } catch (KeeperException ke) {
1623 LOG.warn("Couldn't get the replication znode dump", ke);
1624 }
1625 sb.append("\nQuorum Server Statistics:");
1626 String[] servers = zkw.getQuorum().split(",");
1627 for (String server : servers) {
1628 sb.append("\n ").append(server);
1629 try {
1630 String[] stat = getServerStats(server, ZKUtil.zkDumpConnectionTimeOut);
1631
1632 if (stat == null) {
1633 sb.append("[Error] invalid quorum server: " + server);
1634 break;
1635 }
1636
1637 for (String s : stat) {
1638 sb.append("\n ").append(s);
1639 }
1640 } catch (Exception e) {
1641 sb.append("\n ERROR: ").append(e.getMessage());
1642 }
1643 }
1644 } catch (KeeperException ke) {
1645 sb.append("\nFATAL ZooKeeper Exception!\n");
1646 sb.append("\n" + ke.getMessage());
1647 }
1648 return sb.toString();
1649 }
1650
1651
1652
1653
1654
1655
1656
1657 private static void getReplicationZnodesDump(ZooKeeperWatcher zkw, StringBuilder sb)
1658 throws KeeperException {
1659 String replicationZNodeName = zkw.getConfiguration().get("zookeeper.znode.replication",
1660 "replication");
1661 String replicationZnode = joinZNode(zkw.baseZNode, replicationZNodeName);
1662 if (ZKUtil.checkExists(zkw, replicationZnode) == -1) return;
1663
1664 sb.append("\n").append(replicationZnode).append(": ");
1665 List<String> children = ZKUtil.listChildrenNoWatch(zkw, replicationZnode);
1666 for (String child : children) {
1667 String znode = joinZNode(replicationZnode, child);
1668 if (child.equals(zkw.getConfiguration().get("zookeeper.znode.replication.peers", "peers"))) {
1669 appendPeersZnodes(zkw, znode, sb);
1670 } else if (child.equals(zkw.getConfiguration().
1671 get("zookeeper.znode.replication.rs", "rs"))) {
1672 appendRSZnodes(zkw, znode, sb);
1673 }
1674 }
1675 }
1676
1677 private static void appendRSZnodes(ZooKeeperWatcher zkw, String znode, StringBuilder sb)
1678 throws KeeperException {
1679 List<String> stack = new LinkedList<String>();
1680 stack.add(znode);
1681 do {
1682 String znodeToProcess = stack.remove(stack.size() - 1);
1683 sb.append("\n").append(znodeToProcess).append(": ");
1684 byte[] data = ZKUtil.getData(zkw, znodeToProcess);
1685 if (data != null && data.length > 0) {
1686 long position = 0;
1687 try {
1688 position = ZKUtil.parseHLogPositionFrom(ZKUtil.getData(zkw, znodeToProcess));
1689 sb.append(position);
1690 } catch (Exception e) {
1691 }
1692 }
1693 for (String zNodeChild : ZKUtil.listChildrenNoWatch(zkw, znodeToProcess)) {
1694 stack.add(ZKUtil.joinZNode(znodeToProcess, zNodeChild));
1695 }
1696 } while (stack.size() > 0);
1697 }
1698
1699 private static void appendPeersZnodes(ZooKeeperWatcher zkw, String peersZnode,
1700 StringBuilder sb) throws KeeperException {
1701 int pblen = ProtobufUtil.lengthOfPBMagic();
1702 sb.append("\n").append(peersZnode).append(": ");
1703 for (String peerIdZnode : ZKUtil.listChildrenNoWatch(zkw, peersZnode)) {
1704 String znodeToProcess = ZKUtil.joinZNode(peersZnode, peerIdZnode);
1705 byte[] data = ZKUtil.getData(zkw, znodeToProcess);
1706
1707 try {
1708 String clusterKey = ZooKeeperProtos.ReplicationPeer.newBuilder().
1709 mergeFrom(data, pblen, data.length - pblen).getClusterkey();
1710 sb.append("\n").append(znodeToProcess).append(": ").append(clusterKey);
1711
1712 appendPeerState(zkw, znodeToProcess, sb);
1713 } catch (InvalidProtocolBufferException ipbe) {
1714 LOG.warn("Got Exception while parsing peer: " + znodeToProcess, ipbe);
1715 }
1716 }
1717 }
1718
1719 private static void appendPeerState(ZooKeeperWatcher zkw, String znodeToProcess,
1720 StringBuilder sb) throws KeeperException, InvalidProtocolBufferException {
1721 String peerState = zkw.getConfiguration().get("zookeeper.znode.replication.peers.state",
1722 "peer-state");
1723 int pblen = ProtobufUtil.lengthOfPBMagic();
1724 for (String child : ZKUtil.listChildrenNoWatch(zkw, znodeToProcess)) {
1725 if (!child.equals(peerState)) continue;
1726 String peerStateZnode = ZKUtil.joinZNode(znodeToProcess, child);
1727 sb.append("\n").append(peerStateZnode).append(": ");
1728 byte[] peerStateData = ZKUtil.getData(zkw, peerStateZnode);
1729 sb.append(ZooKeeperProtos.ReplicationState.newBuilder()
1730 .mergeFrom(peerStateData, pblen, peerStateData.length - pblen).getState().name());
1731 }
1732 }
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742 public static String[] getServerStats(String server, int timeout)
1743 throws IOException {
1744 String[] sp = server.split(":");
1745 if (sp == null || sp.length == 0) {
1746 return null;
1747 }
1748
1749 String host = sp[0];
1750 int port = sp.length > 1 ? Integer.parseInt(sp[1])
1751 : HConstants.DEFAULT_ZOOKEPER_CLIENT_PORT;
1752
1753 Socket socket = new Socket();
1754 InetSocketAddress sockAddr = new InetSocketAddress(host, port);
1755 socket.connect(sockAddr, timeout);
1756
1757 socket.setSoTimeout(timeout);
1758 PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
1759 BufferedReader in = new BufferedReader(new InputStreamReader(
1760 socket.getInputStream()));
1761 out.println("stat");
1762 out.flush();
1763 ArrayList<String> res = new ArrayList<String>();
1764 while (true) {
1765 String line = in.readLine();
1766 if (line != null) {
1767 res.add(line);
1768 } else {
1769 break;
1770 }
1771 }
1772 socket.close();
1773 return res.toArray(new String[res.size()]);
1774 }
1775
1776 private static void logRetrievedMsg(final ZooKeeperWatcher zkw,
1777 final String znode, final byte [] data, final boolean watcherSet) {
1778 if (!LOG.isTraceEnabled()) return;
1779 LOG.trace(zkw.prefix("Retrieved " + ((data == null)? 0: data.length) +
1780 " byte(s) of data from znode " + znode +
1781 (watcherSet? " and set watcher; ": "; data=") +
1782 (data == null? "null": data.length == 0? "empty": (
1783 znode.startsWith(zkw.assignmentZNode)?
1784 ZKAssign.toString(data):
1785 znode.startsWith(zkw.metaServerZNode)?
1786 getServerNameOrEmptyString(data):
1787 znode.startsWith(zkw.backupMasterAddressesZNode)?
1788 getServerNameOrEmptyString(data):
1789 StringUtils.abbreviate(Bytes.toStringBinary(data), 32)))));
1790 }
1791
1792 private static String getServerNameOrEmptyString(final byte [] data) {
1793 try {
1794 return ServerName.parseFrom(data).toString();
1795 } catch (DeserializationException e) {
1796 return "";
1797 }
1798 }
1799
1800
1801
1802
1803
1804 public static void waitForBaseZNode(Configuration conf) throws IOException {
1805 LOG.info("Waiting until the base znode is available");
1806 String parentZNode = conf.get(HConstants.ZOOKEEPER_ZNODE_PARENT,
1807 HConstants.DEFAULT_ZOOKEEPER_ZNODE_PARENT);
1808 ZooKeeper zk = new ZooKeeper(ZKConfig.getZKQuorumServersString(conf),
1809 conf.getInt(HConstants.ZK_SESSION_TIMEOUT,
1810 HConstants.DEFAULT_ZK_SESSION_TIMEOUT), EmptyWatcher.instance);
1811
1812 final int maxTimeMs = 10000;
1813 final int maxNumAttempts = maxTimeMs / HConstants.SOCKET_RETRY_WAIT_MS;
1814
1815 KeeperException keeperEx = null;
1816 try {
1817 try {
1818 for (int attempt = 0; attempt < maxNumAttempts; ++attempt) {
1819 try {
1820 if (zk.exists(parentZNode, false) != null) {
1821 LOG.info("Parent znode exists: " + parentZNode);
1822 keeperEx = null;
1823 break;
1824 }
1825 } catch (KeeperException e) {
1826 keeperEx = e;
1827 }
1828 Threads.sleepWithoutInterrupt(HConstants.SOCKET_RETRY_WAIT_MS);
1829 }
1830 } finally {
1831 zk.close();
1832 }
1833 } catch (InterruptedException ex) {
1834 Thread.currentThread().interrupt();
1835 }
1836
1837 if (keeperEx != null) {
1838 throw new IOException(keeperEx);
1839 }
1840 }
1841
1842
1843 public static byte[] blockUntilAvailable(
1844 final ZooKeeperWatcher zkw, final String znode, final long timeout)
1845 throws InterruptedException {
1846 if (timeout < 0) throw new IllegalArgumentException();
1847 if (zkw == null) throw new IllegalArgumentException();
1848 if (znode == null) throw new IllegalArgumentException();
1849
1850 byte[] data = null;
1851 boolean finished = false;
1852 final long endTime = System.currentTimeMillis() + timeout;
1853 while (!finished) {
1854 try {
1855 data = ZKUtil.getData(zkw, znode);
1856 } catch(KeeperException e) {
1857 if (e instanceof KeeperException.SessionExpiredException
1858 || e instanceof KeeperException.AuthFailedException) {
1859
1860 throw new InterruptedException("interrupted due to " + e);
1861 }
1862 LOG.warn("Unexpected exception handling blockUntilAvailable", e);
1863 }
1864
1865 if (data == null && (System.currentTimeMillis() +
1866 HConstants.SOCKET_RETRY_WAIT_MS < endTime)) {
1867 Thread.sleep(HConstants.SOCKET_RETRY_WAIT_MS);
1868 } else {
1869 finished = true;
1870 }
1871 }
1872
1873 return data;
1874 }
1875
1876
1877
1878
1879
1880
1881
1882
1883 public static KeeperException convert(final DeserializationException e) {
1884 KeeperException ke = new KeeperException.DataInconsistencyException();
1885 ke.initCause(e);
1886 return ke;
1887 }
1888
1889
1890
1891
1892
1893
1894 public static void logZKTree(ZooKeeperWatcher zkw, String root) {
1895 if (!LOG.isDebugEnabled()) return;
1896 LOG.debug("Current zk system:");
1897 String prefix = "|-";
1898 LOG.debug(prefix + root);
1899 try {
1900 logZKTree(zkw, root, prefix);
1901 } catch (KeeperException e) {
1902 throw new RuntimeException(e);
1903 }
1904 }
1905
1906
1907
1908
1909
1910
1911 protected static void logZKTree(ZooKeeperWatcher zkw, String root, String prefix) throws KeeperException {
1912 List<String> children = ZKUtil.listChildrenNoWatch(zkw, root);
1913 if (children == null) return;
1914 for (String child : children) {
1915 LOG.debug(prefix + child);
1916 String node = ZKUtil.joinZNode(root.equals("/") ? "" : root, child);
1917 logZKTree(zkw, node, prefix + "---");
1918 }
1919 }
1920
1921
1922
1923
1924
1925
1926 public static byte[] positionToByteArray(final long position) {
1927 byte[] bytes = ZooKeeperProtos.ReplicationHLogPosition.newBuilder().setPosition(position)
1928 .build().toByteArray();
1929 return ProtobufUtil.prependPBMagic(bytes);
1930 }
1931
1932
1933
1934
1935
1936
1937 public static long parseHLogPositionFrom(final byte[] bytes) throws DeserializationException {
1938 if (bytes == null) {
1939 throw new DeserializationException("Unable to parse null HLog position.");
1940 }
1941 if (ProtobufUtil.isPBMagicPrefix(bytes)) {
1942 int pblen = ProtobufUtil.lengthOfPBMagic();
1943 ZooKeeperProtos.ReplicationHLogPosition.Builder builder =
1944 ZooKeeperProtos.ReplicationHLogPosition.newBuilder();
1945 ZooKeeperProtos.ReplicationHLogPosition position;
1946 try {
1947 position = builder.mergeFrom(bytes, pblen, bytes.length - pblen).build();
1948 } catch (InvalidProtocolBufferException e) {
1949 throw new DeserializationException(e);
1950 }
1951 return position.getPosition();
1952 } else {
1953 if (bytes.length > 0) {
1954 return Bytes.toLong(bytes);
1955 }
1956 return 0;
1957 }
1958 }
1959
1960
1961
1962
1963
1964
1965
1966
1967 public static byte[] regionSequenceIdsToByteArray(final Long regionLastFlushedSequenceId,
1968 final Map<byte[], Long> storeSequenceIds) {
1969 ZooKeeperProtos.RegionStoreSequenceIds.Builder regionSequenceIdsBuilder =
1970 ZooKeeperProtos.RegionStoreSequenceIds.newBuilder();
1971 ZooKeeperProtos.StoreSequenceId.Builder storeSequenceIdBuilder =
1972 ZooKeeperProtos.StoreSequenceId.newBuilder();
1973 if (storeSequenceIds != null) {
1974 for (Map.Entry<byte[], Long> e : storeSequenceIds.entrySet()){
1975 byte[] columnFamilyName = e.getKey();
1976 Long curSeqId = e.getValue();
1977 storeSequenceIdBuilder.setFamilyName(ByteStringer.wrap(columnFamilyName));
1978 storeSequenceIdBuilder.setSequenceId(curSeqId);
1979 regionSequenceIdsBuilder.addStoreSequenceId(storeSequenceIdBuilder.build());
1980 storeSequenceIdBuilder.clear();
1981 }
1982 }
1983 regionSequenceIdsBuilder.setLastFlushedSequenceId(regionLastFlushedSequenceId);
1984 byte[] result = regionSequenceIdsBuilder.build().toByteArray();
1985 return ProtobufUtil.prependPBMagic(result);
1986 }
1987
1988
1989
1990
1991
1992
1993 public static RegionStoreSequenceIds parseRegionStoreSequenceIds(final byte[] bytes)
1994 throws DeserializationException {
1995 if (bytes == null || !ProtobufUtil.isPBMagicPrefix(bytes)) {
1996 throw new DeserializationException("Unable to parse RegionStoreSequenceIds.");
1997 }
1998 RegionStoreSequenceIds.Builder regionSequenceIdsBuilder =
1999 ZooKeeperProtos.RegionStoreSequenceIds.newBuilder();
2000 int pblen = ProtobufUtil.lengthOfPBMagic();
2001 RegionStoreSequenceIds storeIds = null;
2002 try {
2003 storeIds = regionSequenceIdsBuilder.mergeFrom(bytes, pblen, bytes.length - pblen).build();
2004 } catch (InvalidProtocolBufferException e) {
2005 throw new DeserializationException(e);
2006 }
2007 return storeIds;
2008 }
2009 }