* Msg consumer.
*/
private class RemoteNodeRouter implements MsgOutInterceptor {
public void push(Msg aMsg) {
MsgHeader header = aMsg.getHeader();
Object destNode = header.getHeader(MsgHeaderConstants.DEST_NODES);
if (destNode instanceof NodeInfo) {
destNode = new NodeInfo[] {(NodeInfo) destNode };
}
MsgOutInterceptor out;
NodeInfo[] dests = (NodeInfo[]) destNode;
for (int i = 0; i < dests.length; i++) {
NodeInfo target = dests[i];
Msg msg2 = new Msg(aMsg);
MsgHeader header2 = msg2.getHeader();
// A path is defined if this Msg is routed via the node
// owning this instance.
NodeInfo[] path =
(NodeInfo[]) header2.getOptionalHeader(
MsgHeaderConstants.DEST_NODE_PATH);
if ( null != path ) {
// A path has already been computed. Gets the next hop.
target = path[0];
// Pops the next hop from the path.
header2.addHeader(
MsgHeaderConstants.DEST_NODE_PATH,
NodeInfo.pop(path));
RemoteNode remoteNode = findRemoteNode(target);
if ( null == remoteNode ) {
throw new CommunicationException(target +
" has failed during a topology reconfiguration.");
}
out = remoteNode.getMsgConsumerOut();
} else {
// A path has not already been computed. Computes one.
NodeInfo src = (NodeInfo)
header2.getHeader(MsgHeaderConstants.SRC_NODE);
NodeTopology topo = markTopology(header2);
path = topo.getPath(src, target);
if (null == path) {
throw new CommunicationException("{" + target
+ "} is not reachable by {" + src +
"} in the topology " + topo);
}
RemoteNode remoteNode = findRemoteNode(path[0]);
if ( null == remoteNode ) {
throw new CommunicationException(path[0] +
" has failed during a topology reconfiguration.");
}
out = remoteNode.getMsgConsumerOut();
// Inserts the computed path and the new dests.
header2.addHeader(MsgHeaderConstants.DEST_NODE_PATH, NodeInfo.pop(path));
header2.addHeader(MsgHeaderConstants.DEST_NODES, target);
}
out.push(msg2);
}
}