use of org.apache.helix.model.builder.HelixConfigScopeBuilder in project helix by apache.
the class ClusterAccessor method updateClusterConfig.
@POST
@Path("{clusterId}/configs")
public Response updateClusterConfig(@PathParam("clusterId") String clusterId, @QueryParam("command") String commandStr, String content) {
Command command;
try {
command = getCommand(commandStr);
} catch (HelixException ex) {
return badRequest(ex.getMessage());
}
ZNRecord record;
try {
record = toZNRecord(content);
} catch (IOException e) {
_logger.error("Failed to deserialize user's input " + content + ", Exception: " + e);
return badRequest("Input is not a valid ZNRecord!");
}
if (!record.getId().equals(clusterId)) {
return badRequest("ID does not match the cluster name in input!");
}
ClusterConfig config = new ClusterConfig(record);
ConfigAccessor configAccessor = getConfigAccessor();
try {
switch(command) {
case update:
configAccessor.updateClusterConfig(clusterId, config);
break;
case delete:
{
HelixConfigScope clusterScope = new HelixConfigScopeBuilder(HelixConfigScope.ConfigScopeProperty.CLUSTER).forCluster(clusterId).build();
configAccessor.remove(clusterScope, config.getRecord());
}
break;
default:
return badRequest("Unsupported command " + commandStr);
}
} catch (HelixException ex) {
return notFound(ex.getMessage());
} catch (Exception ex) {
_logger.error("Failed to " + command + " cluster config, cluster " + clusterId + " new config: " + content + ", Exception: " + ex);
return serverError(ex);
}
return OK();
}
use of org.apache.helix.model.builder.HelixConfigScopeBuilder in project helix by apache.
the class ConfigResource method getConfigKeys.
StringRepresentation getConfigKeys(ConfigScopeProperty scopeProperty, String... keys) throws Exception {
StringRepresentation representation = null;
ZkClient zkClient = ResourceUtil.getAttributeFromCtx(getContext(), ResourceUtil.ContextKey.ZKCLIENT);
ClusterSetup setupTool = new ClusterSetup(zkClient);
HelixAdmin admin = setupTool.getClusterManagementTool();
ZNRecord record = new ZNRecord(scopeProperty + " Config");
HelixConfigScope scope = new HelixConfigScopeBuilder(scopeProperty, keys).build();
List<String> configKeys = admin.getConfigKeys(scope);
record.setListField(scopeProperty.toString(), configKeys);
representation = new StringRepresentation(ClusterRepresentationUtil.ZNRecordToJson(record), MediaType.APPLICATION_JSON);
return representation;
}
use of org.apache.helix.model.builder.HelixConfigScopeBuilder in project helix by apache.
the class AgentStateModel method genericStateTransitionHandler.
@Transition(to = "*", from = "*")
public void genericStateTransitionHandler(Message message, NotificationContext context) throws Exception {
// first try get command from message
String cmd = message.getRecord().getSimpleField(CommandAttribute.COMMAND.getName());
String workingDir = message.getRecord().getSimpleField(CommandAttribute.WORKING_DIR.getName());
String timeout = message.getRecord().getSimpleField(CommandAttribute.TIMEOUT.getName());
String pidFile = message.getRecord().getSimpleField(CommandAttribute.PID_FILE.getName());
HelixManager manager = context.getManager();
String clusterName = manager.getClusterName();
String fromState = message.getFromState();
String toState = message.getToState();
// construct keys for command-config
String cmdKey = buildKey(fromState, toState, CommandAttribute.COMMAND);
String workingDirKey = buildKey(fromState, toState, CommandAttribute.WORKING_DIR);
String timeoutKey = buildKey(fromState, toState, CommandAttribute.TIMEOUT);
String pidFileKey = buildKey(fromState, toState, CommandAttribute.PID_FILE);
List<String> cmdConfigKeys = Arrays.asList(cmdKey, workingDirKey, timeoutKey, pidFileKey);
// read command from resource-scope configures
if (cmd == null) {
HelixConfigScope resourceScope = new HelixConfigScopeBuilder(ConfigScopeProperty.RESOURCE).forCluster(clusterName).forResource(message.getResourceName()).build();
Map<String, String> cmdKeyValueMap = manager.getConfigAccessor().get(resourceScope, cmdConfigKeys);
if (cmdKeyValueMap != null) {
cmd = cmdKeyValueMap.get(cmdKey);
workingDir = cmdKeyValueMap.get(workingDirKey);
timeout = cmdKeyValueMap.get(timeoutKey);
pidFile = cmdKeyValueMap.get(pidFileKey);
}
}
// if resource-scope doesn't contain command, fall back to cluster-scope configures
if (cmd == null) {
HelixConfigScope clusterScope = new HelixConfigScopeBuilder(ConfigScopeProperty.CLUSTER).forCluster(clusterName).build();
Map<String, String> cmdKeyValueMap = manager.getConfigAccessor().get(clusterScope, cmdConfigKeys);
if (cmdKeyValueMap != null) {
cmd = cmdKeyValueMap.get(cmdKey);
workingDir = cmdKeyValueMap.get(workingDirKey);
timeout = cmdKeyValueMap.get(timeoutKey);
pidFile = cmdKeyValueMap.get(pidFileKey);
}
}
if (cmd == null) {
throw new Exception("Unable to find command for transition from:" + message.getFromState() + " to:" + message.getToState());
}
_logger.info("Executing command: " + cmd + ", using workingDir: " + workingDir + ", timeout: " + timeout + ", on " + manager.getInstanceName());
// skip nop command
if (cmd.equals(CommandAttribute.NOP.getName())) {
return;
}
// split the cmd to actual cmd and args[]
String[] cmdSplits = cmd.trim().split("\\s+");
String cmdValue = cmdSplits[0];
String[] args = Arrays.copyOfRange(cmdSplits, 1, cmdSplits.length);
// get the command-execution timeout
// 0 means wait for ever
long timeoutValue = 0;
if (timeout != null) {
try {
timeoutValue = Long.parseLong(timeout);
} catch (NumberFormatException e) {
// OK to use 0
}
}
ExternalCommand externalCmd = ExternalCommand.executeWithTimeout(new File(workingDir), cmdValue, timeoutValue, args);
int exitValue = externalCmd.exitValue();
if (_logger.isDebugEnabled()) {
_logger.debug("command: " + cmd + ", exitValue: " + exitValue + " output:\n" + externalCmd.getStringOutput());
}
// monitor pid if pidFile exists
if (pidFile == null) {
// no pid to monitor
return;
}
String pidFileValue = instantiateByMessage(pidFile, message);
String pid = SystemUtil.getPidFromFile(new File(pidFileValue));
if (pid != null) {
new ProcessMonitorThread(pid).start();
}
}
use of org.apache.helix.model.builder.HelixConfigScopeBuilder in project helix by apache.
the class TestHelixAgent method test.
@Test
public void test() throws Exception {
String className = TestHelper.getTestClassName();
String methodName = TestHelper.getTestMethodName();
final String clusterName = className + "_" + methodName;
final int n = 1;
final String zkAddr = ZK_ADDR;
System.out.println("START " + clusterName + " at " + new Date(System.currentTimeMillis()));
// participant port
TestHelper.setupCluster(// participant port
clusterName, // participant port
zkAddr, // participant port
12918, // participant name prefix
"localhost", // resource name prefix
"TestDB", // resources
1, // partitions per resource
1, // number of nodes
n, // replicas
1, "MasterSlave", // do rebalance
true);
// set cluster config
HelixConfigScope scope = new HelixConfigScopeBuilder(ConfigScopeProperty.CLUSTER).forCluster(clusterName).build();
ConfigAccessor configAccessor = new ConfigAccessor(_gZkClient);
// String pidFile = ScriptTestHelper.getPrefix() + ScriptTestHelper.INTEGRATION_LOG_DIR +
// "/default/foo_{PARTITION_NAME}_pid.txt";
// the pid file path for the first partition
// delete it if exists
// String pidFileFirstPartition = ScriptTestHelper.getPrefix() +
// ScriptTestHelper.INTEGRATION_LOG_DIR + "/default/foo_TestDB0_0_pid.txt";
// File file = new File(pidFileFirstPartition);
// if (file.exists()) {
// file.delete();
// }
// set commands for state-transitions
CommandConfig.Builder builder = new CommandConfig.Builder();
CommandConfig cmdConfig = builder.setTransition("SLAVE", "MASTER").setCommand("simpleHttpClient.py SLAVE-MASTER").setCommandWorkingDir(workingDir).setCommandTimeout("0").build();
configAccessor.set(scope, cmdConfig.toKeyValueMap());
builder = new CommandConfig.Builder();
cmdConfig = builder.setTransition("OFFLINE", "SLAVE").setCommand("simpleHttpClient.py OFFLINE-SLAVE").setCommandWorkingDir(workingDir).build();
configAccessor.set(scope, cmdConfig.toKeyValueMap());
builder = new CommandConfig.Builder();
cmdConfig = builder.setTransition("MASTER", "SLAVE").setCommand("simpleHttpClient.py MASTER-SLAVE").setCommandWorkingDir(workingDir).build();
configAccessor.set(scope, cmdConfig.toKeyValueMap());
builder = new CommandConfig.Builder();
cmdConfig = builder.setTransition("SLAVE", "OFFLINE").setCommand("simpleHttpClient.py SLAVE-OFFLINE").setCommandWorkingDir(workingDir).build();
configAccessor.set(scope, cmdConfig.toKeyValueMap());
builder = new CommandConfig.Builder();
cmdConfig = builder.setTransition("OFFLINE", "DROPPED").setCommand(CommandAttribute.NOP.getName()).build();
configAccessor.set(scope, cmdConfig.toKeyValueMap());
// start controller
ClusterControllerManager controller = new ClusterControllerManager(zkAddr, clusterName, "controller_0");
controller.syncStart();
// start helix-agent
Map<String, Thread> agents = new HashMap<String, Thread>();
for (int i = 0; i < n; i++) {
final String instanceName = "localhost_" + (12918 + i);
Thread agentThread = new Thread() {
@Override
public void run() {
try {
HelixAgentMain.main(new String[] { "--zkSvr", zkAddr, "--cluster", clusterName, "--instanceName", instanceName, "--stateModel", "MasterSlave" });
} catch (Exception e) {
LOG.error("Exception start helix-agent", e);
}
}
};
agents.put(instanceName, agentThread);
agentThread.start();
// wait participant thread to start
Thread.sleep(100);
}
boolean result = ClusterStateVerifier.verifyByZkCallback(new BestPossAndExtViewZkVerifier(ZK_ADDR, clusterName));
Assert.assertTrue(result);
// read the pid file should get current process id
// String readPid = SystemUtil.getPidFromFile(new File(pidFileFirstPartition));
// Assert.assertNotNull(readPid, "readPid is the pid for foo_test.py. should NOT be null");
// String name = ManagementFactory.getRuntimeMXBean().getName();
// String currentPid = name.substring(0,name.indexOf("@"));
// System.out.println("read-pid: " + readPid + ", current-pid: " + currentPid);
// drop resource will trigger M->S and S->O transitions
ClusterSetup.processCommandLineArgs(new String[] { "--zkSvr", ZK_ADDR, "--dropResource", clusterName, "TestDB0" });
result = ClusterStateVerifier.verifyByZkCallback(new BestPossAndExtViewZkVerifier(ZK_ADDR, clusterName));
Assert.assertTrue(result);
// clean up
controller.syncStop();
for (Thread agentThread : agents.values()) {
agentThread.interrupt();
}
System.out.println("END " + clusterName + " at " + new Date(System.currentTimeMillis()));
}
use of org.apache.helix.model.builder.HelixConfigScopeBuilder in project helix by apache.
the class ConfigAccessor method getClusterConfig.
/**
* Get ClusterConfig of the given cluster.
*
* @param clusterName
*
* @return
*/
public ClusterConfig getClusterConfig(String clusterName) {
if (!ZKUtil.isClusterSetup(clusterName, zkClient)) {
throw new HelixException("fail to get config. cluster: " + clusterName + " is NOT setup.");
}
HelixConfigScope scope = new HelixConfigScopeBuilder(ConfigScopeProperty.CLUSTER).forCluster(clusterName).build();
ZNRecord record = getConfigZnRecord(scope);
if (record == null) {
LOG.warn("No config found at " + scope.getZkPath());
return null;
}
return new ClusterConfig(record);
}
Aggregations