use of org.mobicents.tools.heartbeat.api.Node in project load-balancer by RestComm.
the class NodeRegisterImpl method heartbeatRequestReceived.
@Override
public synchronized void heartbeatRequestReceived(MessageEvent e, JsonObject json) {
logger.trace("LB got heartbeat from Node : " + json);
KeySession keySession = new KeySession(json.get(Protocol.SESSION_ID).toString());
boolean was = false;
for (Entry<String, InvocationContext> ctxEntry : balancerRunner.contexts.entrySet()) {
InvocationContext ctx = ctxEntry.getValue();
Node nodePresentIPv4 = ctx.sessionNodeMap(false).get(keySession);
Node nodePresentIPv6 = null;
if (nodePresentIPv4 != null) {
nodePresentIPv4.updateTimerStamp();
was = true;
} else if ((nodePresentIPv6 = ctx.sessionNodeMap(true).get(keySession)) != null) {
nodePresentIPv6.updateTimerStamp();
was = true;
}
}
if (!was) {
logger.error("LB got heartbeat ( " + json + " ) from node which not pesent in maps");
}
if (e != null)
writeResponse(e, HttpResponseStatus.OK, Protocol.HEARTBEAT, Protocol.OK);
}
use of org.mobicents.tools.heartbeat.api.Node in project load-balancer by RestComm.
the class NodeRegisterImpl method handlePingInRegister.
/**
* {@inheritDoc}
*/
public synchronized void handlePingInRegister(ArrayList<Node> ping) {
for (Node pingNode : ping) {
if (pingNode.getIp() == null) {
// https://telestax.atlassian.net/browse/LB-9 Prevent Routing of Requests to Nodes that exposed null IP address
logger.warn("[" + pingNode + "] not added as its IP is null, the node is sending bad information");
} else {
Boolean isIpV6 = LbUtils.isValidInet6Address(pingNode.getIp());
Boolean isIpV4 = InetAddressValidator.getInstance().isValidInet4Address(pingNode.getIp());
if (!isIpV4 && !isIpV6)
logger.warn("[" + pingNode + "] not added as its IP is null, the node is sending bad information");
else {
String version = pingNode.getProperties().get("version");
if (version == null)
version = "0";
InvocationContext ctx = balancerRunner.getInvocationContext(version);
// if bad node changed sessioId it means that the node was restarted so we remove it from map of bad nodes
KeySip keySip = new KeySip(pingNode, isIpV6);
if (ctx.sipNodeMap(isIpV6).get(keySip) != null && ctx.sipNodeMap(isIpV6).get(keySip).isBad()) {
if (ctx.sipNodeMap(isIpV6).get(keySip).getProperties().get("sessionId").equals(pingNode.getProperties().get("sessionId")))
continue;
else {
ctx.sipNodeMap(isIpV6).get(keySip).setBad(false);
String instanseId = pingNode.getProperties().get(Protocol.RESTCOMM_INSTANCE_ID);
if (instanseId != null)
ctx.httpNodeMap.get(new KeyHttp(instanseId)).setBad(false);
}
}
pingNode.updateTimerStamp();
// logger.info("Pingnode updated " + pingNode);
if (pingNode.getProperties().get("jvmRoute") != null) {
// Let it leak, we will have 10-100 nodes, not a big deal if it leaks.
// We need info about inactive nodes to do the failover
balancerRunner.balancerContext.jvmRouteToSipNode.put(pingNode.getProperties().get("jvmRoute"), pingNode);
}
Node nodePresent = ctx.sipNodeMap(isIpV6).get(keySip);
// adding done afterwards to avoid ConcurrentModificationException when adding the node while going through the iterator
if (nodePresent != null) {
nodePresent.updateTimerStamp();
if (logger.isTraceEnabled()) {
logger.trace("Ping " + nodePresent.getTimeStamp());
}
if (pingNode.getProperties().get("GRACEFUL_SHUTDOWN") != null && pingNode.getProperties().get("GRACEFUL_SHUTDOWN").equals("true")) {
logger.info("LB will exclude node " + nodePresent + " for new calls because of GRACEFUL_SHUTDOWN");
ctx.sipNodeMap(isIpV6).get(keySip).setGracefulShutdown(true);
String instanseId = pingNode.getProperties().get(Protocol.RESTCOMM_INSTANCE_ID);
if (instanseId != null)
ctx.httpNodeMap.get(new KeyHttp(instanseId)).setGracefulShutdown(true);
}
} else if (pingNode.getProperties().get("GRACEFUL_SHUTDOWN") != null && pingNode.getProperties().get("GRACEFUL_SHUTDOWN").equals("true")) {
if (logger.isDebugEnabled())
logger.debug("Ping from node which LB exclude because of GRACEFUL_SHUTDOWN : " + pingNode);
} else {
Integer current = Integer.parseInt(version);
Integer latest = Integer.parseInt(latestVersion);
latestVersion = Math.max(current, latest) + "";
balancerRunner.balancerContext.aliveNodes.add(pingNode);
ctx.sipNodeMap(isIpV6).put(keySip, pingNode);
String instanceId = pingNode.getProperties().get("Restcomm-Instance-Id");
if (instanceId != null)
ctx.httpNodeMap.put(new KeyHttp(instanceId), pingNode);
Integer smppPort = null;
if (pingNode.getProperties().get("smppPort") != null) {
smppPort = Integer.parseInt(pingNode.getProperties().get("smppPort"));
ctx.smppNodeMap.put(new KeySmpp(pingNode), pingNode);
}
ctx.balancerAlgorithm.nodeAdded(pingNode);
balancerRunner.balancerContext.allNodesEver.add(pingNode);
pingNode.updateTimerStamp();
if (logger.isInfoEnabled()) {
logger.info("NodeExpirationTimerTask Run NSync[" + pingNode + "] added");
}
}
}
}
}
}
use of org.mobicents.tools.heartbeat.api.Node in project load-balancer by RestComm.
the class PureConsistentHashBalancerAlgorithm method syncNodes.
@Override
public synchronized void syncNodes(Boolean isIpV6) {
Set<Node> nodes = tmpNodes;
if (nodes != null) {
ArrayList<Node> nodeList = new ArrayList<Node>();
nodeList.addAll(nodes);
Collections.sort(nodeList, new Comparator<Node>() {
public int compare(Node o1, Node o2) {
int a = absDigest(o1.toStringWithoutJvmroute());
int b = absDigest(o2.toStringWithoutJvmroute());
if (a == b)
return 0;
if (a < b)
return -1;
return 1;
}
});
HashMap<Integer, Node> tmpHashToNode = new HashMap<Integer, Node>();
for (Node node : nodeList) tmpHashToNode.put(absDigest(node.toStringWithoutJvmroute()), node);
this.hashToNode = tmpHashToNode;
HashMap<Node, Integer> tmpNodeToHash = new HashMap<Node, Integer>();
for (Node node : nodeList) tmpNodeToHash.put(node, absDigest(node.toStringWithoutJvmroute()));
this.nodeToHash = tmpNodeToHash;
if (isIpV6)
this.nodesArrayV6 = nodeList.toArray();
else
this.nodesArrayV4 = nodeList.toArray();
}
dumpNodes();
}
use of org.mobicents.tools.heartbeat.api.Node in project load-balancer by RestComm.
the class PureConsistentHashBalancerAlgorithm method dumpNodes.
private void dumpNodes() {
String nodes = null;
if (nodesArrayV6 != null)
nodes = "I am " + getBalancerContext().externalHost + ". I see the following nodes are right now (" + (nodesArrayV4.length + nodesArrayV6.length) + "):\n";
else
nodes = "I am " + getBalancerContext().externalHost + ". I see the following nodes are right now (" + (nodesArrayV4.length) + "):\n";
for (Object object : nodesArrayV4) {
Node node = (Node) object;
nodes += node.toString() + " [ALIVE:" + isAlive(node) + "]" + " [HASH:" + absDigest(node.toStringWithoutJvmroute()) + "]" + "\n";
}
if (nodesArrayV6 != null)
for (Object object : nodesArrayV6) {
Node node = (Node) object;
nodes += node.toString() + " [ALIVE:" + isAlive(node) + "]" + " [HASH:" + absDigest(node.toStringWithoutJvmroute()) + "]" + "\n";
}
logger.info(nodes);
}
use of org.mobicents.tools.heartbeat.api.Node in project load-balancer by RestComm.
the class RouterImpl method getNextHops.
public ListIterator<HopImpl> getNextHops(Request request) {
Node node = null;
for (int i = 0; i < 5 && node == null; i++) {
try {
node = register.getNextNode();
} catch (IndexOutOfBoundsException ioobe) {
}
}
if (node == null) {
return null;
} else {
String transport = ((ViaHeader) request.getHeader(ViaHeader.NAME)).getTransport().toLowerCase();
LinkedList<HopImpl> retval = new LinkedList<HopImpl>();
Integer port = Integer.parseInt(node.getProperties().get(transport + "Port"));
if (port == null) {
throw new RuntimeException("No port available for transport " + transport + " for node " + node);
}
retval.add(new HopImpl(node.getIp(), port, transport));
return retval.listIterator();
}
}
Aggregations