Esempio n. 1
0
  /** @see net.jxta.resolver.QueryHandler#processQuery(ResolverQueryMsg) */
  public ResolverResponseMsg processQuery(ResolverQueryMsg query)
      throws NoResponseException, ResendQueryException, DiscardQueryException, IOException {
    System.out.println("Got query from " + query.getSrc() + " " + query.getQueryId());
    System.out.println("Query is:\n" + query.getQuery());

    if (_actorQueryResponse == null) {
      throw new DiscardQueryException();
    }

    System.out.println("Send query response...");
    _actorQueryResponse.setQueryId(query.getQueryId());
    return _actorQueryResponse;
  }
Esempio n. 2
0
  /**
   * Process the Query, and generate response
   *
   * @param query the query to process
   */
  public int processQuery(ResolverQueryMsg query) {

    if (!useRouteResolver) { // Route resolver disabled
      return ResolverService.OK;
    }

    if (LOG.isEnabledFor(Level.DEBUG)) {
      LOG.debug("processQuery starts");
    }

    RouteQuery routeQuery = null;
    Reader ip = null;

    try {
      ip = new StringReader(query.getQuery());

      StructuredTextDocument asDoc =
          (StructuredTextDocument)
              StructuredDocumentFactory.newStructuredDocument(MimeMediaType.XMLUTF8, ip);

      routeQuery = new RouteQuery(asDoc);

    } catch (Throwable e) {
      if (LOG.isEnabledFor(Level.DEBUG)) {
        LOG.debug("Malformed Route query ", e);
      }
      return ResolverService.OK;
    } finally {
      try {
        if (null != ip) {
          ip.close();
          ip = null;
        }
      } catch (Throwable ignored) {;
      }
    }

    PeerID pId = routeQuery.getDestPeerID();

    if (LOG.isEnabledFor(Level.DEBUG)) {
      LOG.debug("processQuery: looking for route to " + pId);
    }

    RouteAdvertisement srcRoute = routeQuery.getSrcRoute();
    List badHops = routeQuery.getBadHops();

    if (LOG.isEnabledFor(Level.DEBUG)) {
      if (badHops != null) {
        LOG.debug("processQuery: bad Hops");
        for (int i = 0; i < badHops.size(); i++) {
          LOG.debug("processQuery:   :" + ((PeerID) badHops.get(i)).toString());
        }
      }
    }
    // if our source route is not null, then publish it
    if (srcRoute != null) {
      if (!(srcRoute.getDestPeerID()).equals(localPeerId)) {
        // This is not our own peer adv so we must not keep it
        // longer than its expiration time.
        try {
          if (LOG.isEnabledFor(Level.DEBUG)) {
            LOG.debug("processQuery: publishing sender route info " + srcRoute.getDestPeerID());
          }

          // 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())))) {
            routeCM.publishRoute(srcRoute);
          }
        } catch (Exception e) {
          if (LOG.isEnabledFor(Level.DEBUG)) {
            LOG.debug("Could not publish Route Adv from query - discard", e);
          }
          return ResolverService.OK;
        }
      }
    } else {
      if (LOG.isEnabledFor(Level.DEBUG)) {
        LOG.debug("No src Route in route query - discard ");
      }
      return ResolverService.OK;
    }

    if (pId == null) {
      if (LOG.isEnabledFor(Level.DEBUG)) {
        LOG.debug("Malformed route query request, no PeerId - discard");
      }
      return ResolverService.OK;
    }

    // We have more luck with that one because, since it is part of OUR
    // message, and not part of the resolver protocol, it is in OUR
    // format.
    EndpointAddress qReqAddr = router.pid2addr(pId);

    RouteAdvertisement route = null;

    // check if this peer has a route to the destination
    // requested
    boolean found = false;

    if (qReqAddr.equals(localPeerAddr)) {
      found = true;
      // return the route that is my local route
      route = router.getMyLocalRoute();
    } else {
      // only rendezvous can respond to route requests
      // if not we are generating too much traffic
      // XXX: here is where we could be more conservative and use isNormallyReachable() instead,
      // thus excluding
      // incoming messengers.
      if (router.isLocalRoute(qReqAddr)) {
        if (LOG.isEnabledFor(Level.DEBUG)) {
          LOG.debug("processQuery: peer has direct route to destination ");
        }
        // we should set the route to something  :-)

        found = true;

        // this peer has a direct route to the destination
        // return the short route advertisement we know for this peer
        // (For us it is zero hop, and we advertise ourself as the routing
        // peer in the response. The stiching is done by whoever gets that
        // response). May be there are more than one hop advertised in-there...
        // alternate routing peers...should we leave them ?
        // For now, we keep the full dest, but wack the hops.

        route =
            (RouteAdvertisement)
                AdvertisementFactory.newAdvertisement(RouteAdvertisement.getAdvertisementType());

        AccessPointAdvertisement ap =
            (AccessPointAdvertisement)
                AdvertisementFactory.newAdvertisement(
                    AccessPointAdvertisement.getAdvertisementType());

        ap.setPeerID(pId);
        route.setDest(ap);

      } else {

        route = router.getRoute(qReqAddr, false);
        if (route != null) {
          found = true;
          // check if we were given some bad hops info
          // and see if the found route contains
          // any of these bad hops. In that case, we need
          // to mark this route as bad
          for (int i = 0; i < badHops.size(); i++) {

            // destination is known to be bad
            if (router.addr2pid(qReqAddr).equals(((PeerID) badHops.get(i)))) {
              processBadRoute((PeerID) badHops.get(i), route);
              found = false;
              break;
            }

            if (route.containsHop((PeerID) badHops.get(i))) {
              if (LOG.isEnabledFor(Level.DEBUG)) {
                LOG.debug(
                    "processQuery: peer has bad route due to "
                        + ((PeerID) badHops.get(i)).toString());
              }
              processBadRoute((PeerID) badHops.get(i), route);
              found = false;
              break;
            }
          }
        }
      }
    }

    if (!found) {
      // discard the request if we are not a rendezvous
      // else forward to the next peers
      if (!group.isRendezvous()) {
        if (LOG.isEnabledFor(Level.DEBUG)) {
          LOG.debug("discard query forwarding as not a rendezvous");
        }
        return ResolverService.OK;
      }

      // did not find a route, check our srdi cache
      // make sure we protect against out of sync
      // SRDI index

      // srdi forwarding is only involved once the Index entry has
      // been found and we forwarded the resolver query. Afterward a
      // normal walk proceeds from the initial SRDI index pointing
      // rdv. This is done to protect against potential loopback
      // entries in the SRDI cache index due to out of sync peerview
      // and index.
      if (query.getHopCount() < 2) {

        // check local SRDI cache to see if we have the entry
        // we look for 10 entries, will pickup one randomly
        Vector results = srdiIndex.query("route", "DstPID", pId.toString(), 10);

        if (results.size() > 0) {
          if (LOG.isEnabledFor(Level.DEBUG)) {
            LOG.debug("processQuery srdiIndex lookup match :" + results.size());
          }

          // remove any non-rdv peers to avoid sending
          // to a non-rdv peers and garbage collect the SRDI
          // index in the process
          Vector clean = cleanupAnyEdges(query.getSrc(), results);

          if (clean.size() > 0) {

            if (LOG.isEnabledFor(Level.DEBUG)) {
              LOG.debug("found an srdi entry forwarding query to SRDI peer");
            }

            // 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();

            // Note: this forwards the query to 1 peer randomly
            // selected from the result
            srdi.forwardQuery(clean, query, 1);

            // tell the resolver no further action is needed.
            return ResolverService.OK;
          }
        }
      }

      if (LOG.isEnabledFor(Level.DEBUG)) {
        LOG.debug("did not find a route or SRDI index");
      }

      // force a walk
      return ResolverService.Repropagate;
    }

    // we found a route send the response
    try {
      if (route == null) {
        if (LOG.isEnabledFor(Level.DEBUG)) {
          LOG.debug("we should have had a route at this point");
        }
        return ResolverService.OK;
      }

      if (LOG.isEnabledFor(Level.DEBUG)) {
        LOG.debug("processQuery: we have a route build route response" + route.display());
      }

      RouteAdvertisement myRoute = router.getMyLocalRoute();

      // make sure we initialized our local
      // route info as we will need it to respond. We may
      // not have our route if we are still
      // waiting for a relay connection.
      if (myRoute == null) {
        return ResolverService.OK;
      }

      RouteResponse routeResponse = new RouteResponse();

      routeResponse.setDestRoute(route);
      routeResponse.setSrcRoute(myRoute);

      if (routeResponse == null) {
        if (LOG.isEnabledFor(Level.DEBUG)) {
          LOG.debug("error creating route response");
        }
        return ResolverService.OK;
      }

      // construct a response from the query
      ResolverResponseMsg res = query.makeResponse();

      res.setCredential(credentialDoc);
      res.setResponse(routeResponse.toString());

      resolver.sendResponse(query.getSrc(), res);
      return ResolverService.OK;

    } catch (Exception ee) {
      if (LOG.isEnabledFor(Level.DEBUG)) {
        LOG.debug("processQuery: error while processing query ", ee);
      }
      return ResolverService.OK;
    }
  }