// notify new node
 @Override
 public void publishActiveState(NodeID nodeID) throws GroupException {
   debugInfo("Publishing active state to nodeId: " + nodeID);
   Assert.assertTrue(isActiveCoordinator());
   GroupMessage msg =
       L2StateMessage.createElectionWonAlreadyMessage(
           EnrollmentFactory.createTrumpEnrollment(getLocalNodeID(), weightsFactory));
   L2StateMessage response = (L2StateMessage) groupManager.sendToAndWaitForResponse(nodeID, msg);
   validateResponse(nodeID, response);
 }
 @Override
 public void moveNodeToPassiveStandby(NodeID nodeID) {
   Assert.assertTrue(isActiveCoordinator());
   logger.info("Requesting node " + nodeID + " to move to " + PASSIVE_STANDBY);
   GroupMessage msg =
       L2StateMessage.createMoveToPassiveStandbyMessage(
           EnrollmentFactory.createTrumpEnrollment(getLocalNodeID(), weightsFactory));
   try {
     this.groupManager.sendTo(nodeID, msg);
   } catch (GroupException e) {
     logger.error(e);
   }
 }
 private void handleStartElectionRequest(L2StateMessage msg) throws GroupException {
   if (state == ACTIVE_COORDINATOR) {
     // This is either a new L2 joining a cluster or a renegade L2. Force it to abort
     GroupMessage abortMsg =
         L2StateMessage.createAbortElectionMessage(
             msg, EnrollmentFactory.createTrumpEnrollment(getLocalNodeID(), weightsFactory));
     info("Forcing Abort Election for " + msg + " with " + abortMsg);
     groupManager.sendTo(msg.messageFrom(), abortMsg);
   } else if (!electionMgr.handleStartElectionRequest(msg)) {
     // TODO::FIXME:: Commenting so that stage thread is not held up doing election.
     // startElectionIfNecessary(NodeID.NULL_ID);
     logger.warn("Not starting election as it was commented out");
   }
 }
  private NodeID doElection(NodeID myNodeId, boolean isNew, WeightGeneratorFactory weightsFactory)
      throws GroupException, InterruptedException {

    // Step 1: publish to cluster NodeID, weight and election start
    Enrollment e = EnrollmentFactory.createEnrollment(myNodeId, isNew, weightsFactory);
    electionStarted(e);

    L2StateMessage msg = createElectionStartedMessage(e);
    debugInfo("Sending my election vote to all members");
    groupManager.sendAll(msg);

    // Step 2: Wait for election completion
    waitTillElectionComplete();

    // Step 3: Compute Winner
    Enrollment lWinner = computeResult();
    if (lWinner != e) {
      logger.info("Election lost : Winner is : " + lWinner);
      Assert.assertNotNull(lWinner);
      return lWinner.getNodeID();
    }
    // Step 4 : local host won the election, so notify world for acceptance
    msg = createElectionResultMessage(e);
    debugInfo("Won election, announcing to world and waiting for response...");
    GroupResponse<L2StateMessage> responses = groupManager.sendAllAndWaitForResponse(msg);
    for (L2StateMessage response : responses.getResponses()) {
      Assert.assertEquals(msg.getMessageID(), response.inResponseTo());
      if (response.getType() == L2StateMessage.RESULT_AGREED) {
        Assert.assertEquals(e, response.getEnrollment());
      } else if (response.getType() == L2StateMessage.RESULT_CONFLICT) {
        logger.info(
            "Result Conflict: Local Result : "
                + e
                + " From : "
                + response.messageFrom()
                + " Result : "
                + response.getEnrollment());
        return ServerID.NULL_ID;
      } else {
        throw new AssertionError(
            "Node : "
                + response.messageFrom()
                + " responded neither with RESULT_AGREED or RESULT_CONFLICT :"
                + response);
      }
    }

    // Step 5 : result agreed - I am the winner
    return myNodeId;
  }
 private synchronized void handleElectionResultMessage(L2StateMessage msg) throws GroupException {
   if (activeNode.equals(msg.getEnrollment().getNodeID())) {
     Assert.assertFalse(ServerID.NULL_ID.equals(activeNode));
     // This wouldn't normally happen, but we agree - so ack
     GroupMessage resultAgreed =
         L2StateMessage.createResultAgreedMessage(msg, msg.getEnrollment());
     logger.info("Agreed with Election Result from " + msg.messageFrom() + " : " + resultAgreed);
     groupManager.sendTo(msg.messageFrom(), resultAgreed);
   } else if (state == ACTIVE_COORDINATOR
       || !activeNode.isNull()
       || (msg.getEnrollment().isANewCandidate() && state != START_STATE)) {
     // Condition 1 :
     // Obviously an issue.
     // Condition 2 :
     // This shouldn't happen normally, but is possible when there is some weird network error
     // where A sees B,
     // B sees A/C and C sees B and A is active and C is trying to run election
     // Force other node to rerun election so that we can abort
     // Condition 3 :
     // We don't want new L2s to win an election when there are old L2s in PASSIVE states.
     GroupMessage resultConflict =
         L2StateMessage.createResultConflictMessage(
             msg, EnrollmentFactory.createTrumpEnrollment(getLocalNodeID(), weightsFactory));
     warn(
         "WARNING :: Active Node = "
             + activeNode
             + " , "
             + state
             + " received ELECTION_RESULT message from another node : "
             + msg
             + " : Forcing re-election "
             + resultConflict);
     groupManager.sendTo(msg.messageFrom(), resultConflict);
   } else {
     debugInfo("ElectionMgr handling election result msg: " + msg);
     electionMgr.handleElectionResultMessage(msg);
   }
 }