Search in sources :

Example 1 with ProtectionExportController

use of com.emc.storageos.protectioncontroller.ProtectionExportController in project coprhd-controller by CoprHD.

the class ExportWorkflowUtils method generateExportGroupUpdateWorkflow.

/**
 * Creates the workflow for one export mask (storage system) for an update export
 * group call. It creates a single step in the main workflow that wraps a workflow
 * with necessary steps to:
 * <ol>
 * <li>add block objects (volumes/snapshots)</li>
 * <li>remove volumes</li>
 * <li>add initiators</li>
 * <li>remove initiators</li>
 * </ol>
 * The steps are created based on the diff between the current and the requested for
 * the storage system export mask
 *
 * @param workflow the main workflow
 * @param wfGroupId the workflow group Id, if any
 * @param waitFor the id of a step on which this workflow has to wait, if any
 * @param exportGroupUri the export group being updated
 * @param exportMask the export mask for the storage system
 * @param addedBlockObjects the map of block objects to be added
 * @param removedBlockObjects the map of block objects to be removed
 * @param addedInitiators the new list of initiators to be added
 * @param removedInitiators the new list of initiators to be removed
 * @param blockStorageControllerUri the block storage controller. This will always
 *            be used for adding/removing initiators as we
 *            do not want a protection controller doing this.
 * @param workFlowList holds workflow and sub workflow instances to release all locks during failure
 * @param storageUri the storage controller used to perform the export update.
 *            This can be either a block storage controller or protection
 *            controller.
 * @return the id of the wrapper step that was added to main workflow
 * @throws IOException
 * @throws WorkflowException
 * @throws WorkflowRestartedException
 */
public String generateExportGroupUpdateWorkflow(Workflow workflow, String wfGroupId, String waitFor, URI exportGroupUri, ExportMask exportMask, Map<URI, Integer> addedBlockObjects, Map<URI, Integer> removedBlockObjects, List<URI> addedInitiators, List<URI> removedInitiators, URI blockStorageControllerUri, List<Workflow> workflowList) throws IOException, WorkflowException, WorkflowRestartedException {
    // Filter the addedInitiators for non VPLEX system by the Export Group varray.
    ExportGroup exportGroup = _dbClient.queryObject(ExportGroup.class, exportGroupUri);
    addedInitiators = ExportUtils.filterNonVplexInitiatorsByExportGroupVarray(exportGroup, addedInitiators, blockStorageControllerUri, _dbClient);
    if (allCollectionsAreEmpty(addedBlockObjects, removedBlockObjects, addedInitiators, removedInitiators)) {
        _log.info(String.format("There is no export updated required for %s", blockStorageControllerUri.toString()));
        return null;
    }
    // We would rather the task be the child stepID of the parent workflow's stepID.
    // This helps us to preserve parent/child relationships.
    String exportGroupUpdateStepId = workflow.createStepId();
    Workflow storageWorkflow = newWorkflow("storageSystemExportGroupUpdate", false, exportGroupUpdateStepId);
    workflowList.add(storageWorkflow);
    DiscoveredSystemObject storageSystem = getStorageSystem(_dbClient, blockStorageControllerUri);
    String stepId = null;
    // We willLock the host/storage system duples necessary for the workflows.
    // There are two possibilities about locking. Here we just generate the lockKeys.
    List<URI> lockedInitiatorURIs = new ArrayList<URI>();
    lockedInitiatorURIs.addAll(addedInitiators);
    lockedInitiatorURIs.addAll(StringSetUtil.stringSetToUriList(exportGroup.getInitiators()));
    List<String> lockKeys = ControllerLockingUtil.getHostStorageLockKeys(_dbClient, ExportGroup.ExportGroupType.valueOf(exportGroup.getType()), lockedInitiatorURIs, blockStorageControllerUri);
    // are getting replaced.
    if (addedInitiators != null && !addedInitiators.isEmpty()) {
        stepId = generateExportGroupAddInitiators(storageWorkflow, null, stepId, exportGroupUri, blockStorageControllerUri, addedInitiators);
    }
    if (removedInitiators != null && !removedInitiators.isEmpty()) {
        stepId = generateExportGroupRemoveInitiators(storageWorkflow, null, stepId, exportGroupUri, blockStorageControllerUri, removedInitiators);
    }
    // ends being a problem, we would need to tackle this issue
    if (removedBlockObjects != null && !removedBlockObjects.isEmpty()) {
        Map<URI, Integer> objectsToRemove = new HashMap<URI, Integer>(removedBlockObjects);
        ProtectionExportController protectionExportController = getProtectionExportController();
        stepId = protectionExportController.addStepsForExportGroupRemoveVolumes(storageWorkflow, null, stepId, exportGroupUri, objectsToRemove, blockStorageControllerUri);
        if (!objectsToRemove.isEmpty()) {
            // Unexport the remaining block objects.
            _log.info(String.format("Generating exportGroupRemoveVolumes step for objects %s associated with storage system [%s]", objectsToRemove, blockStorageControllerUri));
            List<URI> objectsToRemoveList = new ArrayList<URI>(objectsToRemove.keySet());
            stepId = generateExportGroupRemoveVolumes(storageWorkflow, null, stepId, blockStorageControllerUri, exportGroupUri, objectsToRemoveList);
        }
    }
    if (addedBlockObjects != null && !addedBlockObjects.isEmpty()) {
        Map<URI, Integer> objectsToAdd = new HashMap<URI, Integer>(addedBlockObjects);
        ProtectionExportController protectionExportController = getProtectionExportController();
        stepId = protectionExportController.addStepsForExportGroupAddVolumes(storageWorkflow, null, stepId, exportGroupUri, objectsToAdd, blockStorageControllerUri);
        if (!objectsToAdd.isEmpty()) {
            // Export the remaining block objects.
            _log.info(String.format("Generating exportGroupAddVolumes step for objects %s associated with storage system [%s]", objectsToAdd.keySet(), blockStorageControllerUri));
            stepId = generateExportGroupAddVolumes(storageWorkflow, null, stepId, blockStorageControllerUri, exportGroupUri, objectsToAdd);
        }
    }
    boolean addObject = (addedInitiators != null && !addedInitiators.isEmpty()) || (addedBlockObjects != null && !addedBlockObjects.isEmpty());
    if (exportMask == null && addObject) {
        // recreate export mask only for add initiator/volume
        if (addedInitiators == null) {
            addedInitiators = new ArrayList<URI>();
        }
        if (addedInitiators.isEmpty()) {
            addedInitiators.addAll(getInitiators(exportGroup));
        }
        // Add block volumes already in the export group
        if (exportGroup.getVolumes() != null) {
            for (String key : exportGroup.getVolumes().keySet()) {
                BlockObject bobject = BlockObject.fetch(_dbClient, URI.create(key));
                if (bobject.getStorageController().equals(blockStorageControllerUri)) {
                    addedBlockObjects.put(URI.create(key), Integer.valueOf(exportGroup.getVolumes().get(key)));
                }
            }
        }
        // Acquire locks for the parent workflow.
        boolean acquiredLocks = getWorkflowService().acquireWorkflowLocks(workflow, lockKeys, LockTimeoutValue.get(LockType.EXPORT_GROUP_OPS));
        if (!acquiredLocks) {
            throw DeviceControllerException.exceptions.failedToAcquireLock(lockKeys.toString(), "ExportMaskUpdate: " + exportGroup.getLabel());
        }
        Map<URI, Integer> objectsToAdd = new HashMap<URI, Integer>(addedBlockObjects);
        ProtectionExportController protectionController = getProtectionExportController();
        waitFor = protectionController.addStepsForExportGroupCreate(workflow, wfGroupId, waitFor, exportGroupUri, objectsToAdd, blockStorageControllerUri, addedInitiators);
        if (!objectsToAdd.isEmpty()) {
            // There are no export BlockObjects tied to the current storage system that have an associated protection
            // system. We can just create a step to call the block controller directly for export group create.
            _log.info(String.format("Generating exportGroupCreate steps for objects %s associated with storage system [%s]", objectsToAdd, blockStorageControllerUri));
            // Add the new block objects to the existing ones and send all down
            waitFor = generateExportGroupCreateWorkflow(workflow, wfGroupId, waitFor, blockStorageControllerUri, exportGroupUri, addedBlockObjects, addedInitiators);
        }
        return waitFor;
    }
    try {
        // Acquire locks for the storageWorkflow which is started just below.
        boolean acquiredLocks = getWorkflowService().acquireWorkflowLocks(storageWorkflow, lockKeys, LockTimeoutValue.get(LockType.EXPORT_GROUP_OPS));
        if (!acquiredLocks) {
            throw DeviceControllerException.exceptions.failedToAcquireLock(lockKeys.toString(), "ExportMaskUpdate: " + exportMask.getMaskName());
        }
        // There will not be a rollback step for the overall update instead
        // the code allows the user to retry update as needed.
        Workflow.Method method = ExportWorkflowEntryPoints.exportGroupUpdateMethod(blockStorageControllerUri, exportGroupUri, storageWorkflow);
        return newWorkflowStep(workflow, wfGroupId, String.format("Updating export (%s) on storage array %s", exportGroupUri, storageSystem.getNativeGuid()), storageSystem, method, null, waitFor, exportGroupUpdateStepId);
    } catch (Exception ex) {
        getWorkflowService().releaseAllWorkflowLocks(storageWorkflow);
        throw ex;
    }
}
Also used : HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) ProtectionExportController(com.emc.storageos.protectioncontroller.ProtectionExportController) Workflow(com.emc.storageos.workflow.Workflow) URI(java.net.URI) URISyntaxException(java.net.URISyntaxException) WorkflowException(com.emc.storageos.workflow.WorkflowException) WorkflowRestartedException(com.emc.storageos.workflow.WorkflowRestartedException) ControllerException(com.emc.storageos.volumecontroller.ControllerException) DeviceControllerException(com.emc.storageos.exceptions.DeviceControllerException) IOException(java.io.IOException) ExportGroup(com.emc.storageos.db.client.model.ExportGroup) DiscoveredSystemObject(com.emc.storageos.db.client.model.DiscoveredSystemObject) BlockObject(com.emc.storageos.db.client.model.BlockObject)

Example 2 with ProtectionExportController

use of com.emc.storageos.protectioncontroller.ProtectionExportController in project coprhd-controller by CoprHD.

the class BlockDeviceExportController method exportGroupCreate.

/**
 * Export one or more volumes. The volumeToExports parameter has
 * all the information required to do the add volumes operation.
 *
 * @param export URI of ExportMask
 * @param volumeMap Volume-lun map to be part of the export mask
 * @param initiatorURIs List of URIs for the initiators to be added to the export mask
 * @param opId Operation ID
 * @throws com.emc.storageos.volumecontroller.ControllerException
 */
@Override
public void exportGroupCreate(URI export, Map<URI, Integer> volumeMap, List<URI> initiatorURIs, String opId) throws ControllerException {
    ExportTaskCompleter taskCompleter = new ExportCreateCompleter(export, volumeMap, opId);
    Workflow workflow = null;
    try {
        // Do some initial sanitizing of the export parameters
        StringSetUtil.removeDuplicates(initiatorURIs);
        workflow = _wfUtils.newWorkflow("exportGroupCreate", false, opId);
        ExportGroup exportGroup = _dbClient.queryObject(ExportGroup.class, export);
        Map<URI, Map<URI, Integer>> storageToVolumes = getStorageToVolumeMap(volumeMap);
        for (Map.Entry<URI, Map<URI, Integer>> entry : storageToVolumes.entrySet()) {
            List<String> lockKeys = ControllerLockingUtil.getHostStorageLockKeys(_dbClient, ExportGroup.ExportGroupType.valueOf(exportGroup.getType()), initiatorURIs, entry.getKey());
            boolean acquiredLocks = _wfUtils.getWorkflowService().acquireWorkflowLocks(workflow, lockKeys, LockTimeoutValue.get(LockType.EXPORT_GROUP_OPS));
            if (!acquiredLocks) {
                throw DeviceControllerException.exceptions.failedToAcquireLock(lockKeys.toString(), "ExportGroupCreate: " + exportGroup.getLabel());
            }
            // Initialize the Map of objects to export with all objects.
            Map<URI, Integer> objectsToAdd = new HashMap<URI, Integer>(entry.getValue());
            String waitFor = null;
            ProtectionExportController protectionController = getProtectionExportController();
            waitFor = protectionController.addStepsForExportGroupCreate(workflow, null, waitFor, export, objectsToAdd, entry.getKey(), initiatorURIs);
            if (!objectsToAdd.isEmpty()) {
                // There are no export BlockObjects tied to the current storage system that have an associated protection
                // system. We can just create a step to call the block controller directly for export group create.
                _log.info(String.format("Generating exportGroupCreates steps for objects %s associated with storage system [%s]", objectsToAdd, entry.getKey()));
                _wfUtils.generateExportGroupCreateWorkflow(workflow, null, waitFor, entry.getKey(), export, objectsToAdd, initiatorURIs);
            }
        }
        workflow.executePlan(taskCompleter, "Exported to all devices successfully.");
    } catch (Exception ex) {
        String message = "exportGroupCreate caught an exception.";
        _log.error(message, ex);
        _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) HashMap(java.util.HashMap) ProtectionExportController(com.emc.storageos.protectioncontroller.ProtectionExportController) 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) ExportCreateCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportCreateCompleter) Map(java.util.Map) HashMap(java.util.HashMap) StringSetMap(com.emc.storageos.db.client.model.StringSetMap)

Aggregations

ExportGroup (com.emc.storageos.db.client.model.ExportGroup)2 DeviceControllerException (com.emc.storageos.exceptions.DeviceControllerException)2 ProtectionExportController (com.emc.storageos.protectioncontroller.ProtectionExportController)2 ControllerException (com.emc.storageos.volumecontroller.ControllerException)2 Workflow (com.emc.storageos.workflow.Workflow)2 IOException (java.io.IOException)2 URI (java.net.URI)2 HashMap (java.util.HashMap)2 BlockObject (com.emc.storageos.db.client.model.BlockObject)1 DiscoveredSystemObject (com.emc.storageos.db.client.model.DiscoveredSystemObject)1 StringSetMap (com.emc.storageos.db.client.model.StringSetMap)1 LockRetryException (com.emc.storageos.locking.LockRetryException)1 ServiceError (com.emc.storageos.svcs.errorhandling.model.ServiceError)1 ExportCreateCompleter (com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportCreateCompleter)1 ExportTaskCompleter (com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportTaskCompleter)1 WorkflowException (com.emc.storageos.workflow.WorkflowException)1 WorkflowRestartedException (com.emc.storageos.workflow.WorkflowRestartedException)1 URISyntaxException (java.net.URISyntaxException)1 ArrayList (java.util.ArrayList)1 Map (java.util.Map)1