}
if (ClusterMethods.SESSION_TRANSFER.toString().equals(clel.getMethodName())) {
Set<String> cancel_nodes = new LinkedHashSet<String>();
String node_found = null;
String userId = clel.getMethodParam(USER_ID);
XMPPSession session = getSession(userId);
String connectionId = clel.getMethodParam(CONNECTION_ID);
XMPPResourceConnection conn = null;
if (session != null) {
conn = session.getResourceForConnectionId(connectionId);
}
//ClusterElement result = null;
if (getComponentId().equals(clel.getFirstNode())) {
log.finest("Session transfer request came back to me....");
// Ok, the request has came back to me, let's look what to do now....
// First let's check whether any of the nodes has decided to accept
// the transfer:
// This is a set of nodes we will send a transfer cancell later on
long time = 0;
long hash = 0;
for (String node: clel.getVisitedNodes()) {
if (clel.getMethodResultVal(node + "-CREATED") != null) {
long tmp_time = clel.getMethodResultVal(node + "-" + AUTH_TIME, 0);
long tmp_hash = clel.getMethodResultVal(
node + "-HASH-" + XMPP_SESSION_ID, 0);
log.finest("Node: " + node + " responded with: "
+ clel.getMethodResultVal(node + "-CREATED")
+ ", tmp_time: " + tmp_time
+ ", tmp_hash: " + tmp_hash);
boolean replace_node = false;
if (tmp_time == time) {
if (tmp_hash > hash) {
replace_node = true;
}
} else {
if (tmp_time > time) {
replace_node = true;
}
}
if (replace_node) {
if (node_found != null) {
log.finest("Addeding node to cancel_nodes: " + node_found);
cancel_nodes.add(node_found);
}
node_found = node;
hash = tmp_hash;
time = tmp_time;
} else {
log.finest("Addeding node to cancel_nodes: " + node);
cancel_nodes.add(node);
}
}
}
if (node_found != null) {
// This is where we want to do the user session transfer then
if (session != null) {
if (conn != null) {
Map<String, String> res_vals = new LinkedHashMap<String, String>();
res_vals.put(TRANSFER, "accept");
ClusterElement result = clel.createMethodResponse(getComponentId(),
node_found, "result", res_vals);
fastAddOutPacket(new Packet(result.getClusterElement()));
conn.putSessionData("redirect-to", node_found);
sendAllOnHold(conn);
String xmpp_sessionId = clel.getMethodParam(XMPP_SESSION_ID);
Packet redirect = Command.REDIRECT.getPacket(node_found,
connectionId, StanzaType.set, "1", "submit");
Command.addFieldValue(redirect, "session-id", xmpp_sessionId);
fastAddOutPacket(redirect);
} else {
// Ups, the user has disconnected, send session transfer to all
log.finest("Addeding node to cancel_nodes: " + node_found);
cancel_nodes.add(node_found);
log.fine("The user connection doesn't exist: " + userId
+ ", connectionId: " + connectionId);
}
} else {
// Ups, the user has disconnected, send session transfer to all
log.finest("Addeding node to cancel_nodes: " + node_found);
cancel_nodes.add(node_found);
log.fine("The user session doesn't exist: " + userId);
}
} else {
// Set status to NORMALL, user is not logged in on any other node.
if (conn != null) {
log.finest("Set status to NORMAL and send all ON_HOLD");
conn.setConnectionStatus(ConnectionStatus.NORMAL);
sendAllOnHold(conn);
} else {
log.fine("The user connection doesn't exist: " + userId
+ ", connectionId: " + connectionId);
}
}
if (cancel_nodes.size() > 0) {
// Send session transfer to all.
Map<String, String> res_vals = new LinkedHashMap<String, String>();
res_vals.put(TRANSFER, "cancel");
for (String node: cancel_nodes) {
ClusterElement result = clel.createMethodResponse(getComponentId(),
node, "result", res_vals);
log.finest("Sending sesstion transfer CANCEL to node: " + node);
fastAddOutPacket(new Packet(result.getClusterElement()));
}
}
} else {
// A request from some other node, maybe the user session should be
// transfered here...
ClusterElement result = ClusterElement.createForNextNode(clel,
cluster_nodes, getComponentId());
if (session != null) {
conn = session.getOldestConnection();
boolean transfer_in = false;
switch (conn.getConnectionStatus()) {
case ON_HOLD:
long local_auth_time = conn.getAuthTime();
long remote_auth_time = clel.getMethodParam(AUTH_TIME, 0L);
if (local_auth_time == remote_auth_time) {
transfer_in = (conn.getSessionId().hashCode() >
clel.getMethodParam(XMPP_SESSION_ID).hashCode());
} else {
transfer_in = (local_auth_time > remote_auth_time);
}
break;
case REDIRECT:
transfer_in = false;
break;
case NORMAL:
transfer_in = true;
break;
default:
break;
}
if (transfer_in) {
addTempSession(clel);
result.addMethodResult(getComponentId() + "-" + AUTH_TIME,
"" + conn.getAuthTime());
result.addMethodResult(getComponentId() + "-HASH-" + XMPP_SESSION_ID,
"" + conn.getSessionId().hashCode());
result.addMethodResult(getComponentId() + "-STATUS",
"" + conn.getConnectionStatus());
result.addMethodResult(getComponentId() + "-CREATED",
"" + true);
}
} else {
// Do nothing really, just forward the request to a next node
}
fastAddOutPacket(new Packet(result.getClusterElement()));
}
}
break;
case result:
if (ClusterMethods.SESSION_TRANSFER.toString().equals(clel.getMethodName())) {
String transfer = clel.getMethodResultVal(TRANSFER);
if (transfer == null) {
log.warning("Incorrect response for the session transfer: "
+ packet.toString());
return;
}
if (transfer.equals("accept")) {
String userId = clel.getMethodParam(USER_ID);
XMPPSession session = getSession(userId);
if (session == null) {
// Ups, something wrong happened, let's record this in the log
// file for now...
log.warning("User session does not exist for the request to complete the user transfer: " + packet.toString());
return;
}
String connectionId = clel.getMethodParam(CONNECTION_ID);
XMPPResourceConnection conn =
session.getResourceForConnectionId(connectionId);
if (conn == null) {
// Ups, something wrong happened, let's record this in the log
// file for now...
log.warning("User connection does not exist for the request to complete the user transfer: " + packet.toString());
return;