/*
* Copyright (c) 2015 EMC Corporation
* All Rights Reserved
*/
package com.emc.sa.engine;
import java.util.Date;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang.math.NumberUtils;
import com.emc.sa.engine.lock.ExecutionLockManager;
import com.emc.storageos.coordinator.client.service.CoordinatorClient;
import com.emc.storageos.db.client.model.uimodels.ExecutionLog;
import com.emc.storageos.db.client.model.uimodels.ExecutionLog.LogLevel;
import com.emc.storageos.model.property.PropertyInfo;
import com.emc.storageos.db.client.model.uimodels.ExecutionPhase;
import com.emc.storageos.db.client.model.uimodels.ExecutionState;
import com.emc.storageos.db.client.model.uimodels.ExecutionStatus;
import com.emc.storageos.db.client.model.uimodels.ExecutionTaskLog;
import com.emc.storageos.db.client.model.uimodels.Order;
import com.emc.storageos.db.client.model.uimodels.ScheduledEvent;
import com.emc.sa.model.dao.ModelClient;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
public class ExecutionContext {
/** Provides access to execution locks. */
private ExecutionLockManager lockManager;
/** Provides access to data objects. */
private ModelClient modelClient;
/** The state of the current execution. */
private ExecutionState executionState;
/** The name of the service being executed. */
private String serviceName;
/** The parameters available to bind to a service. */
private Map<String, Object> parameters;
/** The injected values available to execution tasks. */
private Map<Class<?>, Object> injectedValues;
/** The current rollback list to invoke if an error occurs. */
private List<ExecutionTask<?>> rollback;
/** The order id that created the execution context. */
private Order order;
/** Associated scheduled event if it is recurring order */
private ScheduledEvent scheduledEvent;
private CoordinatorClient coordinatorClient;
public ExecutionLockManager getLockManager() {
return lockManager;
}
public void setLockManager(ExecutionLockManager lockManager) {
this.lockManager = lockManager;
}
public ModelClient getModelClient() {
return modelClient;
}
public void setModelClient(ModelClient modelClient) {
this.modelClient = modelClient;
}
public ExecutionState getExecutionState() {
return executionState;
}
public void setExecutionState(ExecutionState executionState) {
this.executionState = executionState;
}
public String getServiceName() {
return serviceName;
}
public void setServiceName(String serviceName) {
this.serviceName = serviceName;
}
public Map<String, Object> getParameters() {
if (parameters == null) {
parameters = Maps.newHashMap();
}
return parameters;
}
public void setParameters(Map<String, Object> parameters) {
this.parameters = parameters;
}
public Map<Class<?>, Object> getInjectedValues() {
if (injectedValues == null) {
injectedValues = Maps.newHashMap();
}
return injectedValues;
}
public <T> void addInjectedValue(Class<? extends T> clazz, T value) {
getInjectedValues().put(clazz, value);
}
@SuppressWarnings("unchecked")
public <T> T getInjectedValue(Class<? extends T> clazz) {
return (T) getInjectedValues().get(clazz);
}
public List<ExecutionTask<?>> getRollback() {
if (rollback == null) {
rollback = Lists.newArrayList();
}
return rollback;
}
public void setRollback(List<ExecutionTask<?>> rollback) {
this.rollback = rollback;
}
public Order getOrder() {
return order;
}
public void setOrder(Order order) {
this.order = order;
}
public ExecutionStatus getExecutionStatus() {
return ExecutionStatus.valueOf(getExecutionState().getExecutionStatus());
}
public void setExecutionStatus(ExecutionStatus status) {
executionState.setExecutionStatus(status.name());
}
public void setCurrentTask(ExecutionTask<?> task) {
executionState.setCurrentTask(task != null ? task.getName() : null);
}
public ScheduledEvent getScheduledEvent() {
return scheduledEvent;
}
public void setScheduledEvent(ScheduledEvent scheduledEvent) {
this.scheduledEvent = scheduledEvent;
}
public CoordinatorClient getCoordinatorClient() {
return coordinatorClient;
}
public void setCoordinatorClient(CoordinatorClient coordinatorClient) {
this.coordinatorClient = coordinatorClient;
}
protected ExecutionPhase getExecutionPhase() {
switch (getExecutionStatus()) {
case PRECHECK:
return ExecutionPhase.PRECHECK;
case EXECUTE:
return ExecutionPhase.EXECUTE;
case ROLLBACK:
return ExecutionPhase.ROLLBACK;
default:
return ExecutionPhase.NONE;
}
}
protected String getExecutionPhaseName() {
ExecutionPhase phase = getExecutionPhase();
return phase != null ? phase.name() : null;
}
public void logMessage(LogLevel level, Throwable t, String key, Object... args) {
ExecutionLog log = new ExecutionLog();
log.setDate(new Date());
log.setLevel(level.name());
if (args.length > 0) {
log.setMessage(ExecutionUtils.getMessage(key, args));
}
else {
log.setMessage(ExecutionUtils.getMessage(key));
}
if (t != null) {
log.addStackTrace(t);
}
log.setPhase(getExecutionPhaseName());
modelClient.save(log);
executionState.addExecutionLog(log);
modelClient.save(executionState);
}
public void logDebug(String key, Object... args) {
logMessage(LogLevel.DEBUG, null, key, args);
}
public void logInfo(String key, Object... args) {
logMessage(LogLevel.INFO, null, key, args);
}
public void logWarn(String key, Object... args) {
logMessage(LogLevel.WARN, null, key, args);
}
public void logError(String key, Object... args) {
logMessage(LogLevel.ERROR, null, key, args);
}
public void logError(Throwable t, String key, Object... args) {
logMessage(LogLevel.ERROR, t, key, args);
}
public ExecutionTaskLog logCurrentTask(ExecutionTask<?> task) {
setCurrentTask(task);
ExecutionTaskLog log = new ExecutionTaskLog();
log.setDate(new Date());
log.setLevel(LogLevel.INFO.name());
log.setMessage(task.getName());
log.setDetail(task.getDetail());
log.setPhase(getExecutionPhaseName());
modelClient.save(log);
executionState.addExecutionTaskLog(log);
modelClient.save(executionState);
return log;
}
public void updateCurrentTask(ExecutionTaskLog log, ExecutionTask<?> task, long elapsedTime) {
log.setLevel(LogLevel.INFO.name());
log.setMessage(task.getName());
log.setDetail(task.getDetail());
log.setElapsed(elapsedTime);
modelClient.save(log);
}
public void updateCurrentTask(ExecutionTaskLog log, ExecutionTask<?> task, long elapsedTime, Throwable error) {
log.setLevel(LogLevel.ERROR.name());
log.addStackTrace(error);
log.setMessage(task.getName());
log.setDetail(task.getDetail());
log.setElapsed(elapsedTime);
modelClient.save(log);
}
public void updateTaskLog(ExecutionTaskLog log, long elapsedTime) {
log.setLevel(LogLevel.INFO.name());
log.setElapsed(elapsedTime);
modelClient.save(log);
}
public void updateTaskLog(ExecutionTaskLog log, long elapsedTime, Throwable error) {
log.setLevel(LogLevel.ERROR.name());
log.setElapsed(elapsedTime);
log.addStackTrace(error);
modelClient.save(log);
}
public long getResourceLimit(String name) {
PropertyInfo sysprops = coordinatorClient.getPropertyInfo();
String value = sysprops.getProperty(name);
return NumberUtils.toLong(value);
}
}