use of org.apache.helix.HelixManager in project helix by apache.
the class TestZkReconnect method testZKReconnect.
@Test(enabled = false)
public void testZKReconnect() throws Exception {
final AtomicReference<ZkServer> zkServerRef = new AtomicReference<ZkServer>();
final int zkPort = TestHelper.getRandomPort();
final String zkAddr = String.format("localhost:%d", zkPort);
ZkServer zkServer = TestHelper.startZkServer(zkAddr);
zkServerRef.set(zkServer);
String className = TestHelper.getTestClassName();
String methodName = TestHelper.getTestMethodName();
String clusterName = className + "_" + methodName;
// Setup cluster
LOG.info("Setup clusters");
ClusterSetup clusterSetup = new ClusterSetup(zkAddr);
clusterSetup.addCluster(clusterName, true);
// Registers and starts controller
LOG.info("Starts controller");
HelixManager controller = HelixManagerFactory.getZKHelixManager(clusterName, null, InstanceType.CONTROLLER, zkAddr);
controller.connect();
// Registers and starts participant
LOG.info("Starts participant");
String hostname = "localhost";
String instanceId = String.format("%s_%d", hostname, 1);
clusterSetup.addInstanceToCluster(clusterName, instanceId);
HelixManager participant = HelixManagerFactory.getZKHelixManager(clusterName, instanceId, InstanceType.PARTICIPANT, zkAddr);
participant.connect();
LOG.info("Register state machine");
final CountDownLatch latch = new CountDownLatch(1);
participant.getStateMachineEngine().registerStateModelFactory("OnlineOffline", new StateModelFactory<StateModel>() {
@Override
public StateModel createNewStateModel(String resource, String stateUnitKey) {
return new SimpleStateModel(latch);
}
}, "test");
String resourceName = "test-resource";
LOG.info("Ideal state assignment");
HelixAdmin helixAdmin = participant.getClusterManagmentTool();
helixAdmin.addResource(clusterName, resourceName, 1, "OnlineOffline", IdealState.RebalanceMode.CUSTOMIZED.toString());
IdealState idealState = helixAdmin.getResourceIdealState(clusterName, resourceName);
idealState.setReplicas("1");
idealState.setStateModelFactoryName("test");
idealState.setPartitionState(resourceName + "_0", instanceId, "ONLINE");
LOG.info("Shutdown ZK server");
TestHelper.stopZkServer(zkServerRef.get());
Executors.newSingleThreadScheduledExecutor().schedule(new Runnable() {
@Override
public void run() {
try {
LOG.info("Restart ZK server");
// zkServer.set(TestUtils.startZookeeper(zkDir, zkPort));
zkServerRef.set(TestHelper.startZkServer(zkAddr, null, false));
} catch (Exception e) {
LOG.error(e.getMessage(), e);
}
}
}, 2L, TimeUnit.SECONDS);
// future.get();
LOG.info("Before update ideal state");
helixAdmin.setResourceIdealState(clusterName, resourceName, idealState);
LOG.info("After update ideal state");
LOG.info("Wait for OFFLINE->ONLINE state transition");
try {
Assert.assertTrue(latch.await(15, TimeUnit.SECONDS));
// wait until stable state
boolean result = ClusterStateVerifier.verifyByZkCallback(new BestPossAndExtViewZkVerifier(zkAddr, clusterName));
Assert.assertTrue(result);
} finally {
participant.disconnect();
zkServerRef.get().shutdown();
}
}
use of org.apache.helix.HelixManager in project helix by apache.
the class TestZkReconnect method testZKDisconnectCallback.
@Test
public void testZKDisconnectCallback() throws Exception {
final int zkPort = TestHelper.getRandomPort();
final String zkAddr = String.format("localhost:%d", zkPort);
final ZkServer zkServer = TestHelper.startZkServer(zkAddr);
String className = TestHelper.getTestClassName();
String methodName = TestHelper.getTestMethodName();
final String clusterName = className + "_" + methodName;
// Init flag to check if callback is triggered
final AtomicReference<Boolean> flag = new AtomicReference<Boolean>(false);
// Setup cluster
LOG.info("Setup clusters");
ClusterSetup clusterSetup = new ClusterSetup(zkAddr);
clusterSetup.addCluster(clusterName, true);
// For fast test, set short timeout
System.setProperty("zk.connection.timeout", "2000");
System.setProperty("zk.connectionReEstablishment.timeout", "1000");
// Registers and starts controller, register listener for disconnect handling
LOG.info("Starts controller");
final ZKHelixManager controller = (ZKHelixManager) HelixManagerFactory.getZKHelixManager(clusterName, null, InstanceType.CONTROLLER, zkAddr, new HelixManagerStateListener() {
@Override
public void onConnected(HelixManager helixManager) throws Exception {
return;
}
@Override
public void onDisconnected(HelixManager helixManager, Throwable error) throws Exception {
Assert.assertEquals(helixManager.getClusterName(), clusterName);
flag.getAndSet(true);
}
});
try {
controller.connect();
ZkHelixPropertyStore propertyStore = controller.getHelixPropertyStore();
// 1. shutdown zkServer and check if handler trigger callback
zkServer.shutdown();
// Retry will fail, and flag should be set within onDisconnected handler
controller.handleSessionEstablishmentError(new Exception("For testing"));
Assert.assertTrue(flag.get());
try {
propertyStore.get("/", null, 0);
Assert.fail("propertyStore should be disconnected.");
} catch (IllegalStateException e) {
// Expected exception
System.out.println(e.getMessage());
}
// 2. restart zkServer and check if handler will recover connection
flag.getAndSet(false);
zkServer.start();
// Retry will succeed, and flag should not be set
controller.handleSessionEstablishmentError(new Exception("For testing"));
Assert.assertFalse(flag.get());
// New propertyStore should be in good state
propertyStore = controller.getHelixPropertyStore();
propertyStore.get("/", null, 0);
} finally {
controller.disconnect();
zkServer.shutdown();
System.clearProperty("zk.connection.timeout");
System.clearProperty("zk.connectionReEstablishment.timeout");
}
}
use of org.apache.helix.HelixManager in project helix by apache.
the class TestControllerLeadershipChange method testMissingTopStateDurationMonitoring.
@Test
public void testMissingTopStateDurationMonitoring() throws Exception {
String clusterName = "testCluster-TestControllerLeadershipChange";
String instanceName = clusterName + "-participant";
String resourceName = "testResource";
int numPartition = 1;
int numReplica = 1;
String stateModel = "LeaderStandby";
ObjectName resourceMBeanObjectName = getResourceMonitorObjectName(clusterName, resourceName);
MBeanServer beanServer = ManagementFactory.getPlatformMBeanServer();
// Create cluster
_gSetupTool.addCluster(clusterName, true);
// Create participant
_gSetupTool.addInstanceToCluster(clusterName, instanceName);
MockParticipantManager participant = new MockParticipantManager(ZK_ADDR, clusterName, instanceName);
participant.syncStart();
// Create controller, since this is the only controller, it will be the leader
HelixManager manager1 = HelixManagerFactory.getZKHelixManager(clusterName, clusterName + "-manager1", InstanceType.CONTROLLER, ZK_ADDR);
manager1.connect();
Assert.assertTrue(manager1.isLeader());
// Create resource
_gSetupTool.addResourceToCluster(clusterName, resourceName, numPartition, stateModel, IdealState.RebalanceMode.SEMI_AUTO.name());
// Rebalance Resource
_gSetupTool.rebalanceResource(clusterName, resourceName, numReplica);
// Wait for rebalance
Thread.sleep(2000);
// Trigger missing top state in manager1
participant.syncStop();
Thread.sleep(2000);
// Starting manager2
HelixManager manager2 = HelixManagerFactory.getZKHelixManager(clusterName, clusterName + "-manager2", InstanceType.CONTROLLER, ZK_ADDR);
manager2.connect();
Assert.assertFalse(manager2.isLeader());
// Set leader to manager2
setLeader(manager2);
Assert.assertFalse(manager1.isLeader());
Assert.assertTrue(manager2.isLeader());
// Make resource top state to come back
participant = new MockParticipantManager(ZK_ADDR, clusterName, instanceName);
participant.syncStart();
// Wait for rebalance
Thread.sleep(2000);
setLeader(manager1);
Assert.assertTrue(manager1.isLeader());
Assert.assertFalse(manager2.isLeader());
_gSetupTool.rebalanceResource(clusterName, resourceName, numReplica);
// Wait for manager1 to update
Thread.sleep(2000);
// Resource lost top state, and manager1 lost leadership for 4000ms, because manager1 will
// clean monitoring cache after re-gaining leadership, so max value of hand off duration should
// not have such a large value
Assert.assertTrue((long) beanServer.getAttribute(resourceMBeanObjectName, "PartitionTopStateHandoffDurationGauge.Max") < 500);
}
use of org.apache.helix.HelixManager in project helix by apache.
the class TestSchedulerMessage method testSchedulerZeroMsg.
@Test
public void testSchedulerZeroMsg() throws Exception {
_factory._results.clear();
HelixManager manager = null;
for (int i = 0; i < NODE_NR; i++) {
_participants[i].getMessagingService().registerMessageHandlerFactory(_factory.getMessageTypes(), _factory);
// _startCMResultMap.get(hostDest)._manager;
manager = _participants[i];
}
Message schedulerMessage = new Message(MessageType.SCHEDULER_MSG + "", UUID.randomUUID().toString());
schedulerMessage.setTgtSessionId("*");
schedulerMessage.setTgtName("CONTROLLER");
// TODO: change it to "ADMIN" ?
schedulerMessage.setSrcName("CONTROLLER");
// Template for the individual message sent to each participant
Message msg = new Message(_factory.getMessageTypes().get(0), "Template");
msg.setTgtSessionId("*");
msg.setMsgState(MessageState.NEW);
// Criteria to send individual messages
Criteria cr = new Criteria();
cr.setInstanceName("localhost_DOESNOTEXIST");
cr.setRecipientInstanceType(InstanceType.PARTICIPANT);
cr.setSessionSpecific(false);
cr.setResource("%");
cr.setPartition("%");
ObjectMapper mapper = new ObjectMapper();
SerializationConfig serializationConfig = mapper.getSerializationConfig();
serializationConfig.set(SerializationConfig.Feature.INDENT_OUTPUT, true);
StringWriter sw = new StringWriter();
mapper.writeValue(sw, cr);
String crString = sw.toString();
schedulerMessage.getRecord().setSimpleField("Criteria", crString);
schedulerMessage.getRecord().setMapField("MessageTemplate", msg.getRecord().getSimpleFields());
schedulerMessage.getRecord().setSimpleField("TIMEOUT", "-1");
HelixDataAccessor helixDataAccessor = manager.getHelixDataAccessor();
Builder keyBuilder = helixDataAccessor.keyBuilder();
PropertyKey controllerMessageKey = keyBuilder.controllerMessage(schedulerMessage.getMsgId());
helixDataAccessor.setProperty(controllerMessageKey, schedulerMessage);
Thread.sleep(3000);
Assert.assertEquals(0, _factory._results.size());
PropertyKey controllerTaskStatus = keyBuilder.controllerTaskStatus(MessageType.SCHEDULER_MSG.name(), schedulerMessage.getMsgId());
for (int i = 0; i < 10; i++) {
StatusUpdate update = helixDataAccessor.getProperty(controllerTaskStatus);
if (update == null || update.getRecord().getMapField("SentMessageCount") == null) {
Thread.sleep(1000);
}
}
ZNRecord statusUpdate = helixDataAccessor.getProperty(controllerTaskStatus).getRecord();
Assert.assertTrue(statusUpdate.getMapField("SentMessageCount").get("MessageCount").equals("0"));
int count = 0;
for (Set<String> val : _factory._results.values()) {
count += val.size();
}
Assert.assertEquals(count, 0);
}
use of org.apache.helix.HelixManager in project helix by apache.
the class TestSchedulerMessage2 method testSchedulerMsg2.
@Test()
public void testSchedulerMsg2() throws Exception {
_factory._results.clear();
Thread.sleep(2000);
HelixManager manager = null;
for (int i = 0; i < NODE_NR; i++) {
_participants[i].getMessagingService().registerMessageHandlerFactory(_factory.getMessageType(), _factory);
// _startCMResultMap.get(hostDest)._manager;
manager = _participants[i];
}
Message schedulerMessage = new Message(MessageType.SCHEDULER_MSG + "", UUID.randomUUID().toString());
schedulerMessage.setTgtSessionId("*");
schedulerMessage.setTgtName("CONTROLLER");
// TODO: change it to "ADMIN" ?
schedulerMessage.setSrcName("CONTROLLER");
// Template for the individual message sent to each participant
Message msg = new Message(_factory.getMessageType(), "Template");
msg.setTgtSessionId("*");
msg.setMsgState(MessageState.NEW);
// Criteria to send individual messages
Criteria cr = new Criteria();
cr.setInstanceName("localhost_%");
cr.setRecipientInstanceType(InstanceType.PARTICIPANT);
cr.setSessionSpecific(false);
cr.setResource("%");
cr.setPartition("%");
ObjectMapper mapper = new ObjectMapper();
SerializationConfig serializationConfig = mapper.getSerializationConfig();
serializationConfig.set(SerializationConfig.Feature.INDENT_OUTPUT, true);
StringWriter sw = new StringWriter();
mapper.writeValue(sw, cr);
String crString = sw.toString();
schedulerMessage.getRecord().setSimpleField("Criteria", crString);
schedulerMessage.getRecord().setMapField("MessageTemplate", msg.getRecord().getSimpleFields());
schedulerMessage.getRecord().setSimpleField("TIMEOUT", "-1");
schedulerMessage.getRecord().setSimpleField("WAIT_ALL", "true");
Criteria cr2 = new Criteria();
cr2.setRecipientInstanceType(InstanceType.CONTROLLER);
cr2.setInstanceName("*");
cr2.setSessionSpecific(false);
schedulerMessage.getRecord().setSimpleField(DefaultSchedulerMessageHandlerFactory.SCHEDULER_TASK_QUEUE, "TestSchedulerMsg2");
TestSchedulerMessage.MockAsyncCallback callback = new TestSchedulerMessage.MockAsyncCallback();
manager.getMessagingService().sendAndWait(cr2, schedulerMessage, callback, -1);
String msgId = callback._message.getResultMap().get(DefaultSchedulerMessageHandlerFactory.SCHEDULER_MSG_ID);
HelixDataAccessor helixDataAccessor = manager.getHelixDataAccessor();
PropertyKey.Builder keyBuilder = helixDataAccessor.keyBuilder();
for (int i = 0; i < 10; i++) {
Thread.sleep(200);
PropertyKey controllerTaskStatus = keyBuilder.controllerTaskStatus(MessageType.SCHEDULER_MSG.name(), msgId);
ZNRecord statusUpdate = helixDataAccessor.getProperty(controllerTaskStatus).getRecord();
if (statusUpdate.getMapFields().containsKey("Summary")) {
break;
}
}
Assert.assertEquals(_PARTITIONS, _factory._results.size());
PropertyKey controllerTaskStatus = keyBuilder.controllerTaskStatus(MessageType.SCHEDULER_MSG.name(), msgId);
ZNRecord statusUpdate = helixDataAccessor.getProperty(controllerTaskStatus).getRecord();
Assert.assertTrue(statusUpdate.getMapField("SentMessageCount").get("MessageCount").equals("" + (_PARTITIONS * 3)));
int messageResultCount = 0;
for (String key : statusUpdate.getMapFields().keySet()) {
if (key.startsWith("MessageResult ")) {
messageResultCount++;
}
}
Assert.assertEquals(messageResultCount, _PARTITIONS * 3);
int count = 0;
for (Set<String> val : _factory._results.values()) {
count += val.size();
}
Assert.assertEquals(count, _PARTITIONS * 3);
}
Aggregations