Esempio n. 1
0
  /**
   * Sends the new view and digest to all subgroup coordinors in coords. Each coord will in turn
   *
   * <ol>
   *   <li>broadcast the new view and digest to all the members of its subgroup (MergeView)
   *   <li>on reception of the view, if it is a MergeView, each member will set the digest and
   *       install the new view
   * </ol>
   */
  private void sendMergeView(
      Collection<Address> coords, MergeData combined_merge_data, MergeId merge_id) {
    if (coords == null || combined_merge_data == null) return;

    View view = combined_merge_data.view;
    Digest digest = combined_merge_data.digest;
    if (view == null || digest == null) {
      if (log.isErrorEnabled())
        log.error("view or digest is null, cannot send consolidated merge view/digest");
      return;
    }

    if (log.isDebugEnabled())
      log.debug(
          gms.local_addr + ": sending merge view " + view.getVid() + " to coordinators " + coords);

    gms.merge_ack_collector.reset(coords);
    int size = gms.merge_ack_collector.size();
    long timeout = gms.view_ack_collection_timeout;

    long start = System.currentTimeMillis();
    for (Address coord : coords) {
      Message msg = new Message(coord, null, null);
      GMS.GmsHeader hdr = new GMS.GmsHeader(GMS.GmsHeader.INSTALL_MERGE_VIEW);
      hdr.view = view;
      hdr.my_digest = digest;
      hdr.merge_id = merge_id;
      msg.putHeader(gms.getId(), hdr);
      gms.getDownProtocol().down(new Event(Event.MSG, msg));
    }

    // [JGRP-700] - FLUSH: flushing should span merge
    // if flush is in stack wait for acks from separated island coordinators
    if (gms.flushProtocolInStack) {
      try {
        gms.merge_ack_collector.waitForAllAcks(timeout);
        long stop = System.currentTimeMillis();
        if (log.isTraceEnabled())
          log.trace(
              "received all ACKs ("
                  + size
                  + ") for merge view "
                  + view
                  + " in "
                  + (stop - start)
                  + "ms");
      } catch (TimeoutException e) {
        log.warn(
            gms.local_addr
                + ": failed to collect all ACKs for merge ("
                + size
                + ") for view "
                + view
                + " after "
                + timeout
                + "ms, missing ACKs from "
                + gms.merge_ack_collector.printMissing());
      }
    }
  }
Esempio n. 2
0
    /**
     * Sends a MERGE_REQ to all coords and populates a list of MergeData (in merge_rsps). Returns
     * after coords.size() response have been received, or timeout msecs have elapsed (whichever is
     * first).
     *
     * <p>If a subgroup coordinator rejects the MERGE_REQ (e.g. because of participation in a
     * different merge), <em>that member will be removed from coords !</em>
     *
     * @param coords A map of coordinatgor addresses and associated membership lists
     * @param new_merge_id The new merge id
     * @param timeout Max number of msecs to wait for the merge responses from the subgroup coords
     */
    private boolean getMergeDataFromSubgroupCoordinators(
        Map<Address, Collection<Address>> coords, MergeId new_merge_id, long timeout) {
      boolean gotAllResponses;
      long start = System.currentTimeMillis();
      merge_rsps.reset(coords.keySet());
      if (log.isDebugEnabled())
        log.debug(gms.local_addr + ": sending MERGE_REQ to " + coords.keySet());

      for (Map.Entry<Address, Collection<Address>> entry : coords.entrySet()) {
        Address coord = entry.getKey();
        Collection<Address> mbrs = entry.getValue();
        Message msg = new Message(coord, null, null);
        msg.setFlag(Message.OOB);
        GMS.GmsHeader hdr = new GMS.GmsHeader(GMS.GmsHeader.MERGE_REQ, mbrs);
        hdr.mbr = gms.local_addr;
        hdr.merge_id = new_merge_id;
        msg.putHeader(gms.getId(), hdr);
        gms.getDownProtocol().down(new Event(Event.MSG, msg));
      }

      // wait until num_rsps_expected >= num_rsps or timeout elapsed
      merge_rsps.waitForAllResponses(timeout);
      gotAllResponses = merge_rsps.hasAllResponses();
      long stop = System.currentTimeMillis();
      if (log.isDebugEnabled())
        log.debug(
            gms.local_addr
                + ": collected "
                + merge_rsps.size()
                + " merge response(s) in "
                + (stop - start)
                + " ms");
      return gotAllResponses;
    }
Esempio n. 3
0
 /**
  * Fetches the digests from all members and installs them again. Used only for diagnosis and
  * support; don't use this otherwise !
  */
 void fixDigests() {
   Digest digest = fetchDigestsFromAllMembersInSubPartition(gms.view.getMembers());
   Message msg = new Message();
   GMS.GmsHeader hdr = new GMS.GmsHeader(GMS.GmsHeader.INSTALL_DIGEST);
   hdr.my_digest = digest;
   msg.putHeader(gms.getId(), hdr);
   gms.getDownProtocol().down(new Event(Event.MSG, msg));
 }
Esempio n. 4
0
 protected void sendMergeRejectionMessage(Address dest) {
   Message msg = new Message(dest).setFlag(Message.Flag.OOB);
   GMS.GmsHeader hdr = new GMS.GmsHeader(GMS.GmsHeader.MERGE_RSP);
   hdr.setMergeRejected(true);
   msg.putHeader(gms_id, hdr);
   if (log.isDebugEnabled()) log.debug("merge response=" + hdr);
   down_prot.down(new Event(Event.MSG, msg));
 }
Esempio n. 5
0
 protected void sendMergeRejectedResponse(Address sender, MergeId merge_id) {
   Message msg = new Message(sender).setFlag(Message.Flag.OOB, Message.Flag.INTERNAL);
   GMS.GmsHeader hdr = new GMS.GmsHeader(GMS.GmsHeader.MERGE_RSP);
   hdr.merge_rejected = true;
   hdr.merge_id = merge_id;
   msg.putHeader(gms.getId(), hdr);
   gms.getDownProtocol().down(new Event(Event.MSG, msg));
 }
Esempio n. 6
0
 protected void sendMergeRejectedResponse(Address sender, MergeId merge_id) {
   Message msg = new Message(sender, null, null);
   msg.setFlag(Message.OOB);
   GMS.GmsHeader hdr = new GMS.GmsHeader(GMS.GmsHeader.MERGE_RSP);
   hdr.merge_rejected = true;
   hdr.merge_id = merge_id;
   msg.putHeader(gms.getId(), hdr);
   if (log.isDebugEnabled()) log.debug("merge response=" + hdr);
   gms.getDownProtocol().down(new Event(Event.MSG, msg));
 }
Esempio n. 7
0
 /** Send back a response containing view and digest to sender */
 private void sendMergeResponse(Address sender, View view, Digest digest, MergeId merge_id) {
   Message msg = new Message(sender).setFlag(Message.Flag.OOB, Message.Flag.INTERNAL);
   GMS.GmsHeader hdr = new GMS.GmsHeader(GMS.GmsHeader.MERGE_RSP);
   hdr.merge_id = merge_id;
   hdr.view = view;
   hdr.my_digest = digest;
   msg.putHeader(gms.getId(), hdr);
   if (log.isTraceEnabled()) log.trace(gms.local_addr + ": sending merge response=" + hdr);
   gms.getDownProtocol().down(new Event(Event.MSG, msg));
 }
Esempio n. 8
0
  private void sendMergeCancelledMessage(Collection<Address> coords, MergeId merge_id) {
    if (coords == null || merge_id == null) return;

    for (Address coord : coords) {
      Message msg = new Message(coord);
      // msg.setFlag(Message.Flag.OOB);
      GMS.GmsHeader hdr = new GMS.GmsHeader(GMS.GmsHeader.CANCEL_MERGE);
      hdr.merge_id = merge_id;
      msg.putHeader(gms.getId(), hdr);
      gms.getDownProtocol().down(new Event(Event.MSG, msg));
    }
  }
Esempio n. 9
0
  private void sendMergeCancelledMessage(Collection<Address> coords, MergeId merge_id) {
    if (coords == null || merge_id == null) return;

    for (Address coord : coords) {
      Message msg = new Message(coord, null, null);
      // msg.setFlag(Message.OOB);
      GMS.GmsHeader hdr = new GMS.GmsHeader(GMS.GmsHeader.CANCEL_MERGE);
      hdr.merge_id = merge_id;
      msg.putHeader(gms.getId(), hdr);
      if (log.isDebugEnabled()) log.debug(gms.local_addr + ": sending cancel merge to " + coord);
      gms.getDownProtocol().down(new Event(Event.MSG, msg));
    }
  }
Esempio n. 10
0
 /**
  * Handles a GMS header
  *
  * @param gms_hdr
  * @param msg
  * @return true if the message should be passed up, or else false
  */
 protected boolean handleAuthHeader(GMS.GmsHeader gms_hdr, AuthHeader auth_hdr, Message msg) {
   switch (gms_hdr.getType()) {
     case GMS.GmsHeader.JOIN_REQ:
     case GMS.GmsHeader.JOIN_REQ_WITH_STATE_TRANSFER:
     case GMS.GmsHeader.MERGE_REQ:
       if (this.auth_token.authenticate(auth_hdr.getToken(), msg))
         return true; //  authentication passed, send message up the stack
       log.warn(
           "failed to validate AuthHeader token from " + msg.getSrc() + ", token: " + auth_token);
       sendRejectionMessage(gms_hdr.getType(), msg.getSrc(), "authentication failed");
       return false;
     default:
       return true; // pass up
   }
 }
Esempio n. 11
0
  public void up(MessageBatch batch) {
    for (Message msg : batch) {
      // If we have a join or merge request --> authenticate, else pass up
      GMS.GmsHeader gms_hdr = getGMSHeader(msg);
      if (gms_hdr != null && needsAuthentication(gms_hdr)) {
        AuthHeader auth_hdr = (AuthHeader) msg.getHeader(id);
        if (auth_hdr == null) {
          log.warn("found GMS join or merge request but no AUTH header");
          sendRejectionMessage(
              gms_hdr.getType(), batch.sender(), "join or merge without an AUTH header");
          batch.remove(msg);
        } else if (!handleAuthHeader(gms_hdr, auth_hdr, msg)) // authentication failed
        batch.remove(msg); // don't pass up
      }
    }

    if (!batch.isEmpty()) up_prot.up(batch);
  }
Esempio n. 12
0
  /**
   * Multicasts a GET_DIGEST_REQ to all current members and waits for all responses (GET_DIGEST_RSP)
   * or N ms.
   *
   * @return
   */
  private Digest fetchDigestsFromAllMembersInSubPartition(
      List<Address> current_mbrs, MergeId merge_id) {

    // Optimization: if we're the only member, we don't need to multicast the get-digest message
    if (current_mbrs == null
        || current_mbrs.size() == 1 && current_mbrs.get(0).equals(gms.local_addr))
      return (Digest) gms.getDownProtocol().down(new Event(Event.GET_DIGEST, gms.local_addr));

    GMS.GmsHeader hdr = new GMS.GmsHeader(GMS.GmsHeader.GET_DIGEST_REQ);
    hdr.merge_id = merge_id;
    Message get_digest_req =
        new Message().setFlag(Message.Flag.OOB, Message.Flag.INTERNAL).putHeader(gms.getId(), hdr);

    long max_wait_time =
        gms.merge_timeout / 2; // gms.merge_timeout is guaranteed to be > 0, verified in init()
    digest_collector.reset(current_mbrs);

    gms.getDownProtocol().down(new Event(Event.MSG, get_digest_req));

    // add my own digest first - the get_digest_req needs to be sent first *before* getting our own
    // digest, so
    // we have that message in our digest !
    Digest digest =
        (Digest) gms.getDownProtocol().down(new Event(Event.GET_DIGEST, gms.local_addr));
    digest_collector.add(gms.local_addr, digest);
    digest_collector.waitForAllResponses(max_wait_time);
    if (log.isTraceEnabled()) {
      if (digest_collector.hasAllResponses())
        log.trace(gms.local_addr + ": fetched all digests for " + current_mbrs);
      else
        log.trace(
            gms.local_addr
                + ": fetched incomplete digests (after timeout of "
                + max_wait_time
                + ") ms for "
                + current_mbrs);
    }
    Map<Address, Digest> responses = new HashMap<Address, Digest>(digest_collector.getResults());
    MutableDigest retval = new MutableDigest(responses.size());
    for (Digest dig : responses.values()) {
      if (dig != null) retval.add(dig);
    }
    return retval;
  }
Esempio n. 13
0
 /**
  * Handles a GMS header
  *
  * @param gms_hdr
  * @param msg
  * @return true if the message should be passed up, or else false
  */
 protected boolean handleAuthHeader(GMS.GmsHeader gms_hdr, AuthHeader auth_hdr, Message msg) {
   if (needsAuthentication(gms_hdr)) {
     if (this.auth_token.authenticate(auth_hdr.getToken(), msg))
       return true; //  authentication passed, send message up the stack
     else {
       log.warn(
           "%s: failed to validate AuthHeader (token: %s) from %s; dropping message",
           local_addr, auth_token.getClass().getSimpleName(), msg.src());
       sendRejectionMessage(gms_hdr.getType(), msg.getSrc(), "authentication failed");
       return false;
     }
   }
   return true;
 }
Esempio n. 14
0
 protected boolean needsAuthentication(GMS.GmsHeader hdr) {
   switch (hdr.getType()) {
     case GMS.GmsHeader.JOIN_REQ:
     case GMS.GmsHeader.JOIN_REQ_WITH_STATE_TRANSFER:
     case GMS.GmsHeader.MERGE_REQ:
       return true;
     case GMS.GmsHeader.JOIN_RSP:
     case GMS.GmsHeader.MERGE_RSP:
     case GMS.GmsHeader.INSTALL_MERGE_VIEW:
       return this.authenticate_coord;
     default:
       return false;
   }
 }
Esempio n. 15
0
 protected static boolean needsAuthentication(GMS.GmsHeader hdr) {
   return hdr.getType() == GMS.GmsHeader.JOIN_REQ
       || hdr.getType() == GMS.GmsHeader.JOIN_REQ_WITH_STATE_TRANSFER
       || hdr.getType() == GMS.GmsHeader.MERGE_REQ;
 }