use of com.emc.storageos.svcs.errorhandling.resources.InternalException 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);
}
}
use of com.emc.storageos.svcs.errorhandling.resources.InternalException in project coprhd-controller by CoprHD.
the class VPlexDeviceController method addStepsForChangeVirtualArray.
@Override
public String addStepsForChangeVirtualArray(Workflow workflow, String waitFor, List<VolumeDescriptor> volumes, String taskId) throws InternalException {
try {
URI cgURI = null;
URI currentVarrayURI = null;
URI tgtVarrayURI = null;
URI vplexURI = null;
StorageSystem vplexSystem = null;
List<URI> vplexVolumeURIs = new ArrayList<URI>();
VPlexConsistencyGroupManager cgMgr = null;
// Get all the Virtual Volumes and the new varray URI.
List<VolumeDescriptor> vplexVolumeDescriptors = VolumeDescriptor.filterByType(volumes, new VolumeDescriptor.Type[] { VolumeDescriptor.Type.VPLEX_VIRT_VOLUME }, new VolumeDescriptor.Type[] {});
for (VolumeDescriptor vplexVolumeDescriptor : vplexVolumeDescriptors) {
// Add the URI for the VPLEX volume.
URI vplexVolumeURI = vplexVolumeDescriptor.getVolumeURI();
_log.info("Add steps to change virtual array for volume {}", vplexVolumeURI);
vplexVolumeURIs.add(vplexVolumeURI);
// Set the target virtual array if not already set.
if (tgtVarrayURI == null) {
if ((vplexVolumeDescriptor.getParameters() != null) && (!vplexVolumeDescriptor.getParameters().isEmpty())) {
tgtVarrayURI = (URI) vplexVolumeDescriptor.getParameters().get(VolumeDescriptor.PARAM_VARRAY_CHANGE_NEW_VAARAY_ID);
_log.info("Target virtual array for varray change is {}", tgtVarrayURI);
}
}
// migrated when multiple volumes are passed.
if (vplexURI == null) {
Volume vplexVolume = getDataObject(Volume.class, vplexVolumeURI, _dbClient);
vplexURI = vplexVolume.getStorageController();
vplexSystem = getDataObject(StorageSystem.class, vplexURI, _dbClient);
currentVarrayURI = vplexVolume.getVirtualArray();
cgURI = vplexVolume.getConsistencyGroup();
cgMgr = (VPlexConsistencyGroupManager) getConsistencyGroupManager(vplexVolume);
}
}
// We need to determine if the varray change will migrate the
// volumes to the other cluster of the VPLEX. If so and the
// volumes are in a consistency group, then the volumes must
// first be removed from the consistency group.
String lastStep = waitFor;
boolean volumesRemovedFromCG = false;
if (!NullColumnValueGetter.isNullURI(cgURI)) {
_log.info("Varray change volumes are in CG {}", cgURI);
String currentClusterId = ConnectivityUtil.getVplexClusterForVarray(currentVarrayURI, vplexURI, _dbClient);
String newClusterId = ConnectivityUtil.getVplexClusterForVarray(tgtVarrayURI, vplexURI, _dbClient);
if (!newClusterId.equals(currentClusterId)) {
_log.info("Varray change migrates volumes to cluster {}", newClusterId);
// The volumes are in a consistency group and the
// volumes will change cluster, so the volumes
// must be removed from the CG first.
lastStep = cgMgr.addStepForRemoveVolumesFromCG(workflow, waitFor, vplexSystem, vplexVolumeURIs, cgURI);
volumesRemovedFromCG = true;
}
}
// Create steps to migrate the backend volumes.
String migrateStep = null;
List<URI> localSystemsToRemoveCG = new ArrayList<URI>();
List<VolumeDescriptor> vplexMigrateVolumes = VolumeDescriptor.filterByType(volumes, new VolumeDescriptor.Type[] { VolumeDescriptor.Type.VPLEX_MIGRATE_VOLUME }, new VolumeDescriptor.Type[] {});
for (URI vplexVolumeURI : vplexVolumeURIs) {
_log.info("Adding migration steps for vplex volume {}", vplexVolumeURI);
// A list of the volumes to which the data on the current
// backend volumes will be migrated.
List<URI> newVolumes = new ArrayList<URI>();
// A Map containing a migration for each new backend
// volume
Map<URI, URI> migrationMap = new HashMap<URI, URI>();
// A map that specifies the storage pool in which
// each new volume should be created.
Map<URI, URI> poolVolumeMap = new HashMap<URI, URI>();
for (VolumeDescriptor desc : vplexMigrateVolumes) {
// Skip migration targets that are not for the VPLEX
// volume being processed.
Migration migration = getDataObject(Migration.class, desc.getMigrationId(), _dbClient);
if (!migration.getVolume().equals(vplexVolumeURI)) {
continue;
}
_log.info("Found migration {} for VPLEX volume", migration.getId());
// Set data required to add the migration steps.
newVolumes.add(desc.getVolumeURI());
migrationMap.put(desc.getVolumeURI(), desc.getMigrationId());
poolVolumeMap.put(desc.getVolumeURI(), desc.getPoolURI());
// If the migration is to a different storage system
// we may need to remove the backend CG on the source
// system after the migration completes.
URI migSrcURI = migration.getSource();
Volume migSrc = getDataObject(Volume.class, migSrcURI, _dbClient);
URI migTgtURI = migration.getTarget();
Volume migTgt = getDataObject(Volume.class, migTgtURI, _dbClient);
if ((!migTgt.getStorageController().equals(migSrc.getStorageController())) && (!localSystemsToRemoveCG.contains(migSrc.getStorageController()))) {
_log.info("Will remove CG on local system {} if volume is in a CG.", migSrc.getStorageController());
localSystemsToRemoveCG.add(migSrc.getStorageController());
}
}
// Note that the migrate step here is a step group associated
// with deleting the migration sources after the migrations
// have completed and committed. This means that anything
// that waits on this, will occur after the migrations have
// completed, been committed, and the migration sources deleted.
migrateStep = addStepsForMigrateVolumes(workflow, vplexURI, vplexVolumeURI, newVolumes, migrationMap, poolVolumeMap, null, tgtVarrayURI, false, false, taskId, lastStep);
_log.info("Added migration steps for vplex volume {}", vplexVolumeURI);
}
// Update last step
if (migrateStep != null) {
lastStep = migrateStep;
}
// If the volumes are in a CG, we add the final CG steps.
if (!NullColumnValueGetter.isNullURI(cgURI)) {
BlockConsistencyGroup cg = getDataObject(BlockConsistencyGroup.class, cgURI, _dbClient);
if (volumesRemovedFromCG) {
// If the volumes were removed from the consistency group, the
// varray change was across clusters. First add a step to delete
// the CG on the old cluster and then add steps to create the
// CG on the other cluster and add the volumes. The remove step
// must be executed first otherwise, when we go to create the CG
// on the other cluster, the create CG code will see that the CG
// already exists on the VPLEX system and it will not create it.
String removeStepId = workflow.createStepId();
StringSet systemCGs = cg.getSystemConsistencyGroups().get(vplexURI.toString());
String clusterCGName = systemCGs.iterator().next();
String clusterName = BlockConsistencyGroupUtils.fetchClusterName(clusterCGName);
String cgName = BlockConsistencyGroupUtils.fetchCgName(clusterCGName);
cgMgr.addStepForRemoveVPlexCG(workflow, removeStepId, lastStep, vplexSystem, cgURI, cgName, clusterName, Boolean.FALSE, null);
lastStep = cgMgr.addStepsForCreateConsistencyGroup(workflow, removeStepId, vplexSystem, vplexVolumeURIs, true);
_log.info("Added steps to remove the CG from the source cluster and add to target cluster.");
}
if (cg.checkForType(Types.LOCAL)) {
_log.info("CG {} has local type", cgURI);
// If the backend volumes are being migrated to a new storage system,
// then we need to add a step to delete the local CG.
boolean localCGDeleted = false;
List<URI> localSystemURIs = BlockConsistencyGroupUtils.getLocalSystems(cg, _dbClient);
for (URI localSystemURI : localSystemURIs) {
_log.info("CG exists on local system {}", localSystemURI);
if (localSystemsToRemoveCG.contains(localSystemURI)) {
localCGDeleted = true;
_log.info("Adding step to remove CG on local system{}", localSystemURI);
StorageSystem localSystem = getDataObject(StorageSystem.class, localSystemURI, _dbClient);
Workflow.Method deleteCGMethod = new Workflow.Method("deleteConsistencyGroup", localSystemURI, cgURI, Boolean.FALSE);
workflow.createStep("deleteLocalCG", String.format("Delete consistency group from storage system: %s", localSystemURI), lastStep, localSystemURI, localSystem.getSystemType(), BlockDeviceController.class, deleteCGMethod, null, null);
}
}
if (localCGDeleted) {
lastStep = "deleteLocalCG";
}
}
}
// Return the last step
return lastStep;
} catch (Exception ex) {
throw VPlexApiException.exceptions.addStepsForChangeVirtualPoolFailed(ex);
}
}
use of com.emc.storageos.svcs.errorhandling.resources.InternalException in project coprhd-controller by CoprHD.
the class AbstractMirrorOperations method createSingleVolumeMirror.
@Override
public void createSingleVolumeMirror(StorageSystem storage, URI mirror, Boolean createInactive, TaskCompleter taskCompleter) throws DeviceControllerException {
_log.info("createSingleVolumeMirror operation START");
try {
BlockMirror mirrorObj = _dbClient.queryObject(BlockMirror.class, mirror);
StoragePool targetPool = _dbClient.queryObject(StoragePool.class, mirrorObj.getPool());
Volume source = _dbClient.queryObject(Volume.class, mirrorObj.getSource());
TenantOrg tenant = _dbClient.queryObject(TenantOrg.class, source.getTenant().getURI());
String tenantName = tenant.getLabel();
String targetLabelToUse = _nameGenerator.generate(tenantName, mirrorObj.getLabel(), mirror.toString(), '-', SmisConstants.MAX_VOLUME_NAME_LENGTH);
CIMObjectPath replicationSvcPath = _cimPath.getControllerReplicationSvcPath(storage);
CIMArgument[] inArgs = null;
if (storage.checkIfVmax3()) {
CIMObjectPath volumeGroupPath = _helper.getVolumeGroupPath(storage, storage, source, targetPool);
CIMInstance replicaSettingData = getDefaultReplicationSettingData(storage);
inArgs = _helper.getCreateElementReplicaMirrorInputArguments(storage, source, targetPool, createInactive, targetLabelToUse, volumeGroupPath, replicaSettingData);
} else {
inArgs = _helper.getCreateElementReplicaMirrorInputArguments(storage, source, targetPool, createInactive, targetLabelToUse);
}
CIMArgument[] outArgs = new CIMArgument[5];
_helper.invokeMethod(storage, replicationSvcPath, SmisConstants.CREATE_ELEMENT_REPLICA, inArgs, outArgs);
CIMObjectPath job = _cimPath.getCimObjectPathFromOutputArgs(outArgs, SmisConstants.JOB);
if (job != null) {
ControllerServiceImpl.enqueueJob(new QueueJob(new SmisBlockCreateMirrorJob(job, storage.getId(), !createInactive, taskCompleter)));
// Resynchronizing state applies to the initial copy as well as future
// re-synchronization's.
mirrorObj.setSyncState(SynchronizationState.RESYNCHRONIZING.toString());
_dbClient.persistObject(mirrorObj);
}
} catch (final InternalException e) {
_log.info("Problem making SMI-S call: ", e);
taskCompleter.error(_dbClient, e);
} catch (Exception e) {
_log.info("Problem making SMI-S call: ", e);
ServiceError serviceError = DeviceControllerErrors.smis.unableToCallStorageProvider(e.getMessage());
taskCompleter.error(_dbClient, serviceError);
}
}
use of com.emc.storageos.svcs.errorhandling.resources.InternalException in project coprhd-controller by CoprHD.
the class VdcConfigService method resetBlackListForVdc.
@POST
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Path("/resetblacklist")
public Response resetBlackListForVdc(@QueryParam("vdc_short_id") String vdcShortId) {
try {
log.info("Reset blacklist for {}", vdcShortId);
URI vdcId = VdcUtil.getVdcUrn(vdcShortId);
VirtualDataCenter vdc = dbClient.queryObject(VirtualDataCenter.class, vdcId);
dbClient.removeVdcNodesFromBlacklist(vdc);
return Response.ok().build();
} catch (InternalException ex) {
throw ex;
} catch (Exception ex) {
log.error("Reset blacklist vdc error", ex);
throw GeoException.fatals.reconnectVdcIncompatible();
}
}
use of com.emc.storageos.svcs.errorhandling.resources.InternalException in project coprhd-controller by CoprHD.
the class AbstractAuthenticationFilter method doFilter.
@Override
public void doFilter(final ServletRequest servletRequest, final ServletResponse servletResponse, final FilterChain filterChain) throws IOException, ServletException {
final HttpServletResponse response = (HttpServletResponse) servletResponse;
final HttpServletRequest request = (HttpServletRequest) servletRequest;
AbstractRequestWrapper reqWrapper = null;
try {
reqWrapper = authenticate(servletRequest);
} catch (APIException e) {
_log.debug("unauthorized request: serviceUrl = " + request.getRequestURI(), e);
response.sendError(toHTTPStatus(e), toServiceErrorXml(e));
return;
} catch (final InternalException e) {
response.sendError(toHTTPStatus(e), toServiceErrorXml(e));
return;
}
if (reqWrapper != null) {
// we are done, forward it to resource service
forwardToService(servletRequest, servletResponse, reqWrapper);
} else {
// not mine, forward it on to the next filter
filterChain.doFilter(servletRequest, servletResponse);
}
}
Aggregations