use of com.emc.storageos.svcs.errorhandling.model.ServiceCoded in project coprhd-controller by CoprHD.
the class WorkflowService method rollbackInnerWorkflow.
/**
* Rolls back a workflow that is assumed to be a child of the given stepId.
* Updates the step status to EXECUTING if workflow is successfully initiated,
* and aranges for a rollback completer to mark the step as SUCCESS when
* the rollback completes.
* NOTE: The current state of the child workflow must be SUCCESS in order
* for rollback to be invoked.
*
* @param workflow
* -- the Inner workflow
* @param stepId
* -- assumed to be a stepId of the outer workflow
*/
private void rollbackInnerWorkflow(Workflow workflow, String stepId) {
URI uri = workflow.getWorkflowURI();
_log.info(String.format("Rollback requested workflow: %s", uri));
// Get the workflow state.
String[] message = new String[1];
message[0] = "";
StepState state = Workflow.getOverallState(workflow.getStepStatusMap(), message);
// Update the rollback handlers. We do this in order to be able to fire a completer at the end of the workflow.
Object[] args;
if (workflow._rollbackHandler != null) {
// Nested rollback handler, add our arguments to the end.
// Our rollback handler will call the nested handler.
args = new Object[workflow._rollbackHandlerArgs.length + NestedWorkflowRollbackHandler.NUMBER_OF_ADDED_ARGS];
for (int i = 0; i < workflow._rollbackHandlerArgs.length; i++) {
// copy original arguments
args[i] = workflow._rollbackHandlerArgs[i];
}
// append our new arguments, to the original original rollback handler
args[NestedWorkflowRollbackHandler.indexOfNestedHandler(args)] = workflow._rollbackHandler;
// append stepId for completion
args[NestedWorkflowRollbackHandler.indexOfParentStepId(args)] = stepId;
} else {
// No nested rollback handler.
args = new Object[NestedWorkflowRollbackHandler.NUMBER_OF_ADDED_ARGS];
args[NestedWorkflowRollbackHandler.indexOfNestedHandler(args)] = null;
args[NestedWorkflowRollbackHandler.indexOfParentStepId(args)] = stepId;
}
workflow._rollbackHandler = new NestedWorkflowRollbackHandler();
workflow._rollbackHandlerArgs = args;
// Determine if the workflow already attempted a rollback.
// If so, attempt to restart the rollback's error and cancelled steps.
boolean rollBackCompleted = determineIfRollbackCompleted(workflow);
if (rollBackCompleted) {
_log.info(String.format("Rollback already completed workflow %s", workflow.getWorkflowURI()));
WorkflowStepCompleter.stepSucceded(stepId);
return;
}
// See if can restart the previous rollback.
InterProcessLock workflowLock = null;
try {
workflowLock = lockWorkflow(workflow);
boolean rollBackStarted = resumePreviousRollback(workflow);
if (rollBackStarted) {
_log.info(String.format("Previous rollback resumed; errored/cancelled rollback steps queued; workflow %s", workflow.getWorkflowURI()));
} else {
// Otherwise, attempt to initiate a new rollback.
if (workflow._rollbackHandler != null) {
workflow._rollbackHandler.initiatingRollback(workflow, workflow._rollbackHandlerArgs);
}
rollBackStarted = initiateRollback(workflow);
if (rollBackStarted) {
_log.info(String.format("New rollback initiated workflow %s", workflow.getWorkflowURI()));
}
}
if (rollBackStarted) {
// Return now, wait until the rollback completions fire the completer.
persistWorkflow(workflow);
logWorkflow(workflow, true);
WorkflowStepCompleter.stepExecuting(stepId);
} else {
ServiceCoded coded = WorkflowException.exceptions.workflowRollbackNotInitiated(uri.toString());
WorkflowStepCompleter.stepFailed(stepId, coded);
}
} finally {
unlockWorkflow(workflow, workflowLock);
}
}
use of com.emc.storageos.svcs.errorhandling.model.ServiceCoded in project coprhd-controller by CoprHD.
the class WorkflowTest method sub.
/**
* Workflow step to optionally create a sub-workflow.
*
* @param level
* - current workflow level
* @param maxLevels
* - maximum number of workflow levels
* @param error
* - generate error if requested.
* @param stepId
*/
public void sub(int level, int maxLevels, int stepIndex, String stepId) {
WorkflowStepCompleter.stepExecuting(stepId);
if (sleepMillis > 0) {
try {
Thread.sleep(sleepMillis);
} catch (Exception ex) {
// no action
}
}
if (hasInjectedFailure(level, stepIndex)) {
log.info("Injecting failure in step: " + genMsg(level, stepIndex, "sub"));
ServiceCoded coded = WorkflowException.errors.unforeseen();
WorkflowStepCompleter.stepFailed(stepId, coded);
return;
}
if (++level >= maxLevels) {
WorkflowStepCompleter.stepSucceded(stepId);
} else {
String workflowMapping = "generate3StepWF:" + stepId + ":" + level;
if (workflowsKickedOff.contains(workflowMapping)) {
printLog("Idempotent check: already created/executed workflow from this step, not creating another one: " + workflowMapping);
} else {
// Generate a sub-workflow. The completer will complete this step.
printLog("Generating a new 3 step WF");
generate3StepWF(level, maxLevels, stepId);
workflowsKickedOff.add(workflowMapping);
}
}
}
use of com.emc.storageos.svcs.errorhandling.model.ServiceCoded in project coprhd-controller by CoprHD.
the class AbstractVdcTaskOp method handle.
public void handle() {
ServiceCoded coded = null;
try {
process();
success();
} catch (GeoException e) {
coded = ServiceError.buildServiceError(e.getServiceCode(), e.getMessage());
fail(coded);
throw e;
} catch (Exception e) {
log.error("Vdc task failed e=", e);
String err = "An unexpected error happens:" + e;
coded = ServiceError.buildServiceError(ServiceCode.GEOSVC_INTERNAL_ERROR, err);
fail(coded);
throw e;
}
}
use of com.emc.storageos.svcs.errorhandling.model.ServiceCoded in project coprhd-controller by CoprHD.
the class BlockSnapshotSessionManager method createSnapshotSession.
/**
* Implements a request to create a new block snapshot session.
*
* @param snapSessionSourceObjList The URI of the snapshot session source object.
* @param param A reference to the create session information.
* @param fcManager A reference to a full copy manager.
*
* @return TaskList A TaskList
*/
public TaskList createSnapshotSession(List<BlockObject> snapSessionSourceObjList, SnapshotSessionCreateParam param, BlockFullCopyManager fcManager) {
Collection<URI> sourceURIs = transform(snapSessionSourceObjList, fctnDataObjectToID());
s_logger.info("START create snapshot session for sources {}", Joiner.on(',').join(sourceURIs));
// Get the snapshot session label.
String snapSessionLabel = TimeUtils.formatDateForCurrent(param.getName());
// Get the target device information, if any.
int newLinkedTargetsCount = 0;
String newTargetsName = null;
String newTargetsCopyMode = BlockSnapshot.CopyMode.nocopy.name();
SnapshotSessionNewTargetsParam linkedTargetsParam = param.getNewLinkedTargets();
if (linkedTargetsParam != null) {
newLinkedTargetsCount = linkedTargetsParam.getCount().intValue();
newTargetsName = TimeUtils.formatDateForCurrent(linkedTargetsParam.getTargetName());
newTargetsCopyMode = linkedTargetsParam.getCopyMode();
}
BlockObject sourceObj = snapSessionSourceObjList.get(0);
// Get the project for the snapshot session source object.
Project project = BlockSnapshotSessionUtils.querySnapshotSessionSourceProject(sourceObj, _dbClient);
// Get the platform specific block snapshot session implementation.
BlockSnapshotSessionApi snapSessionApiImpl = determinePlatformSpecificImplForSource(sourceObj);
// Validate the create snapshot session request.
snapSessionApiImpl.validateSnapshotSessionCreateRequest(sourceObj, snapSessionSourceObjList, project, snapSessionLabel, newLinkedTargetsCount, newTargetsName, newTargetsCopyMode, false, fcManager);
// Create a unique task identifier.
String taskId = UUID.randomUUID().toString();
boolean inApplication = false;
if (sourceObj instanceof Volume && ((Volume) sourceObj).getApplication(_dbClient) != null) {
inApplication = true;
} else if (sourceObj instanceof BlockSnapshot) {
BlockSnapshot sourceSnap = (BlockSnapshot) sourceObj;
NamedURI namedUri = sourceSnap.getParent();
if (!NullColumnValueGetter.isNullNamedURI(namedUri)) {
Volume source = _dbClient.queryObject(Volume.class, namedUri.getURI());
if (source != null && source.getApplication(_dbClient) != null) {
inApplication = true;
}
}
}
// Prepare the ViPR BlockSnapshotSession instances and BlockSnapshot
// instances for any new targets to be created and linked to the
// snapshot sessions.
List<Map<URI, BlockSnapshot>> snapSessionSnapshots = new ArrayList<>();
BlockSnapshotSession snapSession = snapSessionApiImpl.prepareSnapshotSession(snapSessionSourceObjList, snapSessionLabel, newLinkedTargetsCount, newTargetsName, snapSessionSnapshots, taskId, inApplication);
// Populate the preparedObjects list and create tasks for each snapshot session.
TaskList response = new TaskList();
Operation snapSessionOp = _dbClient.createTaskOpStatus(BlockSnapshotSession.class, snapSession.getId(), taskId, getCreateResourceOperationTypeEnum(snapSession));
snapSession.getOpStatus().put(taskId, snapSessionOp);
response.getTaskList().add(toTask(snapSession, taskId, snapSessionOp));
if (snapSession.hasConsistencyGroup()) {
addConsistencyGroupTasks(snapSessionSourceObjList, response, taskId, getCreateResourceOperationTypeEnum(snapSession));
} else {
for (BlockObject sourceForTask : snapSessionSourceObjList) {
@SuppressWarnings("unchecked") Operation op = _dbClient.createTaskOpStatus(URIUtil.getModelClass(sourceForTask.getId()), sourceForTask.getId(), taskId, ResourceOperationTypeEnum.CREATE_SNAPSHOT_SESSION);
response.getTaskList().add(toTask(sourceForTask, taskId, op));
}
}
List<DataObject> preparedObjects = new ArrayList<>();
List<List<URI>> snapSessionSnapshotURIs = new ArrayList<>();
for (Map<URI, BlockSnapshot> snapshotMap : snapSessionSnapshots) {
// Set Copy Mode
for (Entry<URI, BlockSnapshot> entry : snapshotMap.entrySet()) {
entry.getValue().setCopyMode(newTargetsCopyMode);
}
preparedObjects.addAll(snapshotMap.values());
Set<URI> uris = snapshotMap.keySet();
snapSessionSnapshotURIs.add(Lists.newArrayList(uris));
}
// persist copyMode changes
_dbClient.updateObject(preparedObjects);
preparedObjects.add(snapSession);
// Create the snapshot sessions.
try {
snapSessionApiImpl.createSnapshotSession(sourceObj, snapSession.getId(), snapSessionSnapshotURIs, newTargetsCopyMode, taskId);
} catch (Exception e) {
String errorMsg = format("Failed to create snapshot sessions for source %s: %s", sourceObj.getId(), e.getMessage());
ServiceCoded sc = null;
if (e instanceof ServiceCoded) {
sc = (ServiceCoded) e;
} else {
sc = APIException.internalServerErrors.genericApisvcError(errorMsg, e);
}
cleanupFailure(response.getTaskList(), preparedObjects, errorMsg, taskId, sc);
throw e;
}
// Record a message in the audit log.
auditOp(OperationTypeEnum.CREATE_SNAPSHOT_SESSION, true, AuditLogManager.AUDITOP_BEGIN, snapSessionLabel, sourceObj.getId().toString(), sourceObj.getStorageController().toString());
s_logger.info("FINISH create snapshot session for source {}", sourceObj.getId());
return response;
}
use of com.emc.storageos.svcs.errorhandling.model.ServiceCoded in project coprhd-controller by CoprHD.
the class BlockSnapshotSessionManager method deleteSnapshotSession.
/**
* Delete the snapshot session with the passed URI.
*
* @param snapSessionURI The URI of the BlockSnapshotSession instance.
* @param deleteType The deletion type i.e, VIPR_ONLY or FULL
*
* @return TaskResourceRep representing the snapshot session task.
*/
public TaskList deleteSnapshotSession(URI snapSessionURI, String deleteType) {
s_logger.info("START delete snapshot session {} of type {}", snapSessionURI, deleteType);
// Get the snapshot session.
BlockSnapshotSession snapSession = BlockSnapshotSessionUtils.querySnapshotSession(snapSessionURI, _uriInfo, _dbClient, true);
BlockObject snapSessionSourceObj = null;
List<BlockObject> snapSessionSourceObjs = getAllSnapshotSessionSources(snapSession);
snapSessionSourceObj = snapSessionSourceObjs.get(0);
// Get the project for the snapshot session source object.
Project project = BlockSnapshotSessionUtils.querySnapshotSessionSourceProject(snapSessionSourceObj, _dbClient);
BlockSnapshotSessionApi snapSessionApiImpl = determinePlatformSpecificImplForSource(snapSessionSourceObj);
// Validate that the snapshot session can be deleted.
snapSessionApiImpl.validateDeleteSnapshotSession(snapSession, snapSessionSourceObj, project);
// Create the task identifier.
String taskId = UUID.randomUUID().toString();
TaskList taskList = new TaskList();
Operation snapSessionOp = new Operation();
snapSessionOp.setResourceType(getDeleteResourceOperationTypeEnum(snapSession));
_dbClient.createTaskOpStatus(BlockSnapshotSession.class, snapSession.getId(), taskId, snapSessionOp);
snapSession.getOpStatus().put(taskId, snapSessionOp);
taskList.addTask(toTask(snapSession, taskId, snapSessionOp));
if (snapSession.hasConsistencyGroup() && NullColumnValueGetter.isNotNullValue(snapSession.getReplicationGroupInstance())) {
addConsistencyGroupTasks(snapSessionSourceObjs, taskList, taskId, getDeleteResourceOperationTypeEnum(snapSession));
}
// Delete the snapshot session.
try {
snapSessionApiImpl.deleteSnapshotSession(snapSession, snapSessionSourceObj, taskId, deleteType);
} catch (Exception e) {
String errorMsg = format("Failed to delete snapshot session %s: %s", snapSessionURI, e.getMessage());
ServiceCoded sc = null;
if (e instanceof ServiceCoded) {
sc = (ServiceCoded) e;
} else {
sc = APIException.internalServerErrors.genericApisvcError(errorMsg, e);
}
cleanupFailure(taskList.getTaskList(), new ArrayList<DataObject>(), errorMsg, taskId, sc);
throw e;
}
// Create the audit log entry.
String opStage = VolumeDeleteTypeEnum.VIPR_ONLY.name().equals(deleteType) ? null : AuditLogManager.AUDITOP_BEGIN;
auditOp(OperationTypeEnum.DELETE_SNAPSHOT_SESSION, true, opStage, snapSessionURI.toString(), snapSessionURI.toString(), snapSessionSourceObj.getStorageController().toString());
s_logger.info("FINISH delete snapshot session {}", snapSessionURI);
return taskList;
}
Aggregations