com.linkedin.parseq.zk.client.ZKUtil Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of parseq-zk-client Show documentation
Show all versions of parseq-zk-client Show documentation
Integrates ParSeq with Apache ZooKeeper Library
/*
* Copyright 2016 LinkedIn Crop.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.linkedin.parseq.zk.client;
import java.util.List;
import java.util.stream.Collectors;
import org.apache.zookeeper.KeeperException;
/**
* @author Ang Xu
*/
public final class ZKUtil {
private ZKUtil() {}
public static String normalizeZKPath(String basePath, String child) {
// normalization
while (basePath.endsWith("/")) {
basePath = basePath.substring(0, basePath.length() - 2);
}
while(child.startsWith("/")) {
child = child.substring(1);
}
return basePath + "/" + child;
}
/**
* Decides whether the given {@link Throwable throwable} is recoverable or not.
* Recoverable exceptions are defined as such:
* http://wiki.apache.org/hadoop/ZooKeeper/ErrorHandling
*
* @param t the {@link Throwable}
* @return {@code true} if {@code t} is recoverable and {@code false} otherwise.
*/
public static boolean isRecoverable(Throwable t) {
if (t instanceof KeeperException) {
KeeperException ex = (KeeperException) t;
if (ex.code() == KeeperException.Code.CONNECTIONLOSS ||
ex.code() == KeeperException.Code.OPERATIONTIMEOUT) {
return true;
}
}
return false;
}
public static String findNodeWithUUID(List children, String uuid) {
for (String child : children) {
if (child.startsWith(uuid)) {
return child;
}
}
return null;
}
/**
* Finds node with next lowest sequence number than the given node within
* the given list of nodes.
*
* @param children list of children
* @param node the given node to compare sequence number with
* @return the node with next lowest sequence number
*/
public static String findNodeWithNextLowestSN(List children, String node) {
List sortedChildren = children.stream()
.sorted((String o1, String o2) ->
Long.compare(getSequenceNumber(o1), getSequenceNumber(o2)))
.collect(Collectors.toList());
int index = sortedChildren.indexOf(node);
if (index > 0) {
return sortedChildren.get(index-1);
} else if (index == 0) {
return node;
} else {
return null;
}
}
/**
* Gets 10 digit sequence number from the given znode per:
* http://zookeeper.apache.org/doc/trunk/zookeeperProgrammers.html#Sequence+Nodes+--+Unique+Naming
*/
private static long getSequenceNumber(String node) {
final int length = node.length();
try {
String seqNumStr = node.substring(length - 10, length);
return Long.valueOf(seqNumStr);
} catch (IndexOutOfBoundsException | NumberFormatException ex) {
throw new IllegalArgumentException(String.format("znode %s doesn't have sequence number", node));
}
}
}