/** * {@inheritDoc} * * <p>This is called by the Generic ResolverServiceImpl when processing a response to a query. */ public void processResponse(ResolverResponseMsg response) { if (!useRouteResolver) { // Route resolver disabled return; } if (LOG.isEnabledFor(Level.DEBUG)) { LOG.debug("processResponse got a response"); } // convert the response into a RouteResponse Reader ip = null; RouteResponse doc = null; try { ip = new StringReader(response.getResponse()); StructuredTextDocument asDoc = (StructuredTextDocument) StructuredDocumentFactory.newStructuredDocument(MimeMediaType.XMLUTF8, ip); doc = new RouteResponse(asDoc); } catch (Throwable e) { if (LOG.isEnabledFor(Level.DEBUG)) { LOG.debug("processResponse: malformed response - discard", e); } return; } finally { try { if (null != ip) { ip.close(); ip = null; } } catch (Throwable ignored) { } } RouteAdvertisement dstRoute = doc.getDestRoute(); RouteAdvertisement srcRoute = doc.getSrcRoute(); int queryId = response.getQueryId(); if ((dstRoute == null) || (srcRoute == null)) { if (LOG.isEnabledFor(Level.DEBUG)) { LOG.debug("processResponse: malformed response - discard."); } // Malformed response. Just discard. return; } EndpointAddress routingPeer = router.pid2addr(srcRoute.getDestPeerID()); EndpointAddress destPeer = router.pid2addr(dstRoute.getDestPeerID()); if ((routingPeer == null) || (destPeer == null)) { if (LOG.isEnabledFor(Level.DEBUG)) { LOG.debug("processResponse: malformed PeerID in response - discard."); } // Malformed response. Just discard. return; } // check if we have a negative route response if (queryId == NACKROUTE_QUERYID) { AccessPointAdvertisement badHop = dstRoute.nextHop(router.addr2pid(routingPeer)); PeerID badPeer = null; if (badHop != null) { badPeer = badHop.getPeerID(); } else { // the bad hop is the final destination badPeer = dstRoute.getDestPeerID(); } processBadRoute(badPeer, dstRoute); return; } // This is not our own peer adv, so we must not keep it // for more than its expiration time. // we only need to publish this route if // we don't know about it yet // XXX: here is where we could be more conservative and use isNormallyReachable() instead, thus // excluding // incoming messengers. if ((!router.isLocalRoute(router.pid2addr(srcRoute.getDestPeerID()))) && (!router.isRoutedRoute(router.pid2addr(srcRoute.getDestPeerID())))) { router.updateRouteAdv(srcRoute); } if (destPeer.equals(routingPeer)) { // The dest peer itself managed to respond to us. That means we // learned the route from the reverseRoute in the message // itself. So, there's nothing we need to do. if (LOG.isEnabledFor(Level.DEBUG)) { LOG.debug("learn route directly from the destination"); } } else { if (LOG.isEnabledFor(Level.DEBUG)) { LOG.debug("learn route:" + routingPeer); } try { // build the candidate route using the // route response from the respondant peer RouteAdvertisement candidateRoute = RouteAdvertisement.newRoute( router.addr2pid(destPeer), router.addr2pid(routingPeer), (Vector) dstRoute.getVectorHops().clone()); // cleanup the candidate route from any loop and remove the local peer extra // cycle RouteAdvertisement.cleanupLoop(candidateRoute, (PeerID) localPeerId); // Is there anything left in that route (or did the respondant // believe that we are the last hop on the route - which // obviously we are not. if (candidateRoute.size() == 0) { if (LOG.isEnabledFor(Level.DEBUG)) { LOG.debug("Route response outdated: NACK responder"); } generateNACKRoute( router.addr2pid(routingPeer), router.addr2pid(destPeer), dstRoute.getVectorHops()); return; } // get the address of the first hop in the route to verify that // we have a route (direct or long) to the first hop, so the route // is valid EndpointAddress candidateRouter = router.pid2addr(candidateRoute.getFirstHop().getPeerID()); // check that we have a direct connection to the first hop if (router.ensureLocalRoute(candidateRouter, null) == null) { // If we do not have a direct route to the candidate router check // for a long route in that case stich the route RouteAdvertisement routeToRouter = router.getRoute(candidateRouter, false); if (routeToRouter == null) { if (LOG.isEnabledFor(Level.DEBUG)) { LOG.debug("Route response useless: no route to next router hop"); } return; } // stich the route removing any loops and localPeer cycle if (RouteAdvertisement.stichRoute(candidateRoute, routeToRouter, (PeerID) localPeerId)) { router.setRoute(candidateRoute, false); } else { if (LOG.isEnabledFor(Level.DEBUG)) { LOG.debug("Route response error stiching route response"); } return; } } else { // we have a direct connection with the first hop of the candidate route // set the new route, which starts with the peer that replied to us. router.setRoute(candidateRoute, false); } } catch (Exception ex) { if (LOG.isEnabledFor(Level.DEBUG)) { LOG.debug("Route response exception when building response route" + ex); LOG.debug(" bad dstRoute: " + dstRoute.display()); } } if (LOG.isEnabledFor(Level.DEBUG)) { LOG.debug("finish process route response successfully"); } } }
/** @see net.jxta.resolver.QueryHandler#processResponse(ResolverResponseMsg) */ public void processResponse(ResolverResponseMsg response) { String responseString = response.getResponse(); _inToken = new StringToken(responseString); System.out.println("Got response:\n" + response.getResponse()); }