Search in sources :

Example 1 with ExportDeleteCompleter

use of com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportDeleteCompleter in project coprhd-controller by CoprHD.

the class VPlexDeviceController method exportGroupDelete.

/*
     * (non-Javadoc)
     *
     * @see com.emc.storageos.volumecontroller.impl.vplex.VplexController#exportGroupDelete(java.net.URI, java.net.URI,
     * java.lang.String)
     */
@Override
public void exportGroupDelete(URI vplex, URI export, String opId) throws ControllerException {
    ExportDeleteCompleter completer = null;
    try {
        _log.info("Entering exportGroupDelete");
        WorkflowStepCompleter.stepExecuting(opId);
        completer = new ExportDeleteCompleter(export, opId);
        StorageSystem vplexSystem = getDataObject(StorageSystem.class, vplex, _dbClient);
        ExportGroup exportGroup = null;
        try {
            exportGroup = getDataObject(ExportGroup.class, export, _dbClient);
        } catch (VPlexApiException ve) {
            // This exception is caught specifically to handle rollback
            // cases. The export group will be marked inactive before this
            // method is called hence it will always throw this exception in
            // rollback scenarios. Hence this exception is caught as storage
            // view will be already deleted due to rollback steps.
            completer.ready(_dbClient);
            return;
        }
        _log.info("Attempting to delete ExportGroup " + exportGroup.getGeneratedName() + " on VPLEX " + vplexSystem.getLabel());
        Workflow workflow = _workflowService.getNewWorkflow(this, "exportGroupDelete", false, opId);
        StringBuffer errorMessages = new StringBuffer();
        boolean isValidationNeeded = validatorConfig.isValidationEnabled() && !ExportUtils.checkIfExportGroupIsRP(exportGroup);
        _log.info("Orchestration level validation needed : {}", isValidationNeeded);
        List<ExportMask> exportMasks = ExportMaskUtils.getExportMasks(_dbClient, exportGroup, vplex);
        if (exportMasks.isEmpty()) {
            throw VPlexApiException.exceptions.exportGroupDeleteFailedNull(vplex.toString());
        }
        // back a failed export group creation.
        if (!exportGroupMasksContainExportGroupVolume(exportGroup, exportMasks)) {
            for (ExportMask exportMask : exportMasks) {
                exportGroup.removeExportMask(exportMask.getId());
            }
            _dbClient.updateObject(exportGroup);
            completer.ready(_dbClient);
            return;
        }
        // Add a steps to remove exports on the VPlex.
        List<URI> exportMaskUris = new ArrayList<URI>();
        List<URI> volumeUris = new ArrayList<URI>();
        String storageViewStepId = null;
        VPlexApiClient client = getVPlexAPIClient(_vplexApiFactory, vplex, _dbClient);
        for (ExportMask exportMask : exportMasks) {
            if (exportMask.getStorageDevice().equals(vplex)) {
                String vplexClusterName = VPlexUtil.getVplexClusterName(exportMask, vplex, client, _dbClient);
                VPlexStorageViewInfo storageView = client.getStorageView(vplexClusterName, exportMask.getMaskName());
                _log.info("Refreshing ExportMask {}", exportMask.getMaskName());
                Map<String, String> targetPortToPwwnMap = VPlexControllerUtils.getTargetPortToPwwnMap(client, vplexClusterName);
                VPlexControllerUtils.refreshExportMask(_dbClient, storageView, exportMask, targetPortToPwwnMap, _networkDeviceController);
                // assemble a list of other ExportGroups that reference this ExportMask
                List<ExportGroup> otherExportGroups = ExportUtils.getOtherExportGroups(exportGroup, exportMask, _dbClient);
                boolean existingVolumes = exportMask.hasAnyExistingVolumes();
                boolean existingInitiators = exportMask.hasAnyExistingInitiators();
                boolean removeVolumes = false;
                List<URI> volumeURIList = new ArrayList<URI>();
                if (!otherExportGroups.isEmpty()) {
                    if (exportGroup.getVolumes() != null) {
                        for (String volUri : exportGroup.getVolumes().keySet()) {
                            volumeURIList.add(URI.create(volUri));
                        }
                    }
                    volumeURIList = getVolumeListDiff(exportGroup, exportMask, otherExportGroups, volumeURIList);
                    if (!volumeURIList.isEmpty()) {
                        removeVolumes = true;
                    }
                } else if (existingVolumes || existingInitiators) {
                    // initiators.
                    if (existingVolumes) {
                        _log.info("Storage view will not be deleted because Export Mask {} has existing volumes: {}", exportMask.getMaskName(), exportMask.getExistingVolumes());
                    }
                    if (existingInitiators) {
                        _log.info("Storage view will not be deleted because Export Mask {} has existing initiators: {}", exportMask.getMaskName(), exportMask.getExistingInitiators());
                    }
                    if (exportMask.getUserAddedVolumes() != null && !exportMask.getUserAddedVolumes().isEmpty()) {
                        StringMap volumes = exportMask.getUserAddedVolumes();
                        if (volumes != null) {
                            for (String vol : volumes.values()) {
                                URI volumeURI = URI.create(vol);
                                volumeURIList.add(volumeURI);
                            }
                        }
                        if (!volumeURIList.isEmpty()) {
                            removeVolumes = true;
                        }
                    }
                } else {
                    _log.info("creating a deleteStorageView workflow step for " + exportMask.getMaskName());
                    String exportMaskDeleteStep = workflow.createStepId();
                    Workflow.Method storageViewExecuteMethod = deleteStorageViewMethod(vplex, exportGroup.getId(), exportMask.getId(), false);
                    storageViewStepId = workflow.createStep(DELETE_STORAGE_VIEW, String.format("Delete VPLEX Storage View %s for ExportGroup %s", exportMask.getMaskName(), export), storageViewStepId, vplexSystem.getId(), vplexSystem.getSystemType(), this.getClass(), storageViewExecuteMethod, null, exportMaskDeleteStep);
                }
                if (removeVolumes) {
                    _log.info("removing volumes: " + volumeURIList);
                    Workflow.Method method = ExportWorkflowEntryPoints.exportRemoveVolumesMethod(vplexSystem.getId(), export, volumeURIList);
                    storageViewStepId = workflow.createStep("removeVolumes", String.format("Removing volumes from export on storage array %s (%s)", vplexSystem.getNativeGuid(), vplexSystem.getId().toString()), storageViewStepId, NullColumnValueGetter.getNullURI(), vplexSystem.getSystemType(), ExportWorkflowEntryPoints.class, method, null, null);
                }
                _log.info("determining which volumes to remove from ExportMask " + exportMask.getMaskName());
                exportMaskUris.add(exportMask.getId());
                for (URI volumeUri : ExportMaskUtils.getVolumeURIs(exportMask)) {
                    if (exportGroup.hasBlockObject(volumeUri)) {
                        volumeUris.add(volumeUri);
                        _log.info("   this ExportGroup volume is a match: " + volumeUri);
                    } else {
                        _log.info("   this ExportGroup volume is not in this export mask, so skipping: " + volumeUri);
                    }
                }
            }
        }
        if (!exportMaskUris.isEmpty()) {
            _log.info("exportGroupDelete export mask URIs: " + exportMaskUris);
            _log.info("exportGroupDelete volume URIs: " + volumeUris);
            String zoningStep = workflow.createStepId();
            List<NetworkZoningParam> zoningParams = NetworkZoningParam.convertExportMasksToNetworkZoningParam(export, exportMaskUris, _dbClient);
            Workflow.Method zoningExecuteMethod = _networkDeviceController.zoneExportMasksDeleteMethod(zoningParams, volumeUris);
            workflow.createStep(ZONING_STEP, String.format("Delete ExportMasks %s for VPlex %s", export, vplex), storageViewStepId, nullURI, "network-system", _networkDeviceController.getClass(), zoningExecuteMethod, null, zoningStep);
        }
        String message = errorMessages.toString();
        if (isValidationNeeded && !message.isEmpty()) {
            _log.error("Error Message {}", errorMessages);
            throw DeviceControllerException.exceptions.deleteExportGroupValidationError(exportGroup.forDisplay(), vplexSystem.forDisplay(), message);
        }
        // Start the workflow
        workflow.executePlan(completer, "Successfully deleted ExportMasks for ExportGroup: " + export);
    } catch (Exception ex) {
        _log.error("Exception deleting ExportGroup: " + ex.getMessage());
        String opName = ResourceOperationTypeEnum.DELETE_EXPORT_GROUP.getName();
        ServiceError serviceError = VPlexApiException.errors.exportGroupDeleteFailed(opName, ex);
        failStep(completer, opId, serviceError);
    }
}
Also used : VPlexStorageViewInfo(com.emc.storageos.vplex.api.VPlexStorageViewInfo) StringMap(com.emc.storageos.db.client.model.StringMap) ArrayList(java.util.ArrayList) ExportDeleteCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportDeleteCompleter) NamedURI(com.emc.storageos.db.client.model.NamedURI) URI(java.net.URI) StorageSystem(com.emc.storageos.db.client.model.StorageSystem) ServiceError(com.emc.storageos.svcs.errorhandling.model.ServiceError) ExportMask(com.emc.storageos.db.client.model.ExportMask) ExportWorkflowEntryPoints(com.emc.storageos.volumecontroller.impl.block.ExportWorkflowEntryPoints) Workflow(com.emc.storageos.workflow.Workflow) InternalException(com.emc.storageos.svcs.errorhandling.resources.InternalException) InternalServerErrorException(com.emc.storageos.svcs.errorhandling.resources.InternalServerErrorException) VPlexApiException(com.emc.storageos.vplex.api.VPlexApiException) ControllerException(com.emc.storageos.volumecontroller.ControllerException) IOException(java.io.IOException) URISyntaxException(java.net.URISyntaxException) WorkflowException(com.emc.storageos.workflow.WorkflowException) DatabaseException(com.emc.storageos.db.exceptions.DatabaseException) DeviceControllerException(com.emc.storageos.exceptions.DeviceControllerException) NetworkZoningParam(com.emc.storageos.networkcontroller.impl.NetworkZoningParam) ExportGroup(com.emc.storageos.db.client.model.ExportGroup) VPlexApiException(com.emc.storageos.vplex.api.VPlexApiException) VPlexApiClient(com.emc.storageos.vplex.api.VPlexApiClient)

Example 2 with ExportDeleteCompleter

use of com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportDeleteCompleter in project coprhd-controller by CoprHD.

the class ComputeSystemControllerImpl method deleteExportGroup.

public void deleteExportGroup(URI exportGroup, String stepId) {
    try {
        BlockExportController blockController = getController(BlockExportController.class, BlockExportController.EXPORT);
        _dbClient.createTaskOpStatus(ExportGroup.class, exportGroup, stepId, ResourceOperationTypeEnum.DELETE_EXPORT_GROUP);
        // Test mechanism to invoke a failure. No-op on production systems.
        InvokeTestFailure.internalOnlyInvokeTestFailure(InvokeTestFailure.ARTIFICIAL_FAILURE_027);
        blockController.exportGroupDelete(exportGroup, stepId);
        // Test mechanism to invoke a failure. No-op on production systems.
        InvokeTestFailure.internalOnlyInvokeTestFailure(InvokeTestFailure.ARTIFICIAL_FAILURE_028);
    } catch (Exception ex) {
        _log.error("Exception occured while deleting export group {}", exportGroup, ex);
        // Clean up any pending tasks
        ExportTaskCompleter taskCompleter = new ExportDeleteCompleter(exportGroup, false, stepId);
        ServiceError serviceError = DeviceControllerException.errors.jobFailed(ex);
        taskCompleter.error(_dbClient, serviceError);
        // Fail the step
        WorkflowStepCompleter.stepFailed(stepId, DeviceControllerException.errors.jobFailed(ex));
    }
}
Also used : ServiceError(com.emc.storageos.svcs.errorhandling.model.ServiceError) BlockExportController(com.emc.storageos.volumecontroller.BlockExportController) ExportTaskCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportTaskCompleter) ExportDeleteCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportDeleteCompleter) InternalException(com.emc.storageos.svcs.errorhandling.resources.InternalException) ControllerException(com.emc.storageos.volumecontroller.ControllerException) ComputeSystemControllerException(com.emc.storageos.computesystemcontroller.exceptions.ComputeSystemControllerException) APIException(com.emc.storageos.svcs.errorhandling.resources.APIException) WorkflowException(com.emc.storageos.workflow.WorkflowException) DeviceControllerException(com.emc.storageos.exceptions.DeviceControllerException) RemoteException(java.rmi.RemoteException) CoordinatorException(com.emc.storageos.coordinator.exceptions.CoordinatorException) ClientControllerException(com.emc.storageos.exceptions.ClientControllerException)

Example 3 with ExportDeleteCompleter

use of com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportDeleteCompleter in project coprhd-controller by CoprHD.

the class BlockStorageDeviceTest method testExportGroupDeletion.

@Test
public void testExportGroupDeletion() {
    ExportGroup exportGroup = getExportGroup();
    ExportMask exportMask = getExportMask();
    String token = UUID.randomUUID().toString() + UUID.randomUUID().toString();
    ExportTaskCompleter taskCompleter = new ExportDeleteCompleter(exportGroup.getId(), false, token);
    _deviceController.doExportDelete(_storageSystem, exportMask, null, null, taskCompleter);
}
Also used : ExportGroup(com.emc.storageos.db.client.model.ExportGroup) ExportTaskCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportTaskCompleter) ExportMask(com.emc.storageos.db.client.model.ExportMask) ExportDeleteCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportDeleteCompleter) Test(org.junit.Test)

Example 4 with ExportDeleteCompleter

use of com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportDeleteCompleter in project coprhd-controller by CoprHD.

the class BlockDeviceExportController method exportGroupDelete.

/**
 * Delete the export.
 *
 * @param export URI of ExportGroup
 * @param opId Operation ID
 * @throws com.emc.storageos.volumecontroller.ControllerException
 */
@Override
public void exportGroupDelete(URI export, String opId) throws ControllerException {
    ExportTaskCompleter taskCompleter = new ExportDeleteCompleter(export, false, opId);
    Workflow workflow = null;
    try {
        ExportGroup exportGroup = _dbClient.queryObject(ExportGroup.class, export);
        if (exportGroup != null && exportGroup.getExportMasks() != null) {
            workflow = _wfUtils.newWorkflow("exportGroupDelete", false, opId);
            if (NullColumnValueGetter.isNullValue(exportGroup.getType())) {
                // (VPLEX backend groups have a null export group type, for instance)
                throw DeviceControllerException.exceptions.exportGroupDeleteUnsupported(exportGroup.forDisplay());
            }
            Set<URI> storageSystemURIs = new HashSet<URI>();
            // Use temp set to prevent ConcurrentModificationException
            List<ExportMask> tempExportMasks = ExportMaskUtils.getExportMasks(_dbClient, exportGroup);
            for (ExportMask tempExportMask : tempExportMasks) {
                List<String> lockKeys = ControllerLockingUtil.getHostStorageLockKeys(_dbClient, ExportGroup.ExportGroupType.valueOf(exportGroup.getType()), StringSetUtil.stringSetToUriList(exportGroup.getInitiators()), tempExportMask.getStorageDevice());
                boolean acquiredLocks = _wfUtils.getWorkflowService().acquireWorkflowLocks(workflow, lockKeys, LockTimeoutValue.get(LockType.EXPORT_GROUP_OPS));
                if (!acquiredLocks) {
                    throw DeviceControllerException.exceptions.failedToAcquireLock(lockKeys.toString(), "ExportGroupDelete: " + exportGroup.getLabel());
                }
                if (tempExportMask != null && tempExportMask.getVolumes() != null) {
                    List<URI> uriList = getExportRemovableObjects(exportGroup, tempExportMask);
                    Map<URI, List<URI>> storageToVolumes = getStorageToVolumes(uriList);
                    for (URI storageURI : storageToVolumes.keySet()) {
                        if (!storageSystemURIs.contains(storageURI)) {
                            storageSystemURIs.add(storageURI);
                            _wfUtils.generateExportGroupDeleteWorkflow(workflow, null, null, storageURI, export);
                        }
                    }
                } else {
                    exportGroup.removeExportMask(tempExportMask.getId());
                    _dbClient.updateObject(exportGroup);
                }
            }
            workflow.executePlan(taskCompleter, "Removed export from all devices.");
        } else {
            taskCompleter.ready(_dbClient);
        }
    } catch (Exception ex) {
        String message = "exportGroupDelete caught an exception.";
        _log.error(message, ex);
        if (workflow != null) {
            _wfUtils.getWorkflowService().releaseAllWorkflowLocks(workflow);
        }
        ServiceError serviceError = DeviceControllerException.errors.jobFailed(ex);
        taskCompleter.error(_dbClient, serviceError);
    }
}
Also used : ServiceError(com.emc.storageos.svcs.errorhandling.model.ServiceError) ExportTaskCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportTaskCompleter) ExportMask(com.emc.storageos.db.client.model.ExportMask) ExportDeleteCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportDeleteCompleter) Workflow(com.emc.storageos.workflow.Workflow) URI(java.net.URI) DeviceControllerException(com.emc.storageos.exceptions.DeviceControllerException) ControllerException(com.emc.storageos.volumecontroller.ControllerException) IOException(java.io.IOException) LockRetryException(com.emc.storageos.locking.LockRetryException) ExportGroup(com.emc.storageos.db.client.model.ExportGroup) List(java.util.List) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet)

Aggregations

ExportDeleteCompleter (com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportDeleteCompleter)4 ExportGroup (com.emc.storageos.db.client.model.ExportGroup)3 ExportMask (com.emc.storageos.db.client.model.ExportMask)3 DeviceControllerException (com.emc.storageos.exceptions.DeviceControllerException)3 ServiceError (com.emc.storageos.svcs.errorhandling.model.ServiceError)3 ControllerException (com.emc.storageos.volumecontroller.ControllerException)3 ExportTaskCompleter (com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportTaskCompleter)3 InternalException (com.emc.storageos.svcs.errorhandling.resources.InternalException)2 Workflow (com.emc.storageos.workflow.Workflow)2 WorkflowException (com.emc.storageos.workflow.WorkflowException)2 IOException (java.io.IOException)2 URI (java.net.URI)2 ArrayList (java.util.ArrayList)2 ComputeSystemControllerException (com.emc.storageos.computesystemcontroller.exceptions.ComputeSystemControllerException)1 CoordinatorException (com.emc.storageos.coordinator.exceptions.CoordinatorException)1 NamedURI (com.emc.storageos.db.client.model.NamedURI)1 StorageSystem (com.emc.storageos.db.client.model.StorageSystem)1 StringMap (com.emc.storageos.db.client.model.StringMap)1 DatabaseException (com.emc.storageos.db.exceptions.DatabaseException)1 ClientControllerException (com.emc.storageos.exceptions.ClientControllerException)1