/** * Make this transport as up and running. * * <p>When this method is called, all the services are already registered with the peergroup. So * we do not need to delay binding any further. All the public methods, which could be called * between init and startApp are defensive regarding the services possibly not being there. */ public int startApp(String[] arg) { resolver = group.getResolverService(); membership = group.getMembershipService(); if (null == resolver) { if (LOG.isEnabledFor(Level.DEBUG)) { LOG.debug("Endpoint Router start stalled until resolver service available"); } return Module.START_AGAIN_STALLED; } if (null == membership) { if (LOG.isEnabledFor(Level.DEBUG)) { LOG.debug("Endpoint Router start stalled until membership service available"); } return Module.START_AGAIN_STALLED; } resolver.registerHandler(routerSName, this); // create and register the srdi service srdiIndex = new SrdiIndex(group, srdiIndexerFileName); // Srdi is a thread but we are not going to start, // since the service is reactive. srdi = new Srdi(group, routerSName, this, srdiIndex, 0, 0); resolver.registerSrdiHandler(routerSName, this); // obtain credential for resolver messages try { // FIXME 20041008 bondolo this needs to be converted to dynamically managing credentials. // get the only credential "nobody" credential = (Credential) membership.getDefaultCredential(); if (null != credential) { credentialDoc = credential.getDocument(MimeMediaType.XMLUTF8); } } catch (Exception e) { if (LOG.isEnabledFor(Level.ERROR)) { LOG.error("failed to get credential", e); } } // get the RouteCM cache service routeCM = router.getRouteCM(); return 0; }
/** * issue a new route discovery resolver request * * @param peer the destination as a logical enpoint address */ protected void findRoute(EndpointAddress peer) { RouteAdvertisement myRoute = router.getMyLocalRoute(); // No need to pursue further if we haven't // initialize our own route as responding // peers are not going to be able to respond to us. if (myRoute == null) { if (LOG.isEnabledFor(Level.DEBUG)) { LOG.debug("Cannot issue a find route if we don't know our own route"); } return; } if (LOG.isEnabledFor(Level.DEBUG)) { LOG.debug("Find route for peer = " + peer); } try { // create a new RouteQuery message RouteQuery doc = null; // check if we have some bad route information // for that peer, in that case pass the bad hop count BadRoute badRoute; badRoute = (BadRoute) router.getBadRoute(peer); if (badRoute != null) { // ok we have a bad route // pass the bad hops info as part of the query if (LOG.isEnabledFor(Level.DEBUG)) { LOG.debug("findRoute sends query: known bad Hops" + badRoute.display()); } doc = new RouteQuery(router.addr2pid(peer), myRoute, badRoute.getHops()); } else { doc = new RouteQuery(router.addr2pid(peer), myRoute, null); } if (LOG.isEnabledFor(Level.DEBUG)) { LOG.debug("Sending query for peer : " + peer); } ResolverQuery query = new ResolverQuery( routerSName, credentialDoc, localPeerId.toString(), doc.toString(), qid++); // only run SRDI if we are a rendezvous if (group.isRendezvous()) { // check where to send the query via SRDI Vector results = null; if (srdiIndex != null) { // try to find a least 10 entries, will pick up one // randomly. This will protect against retry. It is // likely that a number of RDV will know about a route results = srdiIndex.query("route", "DstPID", router.addr2pid(peer).toString(), 10); if (results != null && results.size() > 0) { // use SRDI to send the query // remove any non rdv peers from the candidate list // and garbage collect the index in the process Vector clean = cleanupAnyEdges(query.getSrc(), results); if (clean.size() > 0) { // The purpose of incrementing the hopcount // when an SRDI index match is found (we got a // pointer to a rdv that should have the route) is to // restrict any further forwarding. The increment // count is only done when a matching SRDI index is // found. Not when the replica is selected as we // still need to forward the query. This restriction // is purposelly done to avoid too many longjumps // within a walk. query.incrementHopCount(); srdi.forwardQuery(clean, query, 1); if (LOG.isEnabledFor(Level.DEBUG)) { LOG.debug("found an srdi entry forwarding query to SRDI peer"); } return; } } else { // it is not in our cache, look for the replica peer // we need to send the query PeerID destPeer = srdi.getReplicaPeer(router.addr2pid(peer).toString()); if (destPeer != null && !destPeer.equals(localPeerId)) { // don't push anywhere if we do not have a replica // or we are trying to push to ourself if (LOG.isEnabledFor(Level.DEBUG)) { LOG.debug("processQuery srdiIndex DHT forward :" + destPeer); } srdi.forwardQuery(destPeer.toString(), query); return; } } } } // if we reach that point then we just use the resolver walk resolver = group.getResolverService(); if (resolver != null) { resolver.sendQuery(null, query); if (LOG.isEnabledFor(Level.DEBUG)) { LOG.debug("find route query sent"); } } else { if (LOG.isEnabledFor(Level.WARN)) { LOG.warn("cannot get the resolver service"); } } } catch (Exception ee) { if (LOG.isEnabledFor(Level.WARN)) { LOG.warn("Exception in findRoute", ee); } } }