Search in sources :

Example 11 with PropertyKey

use of org.apache.helix.PropertyKey in project helix by apache.

the class HelixStateTransitionHandler method preHandleMessage.

void preHandleMessage() throws Exception {
    if (!_message.isValid()) {
        String errorMessage = "Invalid Message, ensure that message: " + _message + " has all the required fields: " + Arrays.toString(Message.Attributes.values());
        _statusUpdateUtil.logError(_message, HelixStateTransitionHandler.class, errorMessage, _manager);
        logger.error(errorMessage);
        throw new HelixException(errorMessage);
    }
    logger.info("handling message: " + _message.getMsgId() + " transit " + _message.getResourceName() + "." + _message.getPartitionName() + "|" + _message.getPartitionNames() + " from:" + _message.getFromState() + " to:" + _message.getToState() + ", relayedFrom: " + _message.getRelaySrcHost());
    HelixDataAccessor accessor = _manager.getHelixDataAccessor();
    String partitionName = _message.getPartitionName();
    String fromState = _message.getFromState();
    // Verify the fromState and current state of the stateModel
    String state = _currentStateDelta.getState(partitionName);
    // Set start time right before invoke client logic
    _currentStateDelta.setStartTime(_message.getPartitionName(), System.currentTimeMillis());
    if (fromState != null && !fromState.equals("*") && !fromState.equalsIgnoreCase(state)) {
        String errorMessage = "Current state of stateModel does not match the fromState in Message" + ", Current State:" + state + ", message expected:" + fromState + ", partition: " + partitionName + ", from: " + _message.getMsgSrc() + ", to: " + _message.getTgtName();
        _statusUpdateUtil.logError(_message, HelixStateTransitionHandler.class, errorMessage, _manager);
        logger.error(errorMessage);
        throw new HelixStateMismatchException(errorMessage);
    }
    // Reset the REQUESTED_STATE property if it exists.
    try {
        String instance = _manager.getInstanceName();
        String sessionId = _message.getTgtSessionId();
        String resource = _message.getResourceName();
        ZNRecordBucketizer bucketizer = new ZNRecordBucketizer(_message.getBucketSize());
        PropertyKey key = accessor.keyBuilder().currentState(instance, sessionId, resource, bucketizer.getBucketName(partitionName));
        ZNRecord rec = new ZNRecord(resource);
        Map<String, String> map = new TreeMap<String, String>();
        map.put(CurrentState.CurrentStateProperty.REQUESTED_STATE.name(), null);
        rec.getMapFields().put(partitionName, map);
        ZNRecordDelta delta = new ZNRecordDelta(rec, ZNRecordDelta.MergeOperation.SUBTRACT);
        List<ZNRecordDelta> deltaList = new ArrayList<ZNRecordDelta>();
        deltaList.add(delta);
        CurrentState currStateUpdate = new CurrentState(resource);
        currStateUpdate.setDeltaList(deltaList);
        // Update the ZK current state of the node
        if (!accessor.updateProperty(key, currStateUpdate)) {
            logger.error("Fails to persist current state back to ZK for resource " + resource + " partition: " + partitionName);
        }
    } catch (Exception e) {
        logger.error("Error when removing " + CurrentState.CurrentStateProperty.REQUESTED_STATE.name() + " from current state.", e);
        StateTransitionError error = new StateTransitionError(ErrorType.FRAMEWORK, ErrorCode.ERROR, e);
        _stateModel.rollbackOnError(_message, _notificationContext, error);
        _statusUpdateUtil.logError(_message, HelixStateTransitionHandler.class, e, "Error when removing " + CurrentState.CurrentStateProperty.REQUESTED_STATE.name() + " from current state.", _manager);
    }
}
Also used : ZNRecordBucketizer(org.apache.helix.ZNRecordBucketizer) ArrayList(java.util.ArrayList) TreeMap(java.util.TreeMap) ZNRecordDelta(org.apache.helix.ZNRecordDelta) HelixException(org.apache.helix.HelixException) HelixRollbackException(org.apache.helix.HelixRollbackException) InvocationTargetException(java.lang.reflect.InvocationTargetException) HelixException(org.apache.helix.HelixException) HelixDataAccessor(org.apache.helix.HelixDataAccessor) CurrentState(org.apache.helix.model.CurrentState) StateTransitionError(org.apache.helix.participant.statemachine.StateTransitionError) PropertyKey(org.apache.helix.PropertyKey) ZNRecord(org.apache.helix.ZNRecord)

Example 12 with PropertyKey

use of org.apache.helix.PropertyKey in project helix by apache.

the class HelixTaskExecutor method updateMessageState.

private void updateMessageState(List<Message> readMsgs, HelixDataAccessor accessor, String instanceName) {
    Builder keyBuilder = accessor.keyBuilder();
    List<PropertyKey> readMsgKeys = new ArrayList<>();
    for (Message msg : readMsgs) {
        readMsgKeys.add(msg.getKey(keyBuilder, instanceName));
        _knownMessageIds.add(msg.getId());
    }
    accessor.setChildren(readMsgKeys, readMsgs);
}
Also used : Message(org.apache.helix.model.Message) HelixConfigScopeBuilder(org.apache.helix.model.builder.HelixConfigScopeBuilder) Builder(org.apache.helix.PropertyKey.Builder) ArrayList(java.util.ArrayList) PropertyKey(org.apache.helix.PropertyKey)

Example 13 with PropertyKey

use of org.apache.helix.PropertyKey in project ambry by linkedin.

the class HelixHealthReportAggregationTaskTest method initializeNodeReports.

/**
 * Initialize the reports and create instances in helix if not exists.
 * @param type The type of reports to create
 * @param numNode The number of nodes to initiate.
 * @param startingPort The starting port number, which will then be incremented to represent different nodes.
 * @throws IOException
 */
private void initializeNodeReports(StatsReportType type, int numNode, int startingPort) throws IOException {
    String healthReportName = type == StatsReportType.ACCOUNT_REPORT ? HEALTH_REPORT_NAME_ACCOUNT : HEALTH_REPORT_NAME_PARTITION;
    String statsFieldName = type == StatsReportType.ACCOUNT_REPORT ? STATS_FIELD_NAME_ACCOUNT : STATS_FIELD_NAME_PARTITION;
    List<StatsSnapshot> storeSnapshots = new ArrayList<>();
    Random random = new Random();
    for (int i = 3; i < 6; i++) {
        storeSnapshots.add(TestUtils.generateStoreStats(i, 3, random, type));
    }
    StatsWrapper nodeStats = TestUtils.generateNodeStats(storeSnapshots, 1000, type);
    String nodeStatsJSON = mapper.writeValueAsString(nodeStats);
    HelixDataAccessor dataAccessor = mockHelixManager.getHelixDataAccessor();
    for (int i = 0; i < numNode; i++) {
        String instanceName = ClusterMapUtils.getInstanceName("localhost", startingPort);
        InstanceConfig instanceConfig = new InstanceConfig(instanceName);
        instanceConfig.setHostName("localhost");
        instanceConfig.setPort(Integer.toString(startingPort));
        mockHelixAdmin.addInstance(CLUSTER_NAME, instanceConfig);
        PropertyKey key = dataAccessor.keyBuilder().healthReport(instanceName, healthReportName);
        ZNRecord znRecord = new ZNRecord(instanceName);
        // Set the same reports for all instances
        znRecord.setSimpleField(statsFieldName, nodeStatsJSON);
        HelixProperty helixProperty = new HelixProperty(znRecord);
        dataAccessor.setProperty(key, helixProperty);
        startingPort++;
    }
}
Also used : HelixDataAccessor(org.apache.helix.HelixDataAccessor) Random(java.util.Random) InstanceConfig(org.apache.helix.model.InstanceConfig) HelixProperty(org.apache.helix.HelixProperty) ArrayList(java.util.ArrayList) StatsWrapper(com.github.ambry.server.StatsWrapper) PropertyKey(org.apache.helix.PropertyKey) ZNRecord(org.apache.helix.zookeeper.datamodel.ZNRecord) StatsSnapshot(com.github.ambry.server.StatsSnapshot)

Example 14 with PropertyKey

use of org.apache.helix.PropertyKey in project ambry by linkedin.

the class MockHelixDataAccessor method getProperty.

@Override
public <T extends HelixProperty> List<T> getProperty(List<PropertyKey> keys, boolean throwException) {
    List<T> result = new ArrayList<>();
    for (PropertyKey key : keys) {
        if (key.toString().matches("/Ambry-/INSTANCES/.*/CURRENTSTATES/\\d+/\\d+")) {
            // an example for the key: /Ambry-/INSTANCES/localhost_18089/CURRENTSTATES/sessionId/0
            String[] segments = key.toString().split("/");
            String instanceName = segments[3];
            String resourceName = segments[6];
            Map<String, Map<String, String>> partitionStateMap = mockHelixAdmin.getPartitionStateMapForInstance(instanceName);
            ZNRecord record = new ZNRecord(resourceName);
            record.setMapFields(partitionStateMap);
            result.add((T) (new CurrentState(record)));
        } else if (key.toString().matches("/Ambry-/LIVEINSTANCES/.*_\\d+")) {
            String[] segments = key.toString().split("/");
            String instanceName = segments[3];
            ZNRecord record = new ZNRecord(instanceName);
            record.setEphemeralOwner(SESSION_ID);
            result.add((T) (new LiveInstance(record)));
        } else if (key.toString().matches("/Ambry-/CONFIGS/PARTICIPANT/.*_\\d+")) {
            String[] segments = key.toString().split("/");
            String instanceName = segments[4];
            InstanceConfig instanceConfig = mockHelixAdmin.getInstanceConfigs(clusterName).stream().filter(config -> config.getInstanceName().equals(instanceName)).findFirst().get();
            result.add((T) instanceConfig);
        } else {
            result.add((T) properties.get(key));
        }
    }
    return result;
}
Also used : LiveInstance(org.apache.helix.model.LiveInstance) InstanceConfig(org.apache.helix.model.InstanceConfig) CurrentState(org.apache.helix.model.CurrentState) ArrayList(java.util.ArrayList) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Map(java.util.Map) PropertyKey(org.apache.helix.PropertyKey) ZNRecord(org.apache.helix.zookeeper.datamodel.ZNRecord)

Example 15 with PropertyKey

use of org.apache.helix.PropertyKey in project helix by apache.

the class CurrentStateSnapshot method getNewCurrentStateEndTimes.

/**
 * Return the end times of all recent changed current states update.
 */
public Map<PropertyKey, Map<String, Long>> getNewCurrentStateEndTimes() {
    Map<PropertyKey, Map<String, Long>> endTimeMap = new HashMap<>();
    if (_updatedStateKeys != null && _prevStateMap != null) {
        // Note if the prev state map is empty, this is the first time refresh.
        // So the update is not considered as "recent" change.
        // clock drift count for comparing timestamp
        int driftCnt = 0;
        for (PropertyKey propertyKey : _updatedStateKeys) {
            CurrentState prevState = _prevStateMap.get(propertyKey);
            CurrentState curState = _properties.get(propertyKey);
            Map<String, Long> partitionUpdateEndTimes = null;
            for (String partition : curState.getPartitionStateMap().keySet()) {
                long newEndTime = curState.getEndTime(partition);
                // statePropagation latency calculation in RoutingTableProvider would spit out extremely large metrics.
                if ((prevState == null || prevState.getEndTime(partition) < newEndTime) && newEndTime != -1) {
                    if (partitionUpdateEndTimes == null) {
                        partitionUpdateEndTimes = new HashMap<>();
                    }
                    partitionUpdateEndTimes.put(partition, newEndTime);
                } else if (prevState != null && prevState.getEndTime(partition) > newEndTime) {
                    // If clock drift turns out to be common, we can consider print out more logs, or expose an metric.
                    if (driftCnt < 1) {
                        LOG.warn("clock drift. partition:" + partition + " curState:" + curState.getState(partition) + " prevState: " + prevState.getState(partition));
                    }
                    driftCnt++;
                }
            }
            if (partitionUpdateEndTimes != null) {
                endTimeMap.put(propertyKey, partitionUpdateEndTimes);
            }
        }
    }
    return endTimeMap;
}
Also used : HashMap(java.util.HashMap) CurrentState(org.apache.helix.model.CurrentState) Map(java.util.Map) HashMap(java.util.HashMap) PropertyKey(org.apache.helix.PropertyKey)

Aggregations

PropertyKey (org.apache.helix.PropertyKey)130 HelixDataAccessor (org.apache.helix.HelixDataAccessor)59 Test (org.testng.annotations.Test)33 ArrayList (java.util.ArrayList)31 CurrentState (org.apache.helix.model.CurrentState)29 Message (org.apache.helix.model.Message)27 ZNRecord (org.apache.helix.zookeeper.datamodel.ZNRecord)27 HelixManager (org.apache.helix.HelixManager)24 LiveInstance (org.apache.helix.model.LiveInstance)21 Builder (org.apache.helix.PropertyKey.Builder)20 Map (java.util.Map)19 HelixException (org.apache.helix.HelixException)19 HashSet (java.util.HashSet)18 HashMap (java.util.HashMap)17 IdealState (org.apache.helix.model.IdealState)16 InstanceConfig (org.apache.helix.model.InstanceConfig)14 ExternalView (org.apache.helix.model.ExternalView)12 HelixProperty (org.apache.helix.HelixProperty)11 List (java.util.List)10 ClusterControllerManager (org.apache.helix.integration.manager.ClusterControllerManager)10