Search in sources :

Example 31 with HelixManager

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

the class BatchMessageHandler method postHandleMessage.

public void postHandleMessage() {
    if (_message.getBatchMessageMode() == true && _batchMsgWrapper != null) {
        _batchMsgWrapper.end(_message, _notificationContext);
    }
    // update currentState
    HelixManager manager = _notificationContext.getManager();
    HelixDataAccessor accessor = manager.getHelixDataAccessor();
    ConcurrentHashMap<String, CurrentStateUpdate> csUpdateMap = (ConcurrentHashMap<String, CurrentStateUpdate>) _notificationContext.get(MapKey.CURRENT_STATE_UPDATE.toString());
    if (csUpdateMap != null) {
        Map<PropertyKey, CurrentState> csUpdate = mergeCurStateUpdate(csUpdateMap);
        // TODO: change to use asyncSet
        for (PropertyKey key : csUpdate.keySet()) {
            // curStateMap.get(key));
            if (!accessor.updateProperty(key, csUpdate.get(key))) {
                LOG.error("Fails to persist current state to ZK for key " + key);
            }
        }
    }
}
Also used : HelixDataAccessor(org.apache.helix.HelixDataAccessor) HelixManager(org.apache.helix.HelixManager) CurrentState(org.apache.helix.model.CurrentState) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) PropertyKey(org.apache.helix.PropertyKey)

Example 32 with HelixManager

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

the class DistributedLeaderElection method onControllerChange.

/**
 * may be accessed by multiple threads: zk-client thread and
 * ZkHelixManager.disconnect()->reset() TODO: Refactor accessing
 * HelixMangerMain class statically
 */
@Override
public synchronized void onControllerChange(NotificationContext changeContext) {
    HelixManager manager = changeContext.getManager();
    if (manager == null) {
        LOG.error("missing attributes in changeContext. requires HelixManager");
        return;
    }
    InstanceType type = manager.getInstanceType();
    if (type != InstanceType.CONTROLLER && type != InstanceType.CONTROLLER_PARTICIPANT) {
        LOG.error("fail to become controller because incorrect instanceType (was " + type.toString() + ", requires CONTROLLER | CONTROLLER_PARTICIPANT)");
        return;
    }
    ControllerManagerHelper controllerHelper = new ControllerManagerHelper(_manager, _controllerTimerTasks);
    try {
        if (changeContext.getType().equals(NotificationContext.Type.INIT) || changeContext.getType().equals(NotificationContext.Type.CALLBACK)) {
            LOG.info(_manager.getInstanceName() + " is trying to acquire leadership for cluster: " + _manager.getClusterName());
            HelixDataAccessor accessor = manager.getHelixDataAccessor();
            Builder keyBuilder = accessor.keyBuilder();
            while (accessor.getProperty(keyBuilder.controllerLeader()) == null) {
                boolean success = tryUpdateController(manager);
                if (success) {
                    LOG.info(_manager.getInstanceName() + " acquired leadership for cluster: " + _manager.getClusterName());
                    updateHistory(manager);
                    _manager.getHelixDataAccessor().getBaseDataAccessor().reset();
                    controllerHelper.addListenersToController(_controller);
                    controllerHelper.startControllerTimerTasks();
                }
            }
        } else if (changeContext.getType().equals(NotificationContext.Type.FINALIZE)) {
            LOG.info(_manager.getInstanceName() + " relinquish leadership for cluster: " + _manager.getClusterName());
            controllerHelper.stopControllerTimerTasks();
            controllerHelper.removeListenersFromController(_controller);
            /**
             * clear write-through cache
             */
            _manager.getHelixDataAccessor().getBaseDataAccessor().reset();
        }
    } catch (Exception e) {
        LOG.error("Exception when trying to become leader", e);
    }
}
Also used : HelixDataAccessor(org.apache.helix.HelixDataAccessor) HelixManager(org.apache.helix.HelixManager) Builder(org.apache.helix.PropertyKey.Builder) InstanceType(org.apache.helix.InstanceType)

Example 33 with HelixManager

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

the class TestCorrectnessOnConnectivityLoss method testSpectator.

@SuppressWarnings("deprecation")
@Test
public void testSpectator() throws Exception {
    Map<String, Integer> stateReachedCounts = Maps.newHashMap();
    HelixManager participant = HelixManagerFactory.getZKHelixManager(_clusterName, "localhost_12918", InstanceType.PARTICIPANT, ZK_ADDR);
    participant.getStateMachineEngine().registerStateModelFactory("OnlineOffline", new MyStateModelFactory(stateReachedCounts));
    participant.connect();
    RoutingTableProvider routingTableProvider = new RoutingTableProvider();
    HelixManager spectator = HelixManagerFactory.getZKHelixManager(_clusterName, "spectator", InstanceType.SPECTATOR, ZK_ADDR);
    spectator.connect();
    spectator.addConfigChangeListener(routingTableProvider);
    spectator.addExternalViewChangeListener(routingTableProvider);
    Thread.sleep(1000);
    // Now let's stop the ZK server; this should do nothing
    TestHelper.stopZkServer(_zkServer);
    Thread.sleep(1000);
    // Verify routing table still works
    Assert.assertEquals(routingTableProvider.getInstances("resource0", "ONLINE").size(), 1);
    Assert.assertEquals(routingTableProvider.getInstances("resource0", "OFFLINE").size(), 0);
}
Also used : HelixManager(org.apache.helix.HelixManager) RoutingTableProvider(org.apache.helix.spectator.RoutingTableProvider) Test(org.testng.annotations.Test)

Example 34 with HelixManager

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

the class TestCorrectnessOnConnectivityLoss method testParticipant.

@Test
public void testParticipant() throws Exception {
    Map<String, Integer> stateReachedCounts = Maps.newHashMap();
    HelixManager participant = HelixManagerFactory.getZKHelixManager(_clusterName, "localhost_12918", InstanceType.PARTICIPANT, ZK_ADDR);
    participant.getStateMachineEngine().registerStateModelFactory("OnlineOffline", new MyStateModelFactory(stateReachedCounts));
    participant.connect();
    Thread.sleep(1000);
    // Ensure that the external view coalesces
    boolean result = ClusterStateVerifier.verifyByZkCallback(new BestPossAndExtViewZkVerifier(ZK_ADDR, _clusterName));
    Assert.assertTrue(result);
    // Ensure that there was only one state transition
    Assert.assertEquals(stateReachedCounts.size(), 1);
    Assert.assertTrue(stateReachedCounts.containsKey("ONLINE"));
    Assert.assertEquals(stateReachedCounts.get("ONLINE").intValue(), 1);
    // Now let's stop the ZK server; this should do nothing
    TestHelper.stopZkServer(_zkServer);
    Thread.sleep(1000);
    // Verify no change
    Assert.assertEquals(stateReachedCounts.size(), 1);
    Assert.assertTrue(stateReachedCounts.containsKey("ONLINE"));
    Assert.assertEquals(stateReachedCounts.get("ONLINE").intValue(), 1);
}
Also used : HelixManager(org.apache.helix.HelixManager) BestPossAndExtViewZkVerifier(org.apache.helix.tools.ClusterStateVerifier.BestPossAndExtViewZkVerifier) Test(org.testng.annotations.Test)

Example 35 with HelixManager

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

the class TestPreferenceListAsQueue method runTest.

private void runTest() throws Exception {
    final int NUM_PARTITIONS = 1;
    final int NUM_REPLICAS = 2;
    final int NUM_INSTANCES = 2;
    final String RESOURCE_NAME = "MyResource";
    // Setup instances
    String[] instanceInfoArray = { "localhost_1", "localhost_2" };
    _clusterSetup.addInstancesToCluster(_clusterName, instanceInfoArray);
    // Add resource
    _clusterSetup.addResourceToCluster(_clusterName, RESOURCE_NAME, NUM_PARTITIONS, _stateModel, RebalanceMode.SEMI_AUTO.toString());
    // Update resource with empty preference lists
    IdealState idealState = _admin.getResourceIdealState(_clusterName, RESOURCE_NAME);
    for (int i = 0; i < NUM_PARTITIONS; i++) {
        String partitionName = RESOURCE_NAME + "_" + i;
        List<String> dummyPreferences = Lists.newArrayList();
        for (int j = 0; j < NUM_REPLICAS; j++) {
            // hack: need to have some dummy values in the preference list to pass validation
            dummyPreferences.add("");
        }
        idealState.getRecord().setListField(partitionName, dummyPreferences);
    }
    idealState.setReplicas(String.valueOf(NUM_REPLICAS));
    _admin.setResourceIdealState(_clusterName, RESOURCE_NAME, idealState);
    // Start some instances
    HelixManager[] participants = new HelixManager[NUM_INSTANCES];
    for (int i = 0; i < NUM_INSTANCES; i++) {
        participants[i] = HelixManagerFactory.getZKHelixManager(_clusterName, instanceInfoArray[i], InstanceType.PARTICIPANT, ZK_ADDR);
        participants[i].getStateMachineEngine().registerStateModelFactory(_stateModel, new PrefListTaskOnlineOfflineStateModelFactory());
        participants[i].connect();
    }
    // Start the controller
    HelixManager controller = HelixManagerFactory.getZKHelixManager(_clusterName, null, InstanceType.CONTROLLER, ZK_ADDR);
    controller.connect();
    // Disable controller immediately
    _admin.enableCluster(_clusterName, false);
    // This resource only has 1 partition
    String partitionName = RESOURCE_NAME + "_" + 0;
    // There should be no preference lists yet
    Assert.assertTrue(preferenceListIsCorrect(_admin, _clusterName, RESOURCE_NAME, partitionName, Arrays.asList("", "")));
    // Add one instance
    addInstanceToPreferences(participants[0].getHelixDataAccessor(), participants[0].getInstanceName(), RESOURCE_NAME, Arrays.asList(partitionName));
    Assert.assertTrue(preferenceListIsCorrect(_admin, _clusterName, RESOURCE_NAME, partitionName, Arrays.asList("localhost_1", "")));
    // Add a second instance immediately; the first one should still exist
    addInstanceToPreferences(participants[1].getHelixDataAccessor(), participants[1].getInstanceName(), RESOURCE_NAME, Arrays.asList(partitionName));
    Assert.assertTrue(preferenceListIsCorrect(_admin, _clusterName, RESOURCE_NAME, partitionName, Arrays.asList("localhost_1", "localhost_2")));
    // Add the first instance again; it should already exist
    addInstanceToPreferences(participants[0].getHelixDataAccessor(), participants[0].getInstanceName(), RESOURCE_NAME, Arrays.asList(partitionName));
    Assert.assertTrue(preferenceListIsCorrect(_admin, _clusterName, RESOURCE_NAME, partitionName, Arrays.asList("localhost_1", "localhost_2")));
    // Prepare for synchronization
    _onlineLatch = new CountDownLatch(2);
    _offlineLatch = new CountDownLatch(2);
    _prefListHistory.clear();
    // Now reenable the controller
    _admin.enableCluster(_clusterName, true);
    // Now wait for both instances to be done
    boolean countReached = _onlineLatch.await(10000, TimeUnit.MILLISECONDS);
    Assert.assertTrue(countReached);
    List<String> top = _prefListHistory.poll();
    Assert.assertTrue(top.equals(Arrays.asList("localhost_1", "")) || top.equals(Arrays.asList("localhost_2", "")));
    Assert.assertEquals(_prefListHistory.poll(), Arrays.asList("", ""));
    // Wait for everything to be fully offline
    countReached = _offlineLatch.await(10000, TimeUnit.MILLISECONDS);
    Assert.assertTrue(countReached);
    // Add back the instances in the opposite order
    _admin.enableCluster(_clusterName, false);
    addInstanceToPreferences(participants[0].getHelixDataAccessor(), participants[1].getInstanceName(), RESOURCE_NAME, Arrays.asList(partitionName));
    addInstanceToPreferences(participants[0].getHelixDataAccessor(), participants[0].getInstanceName(), RESOURCE_NAME, Arrays.asList(partitionName));
    Assert.assertTrue(preferenceListIsCorrect(_admin, _clusterName, RESOURCE_NAME, partitionName, Arrays.asList("localhost_2", "localhost_1")));
    // Reset the latch
    _onlineLatch = new CountDownLatch(2);
    _prefListHistory.clear();
    _admin.enableCluster(_clusterName, true);
    // Now wait both to be done again
    countReached = _onlineLatch.await(10000, TimeUnit.MILLISECONDS);
    Assert.assertTrue(countReached);
    top = _prefListHistory.poll();
    Assert.assertTrue(top.equals(Arrays.asList("localhost_1", "")) || top.equals(Arrays.asList("localhost_2", "")));
    Assert.assertEquals(_prefListHistory.poll(), Arrays.asList("", ""));
    Assert.assertEquals(_instanceList.size(), 0);
    // Cleanup
    controller.disconnect();
    for (HelixManager participant : participants) {
        participant.disconnect();
    }
}
Also used : HelixManager(org.apache.helix.HelixManager) CountDownLatch(java.util.concurrent.CountDownLatch) IdealState(org.apache.helix.model.IdealState)

Aggregations

HelixManager (org.apache.helix.HelixManager)115 Test (org.testng.annotations.Test)49 HelixDataAccessor (org.apache.helix.HelixDataAccessor)35 ZNRecord (org.apache.helix.ZNRecord)28 Message (org.apache.helix.model.Message)23 PropertyKey (org.apache.helix.PropertyKey)20 Date (java.util.Date)18 ZKHelixDataAccessor (org.apache.helix.manager.zk.ZKHelixDataAccessor)17 Builder (org.apache.helix.PropertyKey.Builder)16 ArrayList (java.util.ArrayList)14 HashMap (java.util.HashMap)12 HelixException (org.apache.helix.HelixException)11 ExternalView (org.apache.helix.model.ExternalView)11 NotificationContext (org.apache.helix.NotificationContext)10 LiveInstance (org.apache.helix.model.LiveInstance)10 IdealState (org.apache.helix.model.IdealState)9 Criteria (org.apache.helix.Criteria)8 HelixAdmin (org.apache.helix.HelixAdmin)8 ZKHelixManager (org.apache.helix.manager.zk.ZKHelixManager)8 StringWriter (java.io.StringWriter)7