use of org.apache.helix.HelixDataAccessor in project helix by apache.
the class ParticipantHealthReportCollectorImpl method transmitHealthReports.
@Override
public synchronized void transmitHealthReports() {
synchronized (_healthReportProviderList) {
for (HealthReportProvider provider : _healthReportProviderList) {
try {
Map<String, String> report = provider.getRecentHealthReport();
Map<String, Map<String, String>> partitionReport = provider.getRecentPartitionHealthReport();
ZNRecord record = new ZNRecord(provider.getReportName());
if (report != null) {
record.setSimpleFields(report);
}
if (partitionReport != null) {
record.setMapFields(partitionReport);
}
record.setSimpleField(HealthStat.TIMESTAMP_NAME, "" + System.currentTimeMillis());
HelixDataAccessor accessor = _helixManager.getHelixDataAccessor();
Builder keyBuilder = accessor.keyBuilder();
if (!accessor.setProperty(keyBuilder.healthReport(_instanceName, record.getId()), new HealthStat(record))) {
LOG.error("Failed to persist health report to zk!");
}
provider.resetStats();
} catch (Exception e) {
LOG.error("fail to transmit health report", e);
}
}
}
}
use of org.apache.helix.HelixDataAccessor 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);
}
}
use of org.apache.helix.HelixDataAccessor in project helix by apache.
the class DistributedLeaderElection method tryUpdateController.
private boolean tryUpdateController(HelixManager manager) {
HelixDataAccessor accessor = manager.getHelixDataAccessor();
Builder keyBuilder = accessor.keyBuilder();
LiveInstance leader = new LiveInstance(manager.getInstanceName());
try {
leader.setLiveInstance(ManagementFactory.getRuntimeMXBean().getName());
leader.setSessionId(manager.getSessionId());
leader.setHelixVersion(manager.getVersion());
boolean success = accessor.createControllerLeader(leader);
if (success) {
return true;
} else {
LOG.info("Unable to become leader probably because some other controller becames the leader");
}
} catch (Exception e) {
LOG.error("Exception when trying to updating leader record in cluster:" + manager.getClusterName() + ". Need to check again whether leader node has been created or not", e);
}
leader = accessor.getProperty(keyBuilder.controllerLeader());
if (leader != null) {
String leaderSessionId = leader.getSessionId();
LOG.info("Leader exists for cluster: " + manager.getClusterName() + ", currentLeader: " + leader.getInstanceName() + ", leaderSessionId: " + leaderSessionId);
if (leaderSessionId != null && leaderSessionId.equals(manager.getSessionId())) {
return true;
}
}
return false;
}
use of org.apache.helix.HelixDataAccessor in project helix by apache.
the class TestDisableCustomCodeRunner method test.
@Test
public void test() throws Exception {
String className = TestHelper.getTestClassName();
String methodName = TestHelper.getTestMethodName();
String clusterName = className + "_" + methodName;
System.out.println("START " + clusterName + " at " + new Date(System.currentTimeMillis()));
// participant port
TestHelper.setupCluster(// participant port
clusterName, // participant port
ZK_ADDR, // participant port
12918, // participant name prefix
"localhost", // resource name prefix
"TestDB", // resources
1, // partitions per resource
PARTITION_NUM, // number of nodes
N, // replicas
2, "MasterSlave", // do rebalance
true);
ClusterControllerManager controller = new ClusterControllerManager(ZK_ADDR, clusterName, "controller");
controller.syncStart();
// start participants
Map<String, MockParticipantManager> participants = new HashMap<String, MockParticipantManager>();
Map<String, HelixCustomCodeRunner> customCodeRunners = new HashMap<String, HelixCustomCodeRunner>();
Map<String, DummyCallback> callbacks = new HashMap<String, DummyCallback>();
for (int i = 0; i < N; i++) {
String instanceName = "localhost_" + (12918 + i);
participants.put(instanceName, new MockParticipantManager(ZK_ADDR, clusterName, instanceName));
customCodeRunners.put(instanceName, new HelixCustomCodeRunner(participants.get(instanceName), ZK_ADDR));
callbacks.put(instanceName, new DummyCallback());
customCodeRunners.get(instanceName).invoke(callbacks.get(instanceName)).on(ChangeType.LIVE_INSTANCE).usingLeaderStandbyModel("TestParticLeader").start();
participants.get(instanceName).syncStart();
}
boolean result = ClusterStateVerifier.verifyByZkCallback(new ClusterStateVerifier.BestPossAndExtViewZkVerifier(ZK_ADDR, clusterName));
Assert.assertTrue(result);
// Make sure callback is registered
BaseDataAccessor<ZNRecord> baseAccessor = new ZkBaseDataAccessor<ZNRecord>(_gZkClient);
final HelixDataAccessor accessor = new ZKHelixDataAccessor(clusterName, baseAccessor);
PropertyKey.Builder keyBuilder = accessor.keyBuilder();
final String customCodeRunnerResource = customCodeRunners.get("localhost_12918").getResourceName();
ExternalView extView = accessor.getProperty(keyBuilder.externalView(customCodeRunnerResource));
Map<String, String> instanceStates = extView.getStateMap(customCodeRunnerResource + "_0");
String leader = null;
for (String instance : instanceStates.keySet()) {
String state = instanceStates.get(instance);
if ("LEADER".equals(state)) {
leader = instance;
break;
}
}
Assert.assertNotNull(leader);
for (String instance : callbacks.keySet()) {
DummyCallback callback = callbacks.get(instance);
if (instance.equals(leader)) {
Assert.assertTrue(callback.isInitTypeInvoked());
} else {
Assert.assertFalse(callback.isInitTypeInvoked());
}
callback.reset();
}
// Disable custom-code runner resource
HelixAdmin admin = new ZKHelixAdmin(_gZkClient);
admin.enableResource(clusterName, customCodeRunnerResource, false);
// Verify that states of custom-code runner are all OFFLINE
result = TestHelper.verify(new TestHelper.Verifier() {
@Override
public boolean verify() throws Exception {
PropertyKey.Builder keyBuilder = accessor.keyBuilder();
ExternalView extView = accessor.getProperty(keyBuilder.externalView(customCodeRunnerResource));
if (extView == null) {
return false;
}
Set<String> partitionSet = extView.getPartitionSet();
if (partitionSet == null || partitionSet.size() != PARTITION_NUM) {
return false;
}
for (String partition : partitionSet) {
Map<String, String> instanceStates = extView.getStateMap(partition);
for (String state : instanceStates.values()) {
if (!"OFFLINE".equals(state)) {
return false;
}
}
}
return true;
}
}, 10 * 1000);
Assert.assertTrue(result);
// Change live-instance should not invoke any custom-code runner
LiveInstance fakeInstance = new LiveInstance("fakeInstance");
fakeInstance.setSessionId("fakeSessionId");
fakeInstance.setHelixVersion("0.6");
accessor.setProperty(keyBuilder.liveInstance("fakeInstance"), fakeInstance);
Thread.sleep(1000);
for (Map.Entry<String, DummyCallback> e : callbacks.entrySet()) {
String instance = e.getKey();
DummyCallback callback = e.getValue();
Assert.assertFalse(callback.isInitTypeInvoked());
Assert.assertFalse(callback.isCallbackTypeInvoked());
// Ensure that we were told that a leader stopped being the leader
if (instance.equals(leader)) {
Assert.assertTrue(callback.isFinalizeTypeInvoked());
}
}
// Remove fake instance
accessor.removeProperty(keyBuilder.liveInstance("fakeInstance"));
// Re-enable custom-code runner
admin.enableResource(clusterName, customCodeRunnerResource, true);
result = ClusterStateVerifier.verifyByZkCallback(new ClusterStateVerifier.BestPossAndExtViewZkVerifier(ZK_ADDR, clusterName));
Assert.assertTrue(result);
// Verify that custom-invoke is invoked again
extView = accessor.getProperty(keyBuilder.externalView(customCodeRunnerResource));
instanceStates = extView.getStateMap(customCodeRunnerResource + "_0");
leader = null;
for (String instance : instanceStates.keySet()) {
String state = instanceStates.get(instance);
if ("LEADER".equals(state)) {
leader = instance;
break;
}
}
Assert.assertNotNull(leader);
for (String instance : callbacks.keySet()) {
DummyCallback callback = callbacks.get(instance);
if (instance.equals(leader)) {
Assert.assertTrue(callback.isInitTypeInvoked());
} else {
Assert.assertFalse(callback.isInitTypeInvoked());
}
callback.reset();
}
// Add a fake instance should invoke custom-code runner
accessor.setProperty(keyBuilder.liveInstance("fakeInstance"), fakeInstance);
Thread.sleep(1000);
for (String instance : callbacks.keySet()) {
DummyCallback callback = callbacks.get(instance);
if (instance.equals(leader)) {
Assert.assertTrue(callback.isCallbackTypeInvoked());
} else {
Assert.assertFalse(callback.isCallbackTypeInvoked());
}
}
// Clean up
controller.syncStop();
for (MockParticipantManager participant : participants.values()) {
participant.syncStop();
}
System.out.println("END " + clusterName + " at " + new Date(System.currentTimeMillis()));
}
use of org.apache.helix.HelixDataAccessor in project helix by apache.
the class TestDisableResource method testDisableResourceInCustomMode.
@Test
public void testDisableResourceInCustomMode() throws Exception {
String className = TestHelper.getTestClassName();
String methodName = TestHelper.getTestMethodName();
String clusterName = className + "_" + methodName;
System.out.println("START " + clusterName + " at " + new Date(System.currentTimeMillis()));
// participant port
TestHelper.setupCluster(// participant port
clusterName, // participant port
ZK_ADDR, // participant port
12918, // participant name prefix
"localhost", // resource name prefix
"TestDB", // resources
1, // partitions per resource
PARTITION_NUM, // number of nodes
N, // replicas
2, "MasterSlave", RebalanceMode.CUSTOMIZED, // do rebalance
true);
// set up custom ideal-state
BaseDataAccessor<ZNRecord> baseAccessor = new ZkBaseDataAccessor<ZNRecord>(_gZkClient);
HelixDataAccessor accessor = new ZKHelixDataAccessor(clusterName, baseAccessor);
PropertyKey.Builder keyBuilder = accessor.keyBuilder();
IdealState idealState = accessor.getProperty(keyBuilder.idealStates("TestDB0"));
idealState.setPartitionState("TestDB0_0", "localhost_12918", "SLAVE");
idealState.setPartitionState("TestDB0_0", "localhost_12919", "SLAVE");
accessor.setProperty(keyBuilder.idealStates("TestDB0"), idealState);
ClusterControllerManager controller = new ClusterControllerManager(ZK_ADDR, clusterName, "controller");
controller.syncStart();
// start participants
MockParticipantManager[] participants = new MockParticipantManager[N];
for (int i = 0; i < N; i++) {
String instanceName = "localhost_" + (12918 + i);
participants[i] = new MockParticipantManager(ZK_ADDR, clusterName, instanceName);
participants[i].syncStart();
}
boolean result = ClusterStateVerifier.verifyByZkCallback(new ClusterStateVerifier.BestPossAndExtViewZkVerifier(ZK_ADDR, clusterName));
Assert.assertTrue(result);
// Disable TestDB0
enableResource(clusterName, false);
checkExternalView(clusterName);
// Re-enable TestDB0
enableResource(clusterName, true);
result = ClusterStateVerifier.verifyByPolling(new ClusterStateVerifier.BestPossAndExtViewZkVerifier(ZK_ADDR, clusterName));
Assert.assertTrue(result);
// Clean up
controller.syncStop();
for (int i = 0; i < N; i++) {
participants[i].syncStop();
}
System.out.println("END " + clusterName + " at " + new Date(System.currentTimeMillis()));
}
Aggregations