package edu.usc.pgroup.floe.coordinator.transitions;
import edu.usc.pgroup.floe.coordinator.Coordinator;
import edu.usc.pgroup.floe.utils.Utils;
import edu.usc.pgroup.floe.zookeeper.ZKClient;
import edu.usc.pgroup.floe.zookeeper.ZKUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Map;
/**
* @author kumbhare
* TODO: Transition and execute may be a misnomer. Change this later.
*/
public final class Transitions {
/**
* Logger.
*/
private static final Logger LOGGER =
LoggerFactory.getLogger(Transitions.class);
/**
* hiding the default constructor.
*/
private Transitions() {
}
/**
* Transition to be executed at the cluster level. e.g. start/stop a new
* application.
* Start the execution in a new thread.
* Uses ZK for coordination.
* Returns immediately.
* @param transition cluster transition to be executed.
* @param args arguments
* @throws Exception Exception wrapper for any exceptions that occur
* during the transition.
*/
public static synchronized void execute(final ClusterTransition transition,
final Map<String, Object> args)
throws Exception {
//Get the cluster status. If it is not AVAILABLE. throw an exception.
// Else. Lock the ZK field, set the status to Busy and start the
// execution of the transaction.
//also set the transaction completed listener.
byte[] bstatus = ZKClient.getInstance().getCuratorClient().getData()
.forPath(ZKUtils.getClusterStatusPath());
Coordinator.ClusterStatus clusterStatus
= (Coordinator.ClusterStatus) Utils.deserialize(bstatus);
if (clusterStatus != Coordinator.ClusterStatus.AVAILABLE) {
throw new ClusterBusyException(clusterStatus);
}
ZKUtils.setClusterStatus(Coordinator.ClusterStatus.BUSY);
transition.addTransitionListener(new TransitionListener() {
@Override
public void transitionCompleted(final Transition transition) {
try {
LOGGER.info("Transition Completed.");
ZKUtils.setClusterStatus(
Coordinator.ClusterStatus.AVAILABLE);
} catch (Exception e) {
LOGGER.error("Error occurred while updating the cluster "
+ "status. Any updates from now on might be "
+ "invalid. Restart the Coordinator to resume "
+ "operations. Exception: {}", e);
}
}
});
try {
transition.executeAsync(args);
} catch (Exception e) {
LOGGER.warn("Error occurred while executing transaction: "
+ transition.getName());
}
}
/**
* Transition to be executed at the cluster level. e.g. start/stop a new
* application.
* Start the execution in a new thread.
* Uses ZK for coordination.
* Returns immediately.
* @param transition cluster transition to be executed.
* @param appName Application name for which the given transition is to
* be executed.
* @param args arguments
* @throws Exception Exception wrapper for any exceptions that occur
* during the transition.
*/
public static synchronized void execute(final AppTransition transition,
final String appName,
final Map<String, Object> args)
throws Exception {
transition.execute(args);
}
}