/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hms.controller;
import java.io.EOFException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hms.controller.CommandHandler;
import org.apache.hms.common.conf.CommonConfigurationKeys;
import org.apache.hms.common.entity.cluster.MachineState;
import org.apache.hms.common.entity.command.Command;
import org.apache.hms.common.entity.command.CommandStatus;
import org.apache.hms.common.entity.command.CreateCommand;
import org.apache.hms.common.entity.command.DeleteCommand;
import org.apache.hms.common.entity.command.StatusCommand;
import org.apache.hms.common.entity.manifest.ClusterHistory;
import org.apache.hms.common.entity.manifest.ClusterManifest;
import org.apache.hms.common.entity.Response;
import org.apache.hms.common.util.ExceptionUtil;
import org.apache.hms.common.util.JAXBUtil;
import org.apache.hms.common.util.ZookeeperUtil;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.ZooDefs.Ids;
public class ClientHandler {
private static Log LOG = LogFactory.getLog(ClientHandler.class);
private ZooKeeper zk;
public ClientHandler(ZooKeeper zk) {
this.zk = zk;
try {
if (zk.exists(CommonConfigurationKeys.ZOOKEEPER_COMMAND_QUEUE_PATH_DEFAULT, null) == null) {
LOG.error("HMS command queue at " + CommonConfigurationKeys.ZOOKEEPER_COMMAND_QUEUE_PATH_DEFAULT + " doesn't exist");
}
} catch (Exception e) {
LOG.error(ExceptionUtil.getStackTrace(e));
}
LOG.info("Created one ClientHandler object");
}
public String queueCmd(Command cmd) throws KeeperException, InterruptedException, IOException {
String path = zk.create(CommonConfigurationKeys.ZOOKEEPER_COMMAND_QUEUE_PATH_DEFAULT + "/cmd-", JAXBUtil.write(cmd), Ids.OPEN_ACL_UNSAFE,
CreateMode.PERSISTENT_SEQUENTIAL);
LOG.info("Queued command: " + cmd);
return path.substring(path.lastIndexOf('/') + 1);
}
// public Response createCluster2(CreateClusterCommand cmd) throws IOException {
// LOG.info("Received COMMAND: " + cmd);
// String output = null;
// Response r = new Response();
// try {
// ((ClusterManifest) cmd.getClusterManifest()).load();
// String clusterName = cmd.getClusterManifest().getClusterName();
// String clusterPath = CommonConfigurationKeys.ZOOKEEPER_CLUSTER_ROOT_DEFAULT + "/" + clusterName;
// if (zk.exists(clusterPath, null) != null) {
// String msg = "Cluster [" + clusterName + "] already exists. CREATE operation aborted.";
// LOG.warn(msg);
// r.setOutput(msg);
// r.setCode(1);
// return r;
// }
// output = queueCmd(cmd);
// } catch (Exception e) {
// LOG.warn(ExceptionUtil.getStackTrace(e));
// r.setOutput(e.getMessage());
// r.setCode(1);
// return r;
// }
// r.setOutput(output);
// r.setCode(0);
// return r;
// }
// public Response createCluster(CreateCommand cmd) throws IOException {
// LOG.info("Received COMMAND: " + cmd);
// String output = null;
// Response r = new Response();
// try {
// String clusterPath = CommonConfigurationKeys.ZOOKEEPER_CLUSTER_ROOT_DEFAULT + "/" + cmd.getClusterName();
// if (zk.exists(clusterPath, null) != null) {
// String msg = "Cluster [" + cmd.getClusterName() + "] already exists. CREATE operation aborted.";
// LOG.warn(msg);
// r.setOutput(msg);
// r.setCode(1);
// return r;
// }
// output = queueCmd(cmd);
// } catch (Exception e) {
// LOG.warn(ExceptionUtil.getStackTrace(e));
// r.setOutput(e.getMessage());
// r.setCode(1);
// return r;
// }
// r.setOutput(output);
// r.setCode(0);
// return r;
// }
//
// public Response deleteCluster(DeleteCommand cmd) throws IOException {
// LOG.info("Received COMMAND: " + cmd);
// String output = null;
// Response r = new Response();
// try {
// String clusterPath = CommonConfigurationKeys.ZOOKEEPER_CLUSTER_ROOT_DEFAULT + "/" + cmd.getClusterName();
// if ( zk.exists(clusterPath, null) == null) {
// String msg = "Cluster [" + cmd.getClusterName() + "] doesn't exist. Delete operation aborted.";
// LOG.warn(msg);
// r.setOutput(msg);
// r.setCode(1);
// return r;
// }
// output = queueCmd(cmd);
// } catch (Exception e) {
// LOG.warn(ExceptionUtil.getStackTrace(e));
// r.setOutput(e.getMessage());
// r.setCode(1);
// return r;
// }
// r.setOutput(output);
// r.setCode(0);
// return r;
// }
public ClusterManifest checkClusterStatus(String clusterId) throws IOException {
String clusterPath = ZookeeperUtil.getClusterPath(clusterId);
try {
if(zk.exists(clusterPath, null) == null) {
throw new IOException("Cluster "+clusterId+" does not exist.");
}
ClusterHistory history = JAXBUtil.read(zk.getData(clusterPath, false, null), ClusterHistory.class);
int index = history.getHistory().size()-1;
ClusterManifest cm = history.getHistory().get(index);
return cm;
} catch(Throwable e) {
throw new IOException(e);
}
}
// public Response checkStatus(StatusCommand cmd) throws IOException {
// LOG.info("Received COMMAND: " + cmd);
// Response r = new Response();
// try {
// String nodePath = cmd.getNodePath();
// if (nodePath != null) {
// if (zk.exists(nodePath, null) == null) {
// String msg = "Node " + nodePath + " doesn't exist";
// LOG.warn(msg);
// r.setOutput(msg);
// r.setCode(1);
// return r;
// }
// MachineState state = JAXBUtil.read(zk.getData(nodePath, false, null),
// MachineState.class);
// r.setOutput(state.toString());
// r.setCode(0);
// return r;
// }
// String cmdPath = CommonConfigurationKeys.ZOOKEEPER_COMMAND_QUEUE_PATH_DEFAULT + "/" + cmd.getCmdId();
// if ( zk.exists(cmdPath, null) == null) {
// String msg = "Command " + cmd.getCmdId() + " doesn't exist";
// LOG.warn(msg);
// r.setOutput(msg);
// r.setCode(1);
// return r;
// }
// String cmdStatusPath = cmdPath + CommandHandler.COMMAND_STATUS;
// CommandStatus status = null;
// try {
// status = JAXBUtil.read(zk.getData(cmdStatusPath, false, null), CommandStatus.class);
// } catch (KeeperException.NoNodeException e) {
// r.setOutput("Command " + cmd.getCmdId() + ": not yet started");
// r.setCode(0);
// return r;
// }
// StringBuilder sb = new StringBuilder(status.toString());
// List<String> children = zk.getChildren(cmdStatusPath, null);
// if (children != null) {
// for (String child : children) {
// ActionStatus as = JAXBUtil.read(zk.getData(cmdStatusPath + "/" + child, false, null), ActionStatus.class);
// sb.append("\nactionId=");
// sb.append(as.getActionId());
// sb.append(", host=");
// sb.append(as.getHost());
// sb.append(", status=");
// sb.append(as.getStatus());
// sb.append(", error msg: ");
// sb.append(as.getError());
// }
// }
// r.setOutput(sb.toString());
// r.setCode(0);
// return r;
// } catch (Exception e) {
// LOG.warn(ExceptionUtil.getStackTrace(e));
// r.setOutput(e.getMessage());
// r.setCode(1);
// return r;
// }
// }
public MachineState checkNodeStatus(String nodePath) throws IOException {
LOG.info("Received Node Path: " + nodePath);
try {
if (zk.exists(nodePath, null) == null) {
String msg = "Node " + nodePath + " doesn't exist";
LOG.warn(msg);
throw new IOException(msg);
}
MachineState state = JAXBUtil.read(zk.getData(nodePath, false, null),
MachineState.class);
return state;
} catch (Exception e) {
LOG.warn(ExceptionUtil.getStackTrace(e));
throw new IOException(e);
}
}
public CommandStatus checkCommandStatus(StatusCommand cmd) throws IOException {
try {
String cmdPath = CommonConfigurationKeys.ZOOKEEPER_COMMAND_QUEUE_PATH_DEFAULT + "/" + cmd.getCmdId();
if ( zk.exists(cmdPath, null) == null) {
String msg = "Command " + cmd.getCmdId() + " doesn't exist";
LOG.warn(msg);
throw new IOException(msg);
}
String cmdStatusPath = cmdPath + CommandHandler.COMMAND_STATUS;
CommandStatus status = null;
try {
status = JAXBUtil.read(zk.getData(cmdStatusPath, false, null),
CommandStatus.class);
} catch (KeeperException.NoNodeException e) {
String msg = "Command " + cmd.getCmdId() + ": not yet started";
throw new IOException(msg);
}
return status;
} catch (Exception e) {
LOG.warn(ExceptionUtil.getStackTrace(e));
throw new IOException(e);
}
}
public List<Command> listCommand() throws IOException {
List<Command> list = new ArrayList<Command>();
try {
String cmdPath = CommonConfigurationKeys.ZOOKEEPER_COMMAND_QUEUE_PATH_DEFAULT;
if(zk.exists(cmdPath, null) == null) {
throw new IOException("Command Queue does not exist.");
}
List<String> commands = zk.getChildren(cmdPath, null);
for(String command : commands) {
StringBuilder cmdStatusPath = new StringBuilder();
cmdStatusPath.append(cmdPath);
cmdStatusPath.append("/");
cmdStatusPath.append(command);
Command cmd = JAXBUtil.read(zk.getData(cmdStatusPath.toString(), false, null),
Command.class);
cmd.setId(command);
list.add(cmd);
}
return list;
} catch(Exception e) {
LOG.warn(ExceptionUtil.getStackTrace(e));
throw new IOException(e);
}
}
public List<ClusterManifest> listClusters() throws IOException {
List<ClusterManifest> list = new ArrayList<ClusterManifest>();
try {
String cmdPath = CommonConfigurationKeys.ZOOKEEPER_CLUSTER_ROOT_DEFAULT;
if(zk.exists(cmdPath, null) == null) {
throw new IOException("No cluster exists.");
}
List<String> commands = zk.getChildren(cmdPath, null);
for(String command : commands) {
StringBuilder cmdStatusPath = new StringBuilder();
cmdStatusPath.append(cmdPath);
cmdStatusPath.append("/");
cmdStatusPath.append(command);
try {
ClusterHistory history = JAXBUtil.read(zk.getData(cmdStatusPath.toString(), false, null),
ClusterHistory.class);
int index = history.getHistory().size()-1;
ClusterManifest cluster = history.getHistory().get(index);
list.add(cluster);
} catch(EOFException skip) {
// Skip cluster if the cluster node is in the process of being created.
}
}
return list;
} catch(Exception e) {
LOG.warn(ExceptionUtil.getStackTrace(e));
throw new IOException(e);
}
}
}