📄 endpointrouter.java
字号:
boolean found = false;
if (qReqAddr.equals(localPeerAddr)) {
found = true;
} else {
if (group.isRendezvous()) {
if (isLocalRoute(qReqAddr)) {
found = true;
} else {
route = getRoute(qReqAddr);
if (route != null) {
found = true;
}
}
}
}
if (!found) {
if (!group.isRendezvous()) {
throw new DiscardQueryException();
}
throw new NoResponseException();
}
try {
// Build the answer
doc = (StructuredTextDocument)
StructuredDocumentFactory.newStructuredDocument(
new MimeMediaType( "text/xml" ), "jxta:EndpointRouter");
Element e = null;
e = doc.createElement(VersionTag, Integer.toString(currentVersion));
doc.appendChild(e);
e = doc.createElement(TypeTag, RouteResponse);
doc.appendChild(e);
e = doc.createElement(DestPeerIdTag, qReqAddr);
doc.appendChild(e);
e = doc.createElement(RoutingPeerIdTag, localPeerAddr);
doc.appendChild(e);
if (route != null) {
e = doc.createElement(NbOfHopsTag, String.valueOf (route.nbOfHops + 1));
} else {
e = doc.createElement(NbOfHopsTag, String.valueOf (1));
}
doc.appendChild(e);
if (localPeerAdv != null) {
e = doc.createElement(RoutingPeerAdvTag, localPeerAdv);
doc.appendChild(e);
}
// The first gateway is the local peer
e = doc.createElement(GatewayForwardTag, localPeerAddr);
doc.appendChild(e);
if (route != null) {
Vector gateways = route.gateways;
String gateway = null;
if ((gateways != null) && (gateways.size() > 0)) {
for (int i = 0; i < gateways.size(); ++i) {
try {
gateway = (String) gateways.elementAt(i);
e = doc.createElement(GatewayForwardTag, gateway);
doc.appendChild(e);
} catch (Exception e1) {
continue;
}
}
}
}
StringWriter dumped = new StringWriter();
doc.sendToWriter( dumped );
ResolverResponse res = new ResolverResponse(routerSName,
null,
queryId,
dumped.toString() );
return res;
} catch (Exception ee) {
if (LOG.isEnabledFor(Priority.DEBUG)) LOG.debug("processQuery: error while processing query: ", ee);
throw new IOException();
}
}
// This class is used in order to add routing information
// to Messengers.
public class RouterMessenger implements EndpointMessenger {
protected EndpointMessenger messenger = null;
protected EndpointAddress destAddress = null;
protected EndpointRouter router = null;
public RouterMessenger(EndpointMessenger m,
EndpointAddress destAddress,
EndpointService e,
EndpointRouter r) {
if( m == null ) {
if (LOG.isEnabledFor(Priority.DEBUG)) LOG.debug( "null messenger!" );
throw new IllegalArgumentException( "null messenger!");
}
this.messenger = m;
this.destAddress = destAddress;
this.router = r;
}
public void sendMessage(Message message) throws IOException {
if (LOG.isEnabledFor(Priority.DEBUG)) LOG.debug("EndpointRouterMessenger.sendMessage starts");
InputStream ip = null;
EndpointRouterMessage routerMsg = null;
MessageElement elem = message.getElement(EndpointRouterMessage.Name);
if ((elem != null) && ((ip = elem.getStream())!= null)) {
try {
routerMsg = new EndpointRouterMessage(ip);
} catch (Exception ez1) {
// Can't read the element. Ignore it.
routerMsg = null;
}
}
if (routerMsg == null) {
// We need to create one.
if (LOG.isEnabledFor(Priority.DEBUG)) LOG.debug ("Create a new EndpointRouterMessage");
routerMsg = new EndpointRouterMessage();
routerMsg.setSrcAddress(router.localPeerAddr);
routerMsg.setNbOfHops ("1");
try {
Route route = router.getRoute (destAddress.getProtocolName() + "://" +
destAddress.getProtocolAddress());
if (route != null) {
if (route.gateways != null) {
routerMsg.setForwardGateways (route.gateways);
}
}
} catch (Exception ez1) {
// Not much we can do
if (LOG.isEnabledFor(Priority.WARN)) LOG.warn ("Cannot set forward gateways");
}
} else {
if (LOG.isEnabledFor(Priority.DEBUG)) LOG.debug ("Using EndpointRouterMessage");
// If we want to modify the routing header of forwarded
// messages, HERE is the best place to do it.
// Check if the destination within the message is the same
// as the destination peer of this messenger.
String inMsgDest = routerMsg.getDestAddress();
if ((inMsgDest != null) && (!inMsgDest.equals (destAddress.toString()))) {
// The destination address is not the same. It is very likely
// that the router message embedded within the message is
// invalid. Update it.
routerMsg.setForwardGateways (null);
try {
Route route = router.getRoute (destAddress.toString());
if (route != null) {
if (route.gateways != null) {
routerMsg.setForwardGateways (route.gateways);
int nbOfHops = route.gateways.size() + 1;
routerMsg.setNbOfHops (String.valueOf (nbOfHops));
}
}
} catch (Exception ez1) {
// Not much we can do
if (LOG.isEnabledFor(Priority.WARN)) LOG.warn ("Cannot set forward gateways");
}
}
// If the routerMsg still contains a potentially correct reverse route,
// check it, and if it is really correct, keep it. Otherwise, try to see
// if we have a reverse route anyway.
boolean reverse = false;
if (routerMsg.getReverseGateways() != null) {
reverse = isLocalRoute (routerMsg.getLastHop());
if (!reverse) {
routerMsg.setReverseGateways(null);
}
}
if (!reverse) {
// Fine, this peer does not have a reverse route to the
// last hop, but maybe it has a route to the source of the message.
if (getRoute (routerMsg.getSrcAddress()) != null) {
reverse = true;
} else {
reverse = isLocalRoute (routerMsg.getSrcAddress());
}
}
if (reverse) {
if (LOG.isEnabledFor(Priority.DEBUG)) LOG.debug (" setting reverse remote route");
// Add this local peer as a hop
Vector v = routerMsg.getReverseGateways();
if (v == null) {
v = new Vector(1);
}
try {
//PDA requirement 18.02.2002
// Vector.add -> Vector.insertElementAt
// v.add(0, localPeerAddr);
v.insertElementAt(localPeerAddr, 0);
} catch (Exception ez1) {
// Not much can be done here.
if (LOG.isEnabledFor(Priority.WARN)) LOG.warn ("Cannot insert local peer id in the reverse route");
}
try {
routerMsg.setNbOfHops
(String.valueOf (Integer.parseInt (routerMsg.getNbOfHops()) + 1));
} catch (Exception ez1) {
// Not much we can do here
if (LOG.isEnabledFor(Priority.WARN)) LOG.warn ("Got exception while trying to set the nbofHops " + ez1);
routerMsg.setNbOfHops ("0");
}
routerMsg.setReverseGateways (v);
} else {
// We really have no reverse route. Sorry.
if (LOG.isEnabledFor(Priority.DEBUG)) LOG.debug (" no reverse route");
routerMsg.setNbOfHops ("0"); //No reverse route
routerMsg.setReverseGateways (null);
}
}
routerMsg.setDestAddress(destAddress.toString());
routerMsg.setLastHop(router.localPeerAddr);
// Push the router header onto the message.
// That's all we have to do for now.
try {
message.addElement(
message.newMessageElement (EndpointRouterMessage.Name,
null,
routerMsg.getInputStream()));
} catch (Exception e) {
if (LOG.isEnabledFor(Priority.DEBUG)) LOG.debug("Can't push header");
}
// give the message to the real messenger
// NB, may be we SHOULD do getTransportMessenger EVERY TIME
// so that we can recover from broken routes.
if (messenger == null) {
throw new IOException ();
}
messenger.sendMessage(message);
}
public void close() {
}
}
// That's what upper layers call (through the endpoint API) to get
// a messenger to a peer-id based destination.
public EndpointMessenger getMessenger(EndpointAddress addr)
throws IOException {
// Extract the relevant components from this address.
String dstPAddr = addr.getProtocolName() + "://"
+ addr.getProtocolAddress();
// If the dest is the local peer, just loop it back without going
// through the router.
if (dstPAddr.equals (localPeerAddr)) {
if (LOG.isEnabledFor(Priority.DEBUG)) LOG.debug("getMessenger: return LoopbackMessenger");
return new LoopbackMessenger (endpoint,
endpoint.newEndpointAddress(localPeerAddr),
addr);
}
// Find an appropriate real transport messenger for this
// address.
EndpointMessenger m = getTransportMessenger(dstPAddr, false);
// Build a RouterMessenger around it that will add our header.
return new RouterMessenger(m, addr, endpoint, this);
}
// That's what does the job of actually finding the address and
// endpoint protocol to use to send the message to its next hop.
// If the local flag is true. We must not look for a route; just use
// a local route or fail.
// NB: we need to get rid of this stupid habit of sometimes returning null
// and sometimes throwing an exception.
private EndpointMessenger getTransportMessenger(String dstPAddr,
boolean local)
throws IOException {
// Find a raw transport address for this peer.
EndpointMessenger messenger = null;
boolean onceMore = true;
while (onceMore) {
onceMore=false;
Address naddr = null;
if (local) {
naddr = (Address) getLocalRoute(dstPAddr);
} else {
naddr = (Address) getAddress(dstPAddr);
}
if (naddr == null) {
// A null address has no protocol name. This equivalent to a non-existant
// protocol, which the endpoint service would respond to by returning null.
// which we handle below by throwing an exception. So, throw an exception here
// as well, instead of returning null.
if (LOG.isEnabledFor(Priority.WARN)) LOG.warn("getTransportMessenger: no address");
throw new IOException("getTransportMessenger: no address");
}
// Clone it. The original is in our tables and must not be
// messed with.
naddr = (Address) naddr.clone();
if (LOG.isEnabledFor(Priority.DEBUG)) LOG.debug("getMessenger(). " +
"dest peer= " + dstPAddr +
"using = " + naddr.toString());
// Complete this address with the router's service queue name
naddr.setServiceName (routerSName);
naddr.setServiceParameter (routerSParam);
// Find the appropriate raw messenger to use.
try {
messenger = endpoint.getMessenger(naddr);
break;
} catch(IOException noCheese) {
// find which local route is broken and purge it.
brokenRoute(dstPAddr);
}
}
// Some transports may return null rather than throwing. Convert.
if (messenger == null) {
if (LOG.isEnabledFor(Priority.INFO)) LOG.info("getMessenger: no messenger to "
+ dstPAddr);
throw new IOException("getTransportMessenger: no messenger");
}
return messenger;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -