Java Code Examples for org.apache.helix.model.CurrentState#getState()

The following examples show how to use org.apache.helix.model.CurrentState#getState() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: TestP2PNoDuplicatedMessage.java    From helix with Apache License 2.0 6 votes vote down vote up
private void verifyP2PDisabled() {
  ResourceControllerDataProvider dataCache = new ResourceControllerDataProvider(CLUSTER_NAME);
  dataCache.refresh(_accessor);
  Map<String, LiveInstance> liveInstanceMap = dataCache.getLiveInstances();

  for (LiveInstance instance : liveInstanceMap.values()) {
    Map<String, CurrentState> currentStateMap =
        dataCache.getCurrentState(instance.getInstanceName(), instance.getEphemeralOwner());
    Assert.assertNotNull(currentStateMap);
    for (CurrentState currentState : currentStateMap.values()) {
      for (String partition : currentState.getPartitionStateMap().keySet()) {
        String state = currentState.getState(partition);
        if (state.equalsIgnoreCase("MASTER")) {
          String triggerHost = currentState.getTriggerHost(partition);
          Assert.assertEquals(triggerHost, _controllerName,
              state + " of " + partition + " on " + instance.getInstanceName()
                  + " was triggered by " + triggerHost);
        }
      }
    }
  }
}
 
Example 2
Source File: TestP2PNoDuplicatedMessage.java    From helix with Apache License 2.0 6 votes vote down vote up
private void verifyP2PEnabled(long startTime) {
  ResourceControllerDataProvider dataCache = new ResourceControllerDataProvider(CLUSTER_NAME);
  dataCache.refresh(_accessor);
  Map<String, LiveInstance> liveInstanceMap = dataCache.getLiveInstances();

  for (LiveInstance instance : liveInstanceMap.values()) {
    Map<String, CurrentState> currentStateMap =
        dataCache.getCurrentState(instance.getInstanceName(), instance.getEphemeralOwner());
    Assert.assertNotNull(currentStateMap);
    for (CurrentState currentState : currentStateMap.values()) {
      for (String partition : currentState.getPartitionStateMap().keySet()) {
        String state = currentState.getState(partition);
        long start = currentState.getStartTime(partition);
        if (state.equalsIgnoreCase("MASTER") && start > startTime) {
          String triggerHost = currentState.getTriggerHost(partition);
          if (!triggerHost.equals(_controllerName)) {
            p2pTrigged ++;
          }
          total ++;
        }
      }
    }
  }
}
 
Example 3
Source File: CustomCodeInvoker.java    From helix with Apache License 2.0 5 votes vote down vote up
private void callParticipantCode(NotificationContext context) {
  // since ZkClient.unsubscribe() does not immediately remove listeners
  // from zk, it is possible that two listeners exist when leadership transfers
  // therefore, double check to make sure only one participant invokes the code
  if (context.getType() == Type.CALLBACK) {
    HelixManager manager = context.getManager();
    // DataAccessor accessor = manager.getDataAccessor();
    HelixDataAccessor accessor = manager.getHelixDataAccessor();
    Builder keyBuilder = accessor.keyBuilder();

    String instance = manager.getInstanceName();
    String sessionId = manager.getSessionId();

    // get resource name from partition key: "PARTICIPANT_LEADER_XXX_0"
    String resourceName = _partitionKey.substring(0, _partitionKey.lastIndexOf('_'));

    CurrentState curState =
        accessor.getProperty(keyBuilder.currentState(instance, sessionId, resourceName));
    if (curState == null) {
      return;
    }

    String state = curState.getState(_partitionKey);
    if (state == null || !state.equalsIgnoreCase("LEADER")) {
      return;
    }
  }

  try {
    _callback.onCallback(context);
  } catch (Exception e) {
    LOG.error("Error invoking callback:" + _callback, e);
  }
}
 
Example 4
Source File: TestP2PMessageSemiAuto.java    From helix with Apache License 2.0 5 votes vote down vote up
private void verifyP2PMessage(String dbName, String instance, String expectedState,
    String expectedTriggerHost, double expectedRatio) {
  ResourceControllerDataProvider dataCache = new ResourceControllerDataProvider(CLUSTER_NAME);
  dataCache.refresh(_accessor);

  Map<String, LiveInstance> liveInstanceMap = dataCache.getLiveInstances();
  LiveInstance liveInstance = liveInstanceMap.get(instance);

  Map<String, CurrentState> currentStateMap =
      dataCache.getCurrentState(instance, liveInstance.getEphemeralOwner());
  Assert.assertNotNull(currentStateMap);
  CurrentState currentState = currentStateMap.get(dbName);
  Assert.assertNotNull(currentState);
  Assert.assertEquals(currentState.getPartitionStateMap().size(), PARTITION_NUMBER);

  int total = 0;
  int expectedHost = 0;
  for (String partition : currentState.getPartitionStateMap().keySet()) {
    String state = currentState.getState(partition);
    Assert.assertEquals(state, expectedState,
        dbName + " Partition " + partition + "'s state is different as expected!");
    String triggerHost = currentState.getTriggerHost(partition);
    if (triggerHost.equals(expectedTriggerHost)) {
      expectedHost++;
    }
    total++;
  }

  double ratio = ((double) expectedHost) / ((double) total);
  Assert.assertTrue(ratio >= expectedRatio,
      String.format(
          "Only %d out of %d percent transitions to Master were triggered by expected host!",
          expectedHost, total));
}
 
Example 5
Source File: InstanceMessagesCache.java    From helix with Apache License 2.0 4 votes vote down vote up
private void checkTargetHost(String targetHost, Message relayMessage, Map<String, LiveInstance> liveInstanceMap,
    Map<String, Map<String, Map<String, CurrentState>>> currentStateMap) {

  long currentTime = System.currentTimeMillis();
  String resourceName = relayMessage.getResourceName();
  String partitionName = relayMessage.getPartitionName();
  String sessionId = relayMessage.getTgtSessionId();

  if (!liveInstanceMap.containsKey(targetHost)) {
    LOG.info("Target host is not alive anymore, expiring relay message {} immediately.",
        relayMessage.getId());
    relayMessage.setExpired(true);
    return;
  }

  String instanceSessionId = liveInstanceMap.get(targetHost).getEphemeralOwner();

  // Target host's session has been changed, remove relay message
  if (!instanceSessionId.equals(sessionId)) {
    LOG.info("Instance SessionId does not match, expiring relay message {} immediately.",
        relayMessage.getId());
    relayMessage.setExpired(true);
    return;
  }

  Map<String, Map<String, CurrentState>> instanceCurrentStateMap =
      currentStateMap.get(targetHost);
  if (instanceCurrentStateMap == null || !instanceCurrentStateMap.containsKey(sessionId)) {
    // This should happen only when a new session is being established.
    // We should not do anything here, once new session is established in participant side,
    // the relay message will be deleted from cache in controller's next pipeline.
    LOG.warn("CurrentStateMap null for {}, session {}, pending relay message {}", targetHost,
        sessionId, relayMessage.getId());
    return;
  }

  Map<String, CurrentState> sessionCurrentStateMap = instanceCurrentStateMap.get(sessionId);
  CurrentState currentState = sessionCurrentStateMap.get(resourceName);
  // TODO: we should add transaction id for each state transition, we can immediately delete the relay message once we have transaction id record in each currentState.
  if (currentState == null) {
    setMessageRelayTime(relayMessage, currentTime);
    LOG.warn("CurrentState is null for {} on {}, set relay time {} for message {}", resourceName,
        targetHost, relayMessage.getRelayTime(), relayMessage.getId());
    return;
  }

  // if the target partition already completed the state transition,
  // or the current state on the target partition has been changed,
  // Do not remove the message immediately to avoid race-condition,
  // for example, controller may decide to move master to another instance at this time,
  // if it does not aware of a pending relay message, it may end up with two masters.
  // so we only set the relay message to be expired.
  // TODO: we should add transaction id for each state transition, we can immediately delete the relay message once we have transaction id record in each currentState.
  String partitionCurrentState = currentState.getState(partitionName);
  String targetState = relayMessage.getToState();
  String fromState = relayMessage.getFromState();
  if (targetState.equals(partitionCurrentState) || !fromState.equals(partitionCurrentState)) {
    setMessageRelayTime(relayMessage, currentTime);
    LOG.debug("{}'s currentState {} on {} has changed, set relay message {} to be expired.",
        partitionName, partitionCurrentState, targetHost, relayMessage.getId());
  }
}
 
Example 6
Source File: InstanceMessagesCache.java    From helix with Apache License 2.0 4 votes vote down vote up
private void checkRelayHost(Message relayMessage, Map<String, LiveInstance> liveInstanceMap,
    Map<String, Map<String, Map<String, CurrentState>>> currentStateMap, Message hostedMessage) {

  long currentTime = System.currentTimeMillis();

  String sessionId = hostedMessage.getTgtSessionId();
  String relayInstance = hostedMessage.getTgtName();
  String resourceName = hostedMessage.getResourceName();
  String partitionName = hostedMessage.getPartitionName();

  if (!liveInstanceMap.containsKey(relayInstance)) {
    // If the p2p forwarding host is no longer live, we should not remove the relay message immediately
    // since we do not know whether the relay message was forwarded before the instance went offline.
    setMessageRelayTime(relayMessage, currentTime);
    return;
  }
  String instanceSessionId = liveInstanceMap.get(relayInstance).getEphemeralOwner();
  if (!instanceSessionId.equals(sessionId)) {
    LOG.info("Relay instance sessionId {} does not match sessionId {} in hosted message {}, "
            + "set relay message {} to be expired.", instanceSessionId, sessionId,
        relayMessage.getId(), hostedMessage.getMsgId());
    setMessageRelayTime(relayMessage, currentTime);
    return;
  }

  Map<String, Map<String, CurrentState>> instanceCurrentStateMap =
      currentStateMap.get(relayInstance);
  if (instanceCurrentStateMap == null || !instanceCurrentStateMap.containsKey(sessionId)) {
    LOG.warn(
        "CurrentStateMap null for {}, session {}, set relay messages {} to be expired. Hosted message {}.",
        relayInstance, sessionId, relayMessage.getId(), hostedMessage.getId());
    setMessageRelayTime(relayMessage, currentTime);
    return;
  }

  Map<String, CurrentState> sessionCurrentStateMap = instanceCurrentStateMap.get(sessionId);
  CurrentState currentState = sessionCurrentStateMap.get(resourceName);

  if (currentState == null) {
    LOG.info("No currentState found for {} on {}, set relay message {} to be expired.",
        resourceName, relayInstance, relayMessage.getId());
    setMessageRelayTime(relayMessage, currentTime);
    return;
  }

  String partitionState = currentState.getState(partitionName);
  String targetState = hostedMessage.getToState();
  String fromState = hostedMessage.getFromState();

  // The relay host partition state has been changed after relay message was created.
  if (!fromState.equals(partitionState)) {
    // If the partition on the relay host turned to ERROR while transited from top state,
    // we can remove the cached relay message right away since participant won't forward the relay message anyway.
    if (HelixDefinedState.ERROR.name().equals(partitionState) && fromState
        .equals(currentState.getPreviousState(partitionName))) {
      LOG.info("Partition {} got to ERROR from the top state, "
              + "expiring relay message {} immediately. Hosted message {}.", partitionName,
          relayMessage.getId(), hostedMessage.getId());
      relayMessage.setExpired(true);
      return;
    }

    // If the partition completed the transition, set the relay time to be the actual time when state transition completed.
    if (targetState.equals(partitionState) && fromState
        .equals(currentState.getPreviousState(partitionName))) {
      // The relay host already completed the state transition.
      long completeTime = currentState.getEndTime(partitionName);
      if (completeTime > relayMessage.getCreateTimeStamp()) {
        setMessageRelayTime(relayMessage, completeTime);
        LOG.error("Target state for partition {} matches the hosted message's target state, "
            + "set relay message {} to be expired.", partitionName, relayMessage.getId());
        return;
      }
    }

    // For all other situations, set relay time to be current time.
    setMessageRelayTime(relayMessage, currentTime);
    // the state has been changed after it completed the required state transition (maybe another state-transition happened).
    LOG.info("Current state {} for partition {} does not match hosted message's from state, "
            + "set relay message {} to be expired.", partitionState, partitionName,
        relayMessage.getId());
  }
}
 
Example 7
Source File: MockHelixTaskExecutor.java    From helix with Apache License 2.0 4 votes vote down vote up
void checkDuplicatedMessages(List<Message> messages) {
  HelixDataAccessor accessor = manager.getHelixDataAccessor();
  PropertyKey.Builder keyBuilder = accessor.keyBuilder();
  PropertyKey path = keyBuilder.currentStates(manager.getInstanceName(), manager.getSessionId());
  Map<String, CurrentState> currentStateMap = accessor.getChildValuesMap(path, true);

  Set<String> seenPartitions = new HashSet<>();
  for (Message message : messages) {
    if (message.getMsgType().equals(Message.MessageType.STATE_TRANSITION.name())) {
      String resource = message.getResourceName();
      String partition = message.getPartitionName();

      //System.err.println(message.getMsgId());
      String key = resource + "-" + partition;
      if (seenPartitions.contains(key)) {
        //System.err.println("Duplicated message received for " + resource + ":" + partition);
        duplicatedMessages++;
      }
      seenPartitions.add(key);

      String toState = message.getToState();
      String state = null;
      if (currentStateMap.containsKey(resource)) {
        CurrentState currentState = currentStateMap.get(resource);
        state = currentState.getState(partition);
      }

      if (toState.equals(state) && message.getMsgState() == Message.MessageState.NEW) {
        //            logger.error(
        //                "Extra message: " + message.getMsgId() + ", Partition is already in target state "
        //                    + toState + " for " + resource + ":" + partition);
        extraStateTransition++;
      }

      String messageTarget =
          getMessageTarget(message.getResourceName(), message.getPartitionName());

      if (message.getMsgState() == Message.MessageState.NEW &&
          _messageTaskMap.containsKey(messageTarget)) {
        String taskId = _messageTaskMap.get(messageTarget);
        MessageTaskInfo messageTaskInfo = _taskMap.get(taskId);
        Message existingMsg = messageTaskInfo.getTask().getMessage();
        if (existingMsg.getMsgId() != message.getMsgId())
          //            logger.error("Duplicated message In Progress: " + message.getMsgId()
          //                    + ", state transition in progress with message " + existingMsg.getMsgId()
          //                    + " to " + toState + " for " + resource + ":" + partition);
          duplicatedMessagesInProgress ++;
      }
    }
  }
}