/* * Copyright (c) 2014 EMC Corporation * All Rights Reserved */ package com.emc.storageos.volumecontroller.impl.utils; import java.io.Serializable; import java.util.ArrayList; import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.emc.storageos.volumecontroller.TaskCompleter; import com.emc.storageos.volumecontroller.impl.smis.vmax.VmaxExportOperationContext; import com.emc.storageos.workflow.WorkflowService; /** * This object contains status information about export operations that occur * within a single workflow step. It benefits rollback operations by indicating * exactly what substeps occurred during creation that need to be rolled back. */ public class ExportOperationContext implements Serializable { private static final long serialVersionUID = 3452808872942655033L; private static final Logger _log = LoggerFactory.getLogger(VmaxExportOperationContext.class); List<ExportOperationContextOperation> operations; public ExportOperationContext() { super(); } public class ExportOperationContextOperation implements Serializable { private static final long serialVersionUID = -4135846269841199964L; private String operation; public String getOperation() { return operation; } public void setOperation(String operation) { this.operation = operation; } public List<Object> getArgs() { return args; } public void setArgs(List<Object> args) { this.args = args; } private List<Object> args; @Override public String toString() { return "Operation [operation=" + operation + ", args=" + args + "]"; } } public void insertOperation(String operation, Object... args) { // Order is important, put this at the end of the list. ExportOperationContextOperation op = new ExportOperationContextOperation(); op.setOperation(operation); List<Object> opArgs = new ArrayList<>(); if (args != null) { for (Object arg : args) { opArgs.add(arg); } } op.setArgs(opArgs); if (operations == null) { operations = new ArrayList<>(); } operations.add(op); _log.info(String.format("Operation %s has been recorded for the benefit of potential rollback " + "in the event of overall failure. %d operation%s been recorded for overall rollback.", operation, operations.size(), operations.size() == 1 ? " has" : "s have")); } public List<ExportOperationContextOperation> getOperations() { return operations; } public void setOperations(List<ExportOperationContextOperation> operations) { this.operations = operations; } @Override public String toString() { return "ExportOperationContext [operations=" + operations + "]"; } /** * Inserts an operation into the step context so rollback will be done properly. * * @param taskCompleter task completer * @param args arguments needed to perform rollback for this individual operation. */ public static void insertContextOperation(TaskCompleter taskCompleter, String operation, Object... args) { if (taskCompleter != null) { ExportOperationContext context = (ExportOperationContext) WorkflowService.getInstance().loadStepData(taskCompleter.getOpId()); if (context != null) { context.insertOperation(operation, args); WorkflowService.getInstance().storeStepData(taskCompleter.getOpId(), context); } else { _log.warn("Rollback context was not found for op: " + taskCompleter.getOpId()); } } } }