use of com.emc.storageos.svcs.errorhandling.model.ServiceCoded in project coprhd-controller by CoprHD.
the class WorkflowTest method deepfirstnop.
public void deepfirstnop(int level, int step, String stepId) {
WorkflowStepCompleter.stepExecuting(stepId);
if (sleepMillis > 0) {
try {
Thread.sleep(sleepMillis);
} catch (Exception ex) {
// no action
}
}
if (hasInjectedFailure(level, step)) {
log.info("Injecting failure in step: " + genMsg(level, step, "deepfirstnop"));
ServiceCoded coded = WorkflowException.errors.unforeseen();
WorkflowStepCompleter.stepFailed(stepId, coded);
} else {
WorkflowStepCompleter.stepSucceded(stepId);
}
}
use of com.emc.storageos.svcs.errorhandling.model.ServiceCoded in project coprhd-controller by CoprHD.
the class SRDFOperations method rollbackSRDFMirror.
private void rollbackSRDFMirror(StorageSystem system, final Volume source, final Volume target, boolean isGrouprollback, boolean isVpoolChange, final SRDFMirrorRollbackCompleter completer) {
log.info("START Rolling back SRDF mirror");
try {
/*
* In order to help the user with any potential cleanup, use this anonymous task completer to update the
* rollback completer on whether or not a detach was successful for this source/target pair.
*/
TaskCompleter inspect = new TaskCompleter() {
@Override
protected void complete(DbClient dbClient, Operation.Status status, ServiceCoded coded) throws DeviceControllerException {
completer.addRollbackStatus(source, target, status, coded);
}
};
performDetach(system, target, isGrouprollback, inspect);
if (target.hasConsistencyGroup()) {
log.info("Removing Volume from device Group on roll back");
removeDeviceGroups(system, source.getId(), target.getId(), isVpoolChange, null);
}
} catch (Exception e) {
String msg = format(FAILURE_MSG_FMT, "rollback", source.getId(), target.getId());
log.warn(msg, e);
// Re-throw in order to cleanup any CG and RDFG.
throw e;
}
}
use of com.emc.storageos.svcs.errorhandling.model.ServiceCoded in project coprhd-controller by CoprHD.
the class SmisCommandHelper method waitForAsyncSmisJob.
private void waitForAsyncSmisJob(StorageSystem storageDevice, CIMObjectPath cimJobPath, SmisJob job) throws SmisException {
if (job == null) {
TaskCompleter taskCompleter = new TaskCompleter() {
@Override
public void ready(DbClient dbClient) throws DeviceControllerException {
}
@Override
public void error(DbClient dbClient, ServiceCoded serviceCoded) throws DeviceControllerException {
}
@Override
protected void complete(DbClient dbClient, Operation.Status status, ServiceCoded coded) throws DeviceControllerException {
}
};
job = new SmisJob(cimJobPath, storageDevice.getId(), taskCompleter, "");
} else {
job.setCimJob(cimJobPath);
}
JobContext jobContext = new JobContext(_dbClient, _cimConnection, null, null, null, null, this);
long startTime = System.currentTimeMillis();
int sync_wrapper_time_out = InvokeTestFailure.internalOnlyOverrideSyncWrapperTimeOut(SYNC_WRAPPER_TIME_OUT);
while (true) {
JobPollResult result = job.poll(jobContext, SYNC_WRAPPER_WAIT);
if (!result.isJobInTerminalState()) {
if (System.currentTimeMillis() - startTime > sync_wrapper_time_out) {
throw new SmisException("Timed out waiting on smis job to complete after " + (System.currentTimeMillis() - startTime) + " milliseconds");
} else {
try {
Thread.sleep(SYNC_WRAPPER_WAIT);
} catch (InterruptedException e) {
_log.error("Thread waiting for smis job to complete was interrupted and " + "will be resumed");
}
}
} else {
if (result.isJobInTerminalFailedState()) {
throw new SmisException("Smis job failed: " + result.getErrorDescription());
}
break;
}
}
}
use of com.emc.storageos.svcs.errorhandling.model.ServiceCoded in project coprhd-controller by CoprHD.
the class VPlexDeviceController method portRebalance.
@Override
public void portRebalance(URI vplex, URI exportGroupURI, URI varray, URI exportMaskURI, Map<URI, List<URI>> adjustedPaths, Map<URI, List<URI>> removedPaths, boolean isAdd, String stepId) throws Exception {
// Retrieve the ExportGroup and ExportMask and validate
ExportGroup exportGroup = _dbClient.queryObject(ExportGroup.class, exportGroupURI);
ExportMask exportMask = _dbClient.queryObject(ExportMask.class, exportMaskURI);
if (exportGroup == null || exportMask == null || exportGroup.getInactive() || exportMask.getInactive() || !exportGroup.hasMask(exportMaskURI)) {
String reason = String.format("Bad exportGroup %s or exportMask %s", exportGroupURI, exportMaskURI);
_log.error(reason);
ServiceCoded coded = WorkflowException.exceptions.workflowConstructionError(reason);
WorkflowStepCompleter.stepFailed(stepId, coded);
return;
}
// Check if the ExportMask is in the desired varray (in cross-coupled ExportGroups)
if (!ExportMaskUtils.exportMaskInVarray(_dbClient, exportMask, varray)) {
_log.info(String.format("ExportMask %s (%s) not in specified varray %s", exportMask.getMaskName(), exportMask.getId(), varray));
WorkflowStepCompleter.stepSucceeded(stepId, String.format("No operation done: Mask not in specified varray %s", varray));
return;
}
// Refresh the ExportMask so we have the latest data.
StorageSystem vplexSystem = getDataObject(StorageSystem.class, vplex, _dbClient);
VPlexApiClient client = getVPlexAPIClient(_vplexApiFactory, vplex, _dbClient);
String vplexClusterName = VPlexUtil.getVplexClusterName(exportMask, vplex, client, _dbClient);
VPlexStorageViewInfo storageView = client.getStorageView(vplexClusterName, exportMask.getMaskName());
_log.info("Processing and Refreshing ExportMask {}", exportMask.getMaskName());
Map<String, String> targetPortToPwwnMap = VPlexControllerUtils.getTargetPortToPwwnMap(client, vplexClusterName);
VPlexControllerUtils.refreshExportMask(_dbClient, storageView, exportMask, targetPortToPwwnMap, _networkDeviceController);
// Determine hosts in ExportMask
Set<URI> hostsInExportMask = new HashSet<URI>();
Set<String> hostNames = ExportMaskUtils.getHostNamesInMask(exportMask, _dbClient);
Set<Initiator> initiatorsInMask = ExportMaskUtils.getInitiatorsForExportMask(_dbClient, exportMask, null);
for (Initiator initiator : initiatorsInMask) {
if (initiator.getHost() != null) {
hostsInExportMask.add(initiator.getHost());
}
}
boolean sharedMask = (hostsInExportMask.size() > 1);
if (isAdd) {
// Processing added paths only
Workflow workflow = _workflowService.getNewWorkflow(this, "portRebalance", false, stepId);
// Determine initiators and targets to be added.
// These are initiators not in mask that are in a host in the mask.
// Earlier versions of the Vplex code may not have had all the initiators in the mask, as
// earlier code only put initiators in the Storage View for which ports were added.
// Targets to be added may be on existing initiators or newly added initiators.
List<URI> initiatorsToAdd = new ArrayList<URI>();
List<URI> targetsToAdd = new ArrayList<URI>();
for (URI initiatorURI : adjustedPaths.keySet()) {
if (!exportMask.hasInitiator(initiatorURI.toString())) {
// Initiator not in ExportMask
Initiator initiator = _dbClient.queryObject(Initiator.class, initiatorURI);
if (initiator != null && !initiator.getInactive()) {
if (hostsInExportMask.contains(initiator.getHost())) {
initiatorsToAdd.add(initiatorURI);
for (URI targetURI : adjustedPaths.get(initiatorURI)) {
if (!exportMask.hasTargets(Arrays.asList(targetURI)) && !targetsToAdd.contains(targetURI)) {
targetsToAdd.add(targetURI);
}
}
}
}
} else {
// Initiator already in ExportMask, look for additional targets
for (URI targetURI : adjustedPaths.get(initiatorURI)) {
if (!exportMask.hasTargets(Arrays.asList(targetURI)) && !targetsToAdd.contains(targetURI)) {
targetsToAdd.add(targetURI);
}
}
}
}
_log.info("Targets to add: " + targetsToAdd.toString());
_log.info("Initiators to add: " + initiatorsToAdd.toString());
// Invoke either storageViewAddInitiators if there are initiators to be added (it will add targets also),
// or storageViewAddStoragePorts if no initiators to be added (which adds only targets).
Workflow.Method addPathsMethod = null;
if (!initiatorsToAdd.isEmpty() || !targetsToAdd.isEmpty()) {
String addInitiatorStepId = workflow.createStepId();
ExportMaskAddInitiatorCompleter completer = new ExportMaskAddInitiatorCompleter(exportGroupURI, exportMaskURI, initiatorsToAdd, targetsToAdd, addInitiatorStepId);
;
if (!initiatorsToAdd.isEmpty()) {
addPathsMethod = storageViewAddInitiatorsMethod(vplex, exportGroupURI, exportMaskURI, initiatorsToAdd, targetsToAdd, sharedMask, completer);
} else if (!targetsToAdd.isEmpty()) {
addPathsMethod = storageViewAddStoragePortsMethod(vplex, exportGroupURI, exportMaskURI, targetsToAdd, completer);
}
String description = String.format("Adding paths to ExportMask %s Hosts %s", exportMask.getMaskName(), hostNames.toString());
workflow.createStep("addPaths", description, null, vplex, vplexSystem.getSystemType(), this.getClass(), addPathsMethod, null, false, addInitiatorStepId);
ExportMaskAddPathsCompleter workflowCompleter = new ExportMaskAddPathsCompleter(exportGroupURI, exportMaskURI, stepId);
workflow.executePlan(workflowCompleter, description + " completed successfully");
return;
}
} else {
// Processing the paths to be removed only, Paths not in the removedPaths map will be retained.
// Note that we only remove ports (targets), never initiators.
Workflow workflow = _workflowService.getNewWorkflow(this, "portRebalance", false, stepId);
// Compute the targets to be removed.
Set<URI> targetsToBeRemoved = ExportMaskUtils.getAllPortsInZoneMap(removedPaths);
Collection<URI> targetsInMask = Collections2.transform(exportMask.getStoragePorts(), CommonTransformerFunctions.FCTN_STRING_TO_URI);
targetsToBeRemoved.retainAll(targetsInMask);
Set<URI> targetsToBeRetained = ExportMaskUtils.getAllPortsInZoneMap(adjustedPaths);
targetsToBeRemoved.removeAll(targetsToBeRetained);
List<URI> portsToBeRemoved = new ArrayList<URI>(targetsToBeRemoved);
_log.info("Targets to be removed: " + portsToBeRemoved.toString());
// Call storageViewRemoveStoragePorts to remove any necessary targets.
Workflow.Method removePathsMethod = null;
if (!portsToBeRemoved.isEmpty()) {
String removeInitiatorStepId = workflow.createStepId();
removePathsMethod = storageViewRemoveStoragePortsMethod(vplex, exportGroupURI, exportMaskURI, portsToBeRemoved, null);
String description = String.format("Removing paths to ExportMask %s Hosts %s", exportMask.getMaskName(), hostNames.toString());
workflow.createStep("removePaths", description, null, vplex, vplexSystem.getSystemType(), this.getClass(), removePathsMethod, null, false, removeInitiatorStepId);
ExportMaskRemovePathsCompleter workflowCompleter = new ExportMaskRemovePathsCompleter(exportGroupURI, exportMaskURI, stepId);
workflowCompleter.setRemovedStoragePorts(portsToBeRemoved);
workflow.executePlan(workflowCompleter, description + " completed successfully");
return;
}
}
// Apparently nothing to do, return success
WorkflowStepCompleter.stepSucceeded(stepId, "No operation performed on VPLEX mask");
}
use of com.emc.storageos.svcs.errorhandling.model.ServiceCoded in project coprhd-controller by CoprHD.
the class VPlexDeviceController method resyncFullCopy.
/**
* {@inheritDoc}
*/
@Override
public void resyncFullCopy(URI vplexURI, List<URI> fullCopyURIs, String opId) throws InternalException {
TaskCompleter completer = null;
try {
completer = new CloneResyncCompleter(fullCopyURIs, opId);
// Generate the Workflow.
Workflow workflow = _workflowService.getNewWorkflow(this, RESYNC_FULL_COPY_WF_NAME, false, opId);
_log.info("Created resync full copy workflow with operation id {}", opId);
// add CG to taskCompleter
Volume firstFullCopy = getDataObject(Volume.class, fullCopyURIs.get(0), _dbClient);
BlockObject firstSource = BlockObject.fetch(_dbClient, firstFullCopy.getAssociatedSourceVolume());
if (!NullColumnValueGetter.isNullURI(firstSource.getConsistencyGroup())) {
completer.addConsistencyGroupId(firstSource.getConsistencyGroup());
}
// Get the VPLEX and backend full copy volumes.
URI nativeSystemURI = null;
Map<URI, Volume> vplexFullCopyMap = new HashMap<URI, Volume>();
Map<URI, Volume> nativeFullCopyMap = new HashMap<URI, Volume>();
for (URI fullCopyURI : fullCopyURIs) {
Volume fullCopyVolume = getDataObject(Volume.class, fullCopyURI, _dbClient);
vplexFullCopyMap.put(fullCopyURI, fullCopyVolume);
Volume nativeFullCopyVolume = VPlexUtil.getVPLEXBackendVolume(fullCopyVolume, true, _dbClient);
nativeFullCopyMap.put(nativeFullCopyVolume.getId(), nativeFullCopyVolume);
if (nativeSystemURI == null) {
nativeSystemURI = nativeFullCopyVolume.getStorageController();
}
}
// Get the native system.
StorageSystem nativeSystem = getDataObject(StorageSystem.class, nativeSystemURI, _dbClient);
// We'll need a list of the native full copy URIs.
List<URI> nativeFullCopyURIs = new ArrayList<URI>(nativeFullCopyMap.keySet());
// Maps Vplex volume that needs to be flushed to underlying array volume
Map<Volume, Volume> vplexToArrayVolumesToFlush = new HashMap<Volume, Volume>();
for (Volume vplexFullCopyVolume : vplexFullCopyMap.values()) {
Volume arrayVolumeToBeResynced = VPlexUtil.getVPLEXBackendVolume(vplexFullCopyVolume, true, _dbClient);
vplexToArrayVolumesToFlush.put(vplexFullCopyVolume, arrayVolumeToBeResynced);
}
Map<URI, String> vplexVolumeIdToDetachStep = new HashMap<URI, String>();
// Generate pre restore steps
String waitFor = addPreRestoreResyncSteps(workflow, vplexToArrayVolumesToFlush, vplexVolumeIdToDetachStep, null);
// Now create a workflow step to natively resynchronize the
// backend full copy volumes. We execute this after the
// invalidate cache steps.
createWorkflowStepForResyncNativeFullCopy(workflow, nativeSystem, nativeFullCopyURIs, waitFor, rollbackMethodNullMethod());
// Generate post restore steps
waitFor = addPostRestoreResyncSteps(workflow, vplexToArrayVolumesToFlush, vplexVolumeIdToDetachStep, waitFor);
// Execute the workflow.
_log.info("Executing workflow plan");
String successMsg = String.format("Resynchronize full copy volumes %s completed successfully", fullCopyURIs);
FullCopyOperationCompleteCallback wfCompleteCB = new FullCopyOperationCompleteCallback();
workflow.executePlan(completer, successMsg, wfCompleteCB, new Object[] { fullCopyURIs }, null, null);
_log.info("Workflow plan executing");
} catch (Exception e) {
String failMsg = String.format("Resynchronize full copy volumes %s failed", fullCopyURIs);
_log.error(failMsg, e);
ServiceCoded sc = VPlexApiException.exceptions.resyncFullCopyFailed(fullCopyURIs.toString(), e);
failStep(completer, opId, sc);
}
}
Aggregations