// connect to both name node if possible.
// If doWait is true, then return only when at least one handshake is
// successful.
//
private NamespaceInfo handshake(boolean startup) throws IOException {
NamespaceInfo nsInfo = null;
boolean firstIsPrimary = false;
// When true indicates ZK is null and there is no primary. This is to
// enable datanode startups during failover. The assumption is that the
// layout version of the Standby and Primary would be consistent when
// we failover and hence we can speak to any one of the nodes to find out
// the NamespaceInfo.
boolean noPrimary = false;
do {
if (startup) {
// The startup option is used when the datanode is first created
// We only need to connect to the primary at this point and as soon
// as possible. So figure out who the primary is from the ZK
Stat stat = new Stat();
try {
String primaryAddress =
zkClient.getPrimaryAvatarAddress(defaultAddr, stat, false);
noPrimary = (primaryAddress == null);
String firstNNAddress = nameAddr1.getHostName() + ":" +
nameAddr1.getPort();
firstIsPrimary = firstNNAddress.equalsIgnoreCase(primaryAddress);
} catch (Exception ex) {
LOG.error("Could not get the primary address from ZooKeeper", ex);
}
}
try {
if ((firstIsPrimary && startup) || !startup || noPrimary) {
// only try to connect to the first NN if it is not the
// startup connection or if it is primary on startup
// This way if it is standby we are not wasting datanode startup time
initProxy1();
if (startup) {
nsInfo = handshake(namenode1, nameAddr1);
}
}
} catch(ConnectException se) { // namenode has not been started
LOG.info("Server at " + nameAddr1 + " not available yet, Zzzzz...");
} catch(SocketTimeoutException te) { // namenode is busy
LOG.info("Problem connecting to server timeout. " + nameAddr1);
} catch (IOException ioe) {
LOG.info("Problem connecting to server. " + nameAddr1, ioe);
}
try {
if ((!firstIsPrimary && startup) || !startup || noPrimary) {
initProxy2();
if (startup) {
NamespaceInfo tempInfo = handshake(namenode2, nameAddr2);
// During failover both layouts should match.
if (noPrimary && nsInfo != null && tempInfo.getLayoutVersion()
!= nsInfo.getLayoutVersion()) {
throw new IOException("Layout versions don't match on zero, one: "
+ nsInfo.getLayoutVersion() + ", "
+ tempInfo.getLayoutVersion());
}
nsInfo = tempInfo;
}
}
} catch(ConnectException se) { // namenode has not been started