Search in sources :

Example 26 with VolumeDescriptor

use of com.emc.storageos.blockorchestrationcontroller.VolumeDescriptor in project coprhd-controller by CoprHD.

the class VPlexBlockServiceApiImpl method changeVolumeVirtualPool.

/**
 * {@inheritDoc}
 */
@Override
public TaskList changeVolumeVirtualPool(List<Volume> volumes, VirtualPool vpool, VirtualPoolChangeParam vpoolChangeParam, String taskId) throws InternalException {
    TaskList taskList = new TaskList();
    StringBuffer notSuppReasonBuff = new StringBuffer();
    VirtualPool volumeVirtualPool = _dbClient.queryObject(VirtualPool.class, volumes.get(0).getVirtualPool());
    if (VirtualPoolChangeAnalyzer.isSupportedPathParamsChange(volumes.get(0), volumeVirtualPool, vpool, _dbClient, notSuppReasonBuff) || VirtualPoolChangeAnalyzer.isSupportedAutoTieringPolicyAndLimitsChange(volumes.get(0), volumeVirtualPool, vpool, _dbClient, notSuppReasonBuff)) {
        taskList = createTasksForVolumes(vpool, volumes, taskId);
        checkCommonVpoolUpdates(volumes, vpool, taskId);
        return taskList;
    }
    // Check if any of the volumes passed is a VPLEX volume
    // in a VPLEX CG with corresponding local consistency
    // group(s) for the backend volumes.
    Volume changeVPoolVolume = isVPlexVolumeInCgWithLocalType(volumes);
    if (changeVPoolVolume != null) {
        s_logger.info("Change vpool request has volumes in VPLEX CG with backing local CGs");
        // If any of the volumes is a CG and if this is a data
        // migration of the volumes, then the volumes passed must
        // contain all the volumes in that CG.
        VirtualPool currentVPool = _dbClient.queryObject(VirtualPool.class, changeVPoolVolume.getVirtualPool());
        VirtualPoolChangeOperationEnum vpoolChange = VirtualPoolChangeAnalyzer.getSupportedVPlexVolumeVirtualPoolChangeOperation(changeVPoolVolume, currentVPool, vpool, _dbClient, new StringBuffer());
        if ((vpoolChange != null) && (vpoolChange == VirtualPoolChangeOperationEnum.VPLEX_DATA_MIGRATION)) {
            s_logger.info("Vpool change is a data migration");
            ControllerOperationValuesWrapper operationsWrapper = new ControllerOperationValuesWrapper();
            operationsWrapper.put(ControllerOperationValuesWrapper.MIGRATION_SUSPEND_BEFORE_COMMIT, vpoolChangeParam.getMigrationSuspendBeforeCommit());
            operationsWrapper.put(ControllerOperationValuesWrapper.MIGRATION_SUSPEND_BEFORE_DELETE_SOURCE, vpoolChangeParam.getMigrationSuspendBeforeDeleteSource());
            List<Volume> volumesNotInRG = new ArrayList<Volume>();
            taskList = migrateVolumesInReplicationGroup(volumes, vpool, volumesNotInRG, null, operationsWrapper);
            // Migrate volumes not in Replication Group as single volumes
            if (!volumesNotInRG.isEmpty()) {
                // Get the migration descriptors
                List<VolumeDescriptor> descriptors = new ArrayList<VolumeDescriptor>();
                for (Volume volume : volumesNotInRG) {
                    StorageSystem vplexStorageSystem = _dbClient.queryObject(StorageSystem.class, volume.getStorageController());
                    descriptors.addAll(createChangeVirtualPoolDescriptors(vplexStorageSystem, volume, vpool, taskId, null, null, operationsWrapper, true));
                }
                // Create the tasks
                taskList.getTaskList().addAll(createTasksForVolumes(vpool, volumesNotInRG, taskId).getTaskList());
                // Now we get the Orchestration controller and use it to migrate all the volumes not in a RG.
                orchestrateVPoolChanges(volumesNotInRG, descriptors, taskId);
            }
            return taskList;
        }
    }
    // Otherwise proceed as we normally would performing
    // individual vpool changes for each volume.
    String nextTaskId = taskId;
    for (Volume volume : volumes) {
        taskList.getTaskList().addAll(changeVolumeVirtualPool(volume.getStorageController(), volume, vpool, vpoolChangeParam, nextTaskId).getTaskList());
        // Create a unique task id.
        nextTaskId = UUID.randomUUID().toString();
    }
    return taskList;
}
Also used : VolumeDescriptor(com.emc.storageos.blockorchestrationcontroller.VolumeDescriptor) Volume(com.emc.storageos.db.client.model.Volume) TaskList(com.emc.storageos.model.TaskList) VirtualPoolChangeOperationEnum(com.emc.storageos.model.vpool.VirtualPoolChangeOperationEnum) ArrayList(java.util.ArrayList) VirtualPool(com.emc.storageos.db.client.model.VirtualPool) ControllerOperationValuesWrapper(com.emc.storageos.volumecontroller.impl.utils.ControllerOperationValuesWrapper) StorageSystem(com.emc.storageos.db.client.model.StorageSystem)

Example 27 with VolumeDescriptor

use of com.emc.storageos.blockorchestrationcontroller.VolumeDescriptor in project coprhd-controller by CoprHD.

the class VPlexBlockServiceApiImpl method createVolumeDescriptorsForVarrayChange.

/**
 * Creates the volumes descriptors for a varray change for the passed
 * list of VPLEX volumes.
 *
 * @param volumes The VPLEX volumes being moved
 * @param newVarray The target virtual array
 * @param taskId The task identifier
 *
 * @return A list of volume descriptors
 */
private List<VolumeDescriptor> createVolumeDescriptorsForVarrayChange(List<Volume> volumes, VirtualArray newVarray, String taskId) {
    // The list of descriptors for the virtual array change.
    List<VolumeDescriptor> descriptors = new ArrayList<VolumeDescriptor>();
    // The VPLEX system.
    StorageSystem vplexSystem = _dbClient.queryObject(StorageSystem.class, volumes.get(0).getStorageController());
    // Create a descriptor for each vplex volume.
    for (Volume vplexVolume : volumes) {
        VolumeDescriptor descriptor = new VolumeDescriptor(VolumeDescriptor.Type.VPLEX_VIRT_VOLUME, vplexVolume.getStorageController(), vplexVolume.getId(), null, null);
        Map<String, Object> descrParams = new HashMap<String, Object>();
        descrParams.put(VolumeDescriptor.PARAM_VARRAY_CHANGE_NEW_VAARAY_ID, newVarray.getId());
        descriptor.setParameters(descrParams);
        descriptors.add(descriptor);
        // We'll need to prepare a target volume and create a
        // descriptor for each backend volume being migrated.
        StringSet assocVolumes = vplexVolume.getAssociatedVolumes();
        if (null == assocVolumes) {
            s_logger.warn("VPLEX volume {} has no backend volumes. It was possibly ingested 'Virtual Volume Only'.", vplexVolume.forDisplay());
        } else {
            String assocVolumeId = assocVolumes.iterator().next();
            URI assocVolumeURI = URI.create(assocVolumeId);
            Volume assocVolume = _dbClient.queryObject(Volume.class, assocVolumeURI);
            VirtualPool assocVolumeVPool = _dbClient.queryObject(VirtualPool.class, assocVolume.getVirtualPool());
            descriptors.addAll(createBackendVolumeMigrationDescriptors(vplexSystem, vplexVolume, assocVolume, newVarray, assocVolumeVPool, getVolumeCapacity(assocVolume), taskId, null, false, null));
        }
    }
    return descriptors;
}
Also used : VolumeDescriptor(com.emc.storageos.blockorchestrationcontroller.VolumeDescriptor) Volume(com.emc.storageos.db.client.model.Volume) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) StringSet(com.emc.storageos.db.client.model.StringSet) BlockObject(com.emc.storageos.db.client.model.BlockObject) DiscoveredDataObject(com.emc.storageos.db.client.model.DiscoveredDataObject) DataObject(com.emc.storageos.db.client.model.DataObject) VirtualPool(com.emc.storageos.db.client.model.VirtualPool) FCTN_STRING_TO_URI(com.emc.storageos.db.client.util.CommonTransformerFunctions.FCTN_STRING_TO_URI) NamedURI(com.emc.storageos.db.client.model.NamedURI) URI(java.net.URI) FCTN_VPLEX_MIRROR_TO_URI(com.emc.storageos.db.client.util.CommonTransformerFunctions.FCTN_VPLEX_MIRROR_TO_URI) StorageSystem(com.emc.storageos.db.client.model.StorageSystem)

Example 28 with VolumeDescriptor

use of com.emc.storageos.blockorchestrationcontroller.VolumeDescriptor in project coprhd-controller by CoprHD.

the class VPlexBlockServiceApiImpl method createChangeVirtualPoolDescriptors.

/**
 * Change the VirtualPool for the passed virtual volume on the passed VPlex
 * storage system.
 *
 * @param vplexSystem A reference to the VPlex storage system.
 * @param volume A reference to the virtual volume.
 * @param newVpool The desired VirtualPool.
 * @param taskId The task identifier.
 * @param operationsWrapper a wrapper of various controller options
 * @param allowHighAvailabilityMigrations Flag to allow HA migration descriptors to be created
 * @throws InternalException
 */
protected List<VolumeDescriptor> createChangeVirtualPoolDescriptors(StorageSystem vplexSystem, Volume volume, VirtualPool newVpool, String taskId, List<Recommendation> recommendations, VirtualPoolCapabilityValuesWrapper capabilities, ControllerOperationValuesWrapper operationsWrapper, boolean allowHighAvailabilityMigrations) throws InternalException {
    // Get the varray and current vpool for the virtual volume.
    URI volumeVarrayURI = volume.getVirtualArray();
    VirtualArray volumeVarray = _dbClient.queryObject(VirtualArray.class, volumeVarrayURI);
    URI volumeVpoolURI = volume.getVirtualPool();
    VirtualPool currentVpool = _dbClient.queryObject(VirtualPool.class, volumeVpoolURI);
    s_logger.info(String.format("Creating VPLEX change vpool descriptors for volume [%s](%s) " + "which belongs to: varray [%s](%s) - vpool [%s](%s)", volume.getLabel(), volume.getId(), volumeVarray.getLabel(), volumeVarray.getId(), currentVpool.getLabel(), currentVpool.getId()));
    List<VolumeDescriptor> descriptors = new ArrayList<VolumeDescriptor>();
    // Add the VPLEX Virtual Volume Descriptor for change vpool
    VolumeDescriptor vplexVirtualVolumeDesc = new VolumeDescriptor(VolumeDescriptor.Type.VPLEX_VIRT_VOLUME, volume.getStorageController(), volume.getId(), volume.getPool(), null);
    Map<String, Object> volumeParams = new HashMap<String, Object>();
    volumeParams.put(VolumeDescriptor.PARAM_VPOOL_CHANGE_EXISTING_VOLUME_ID, volume.getId());
    volumeParams.put(VolumeDescriptor.PARAM_VPOOL_CHANGE_NEW_VPOOL_ID, newVpool.getId());
    volumeParams.put(VolumeDescriptor.PARAM_VPOOL_CHANGE_OLD_VPOOL_ID, volume.getVirtualPool());
    if (operationsWrapper != null) {
        if (operationsWrapper.getMigrationSuspendBeforeCommit() != null) {
            volumeParams.put(VolumeDescriptor.PARAM_MIGRATION_SUSPEND_BEFORE_COMMIT, operationsWrapper.getMigrationSuspendBeforeCommit());
        }
        if (operationsWrapper.getMigrationSuspendBeforeDeleteSource() != null) {
            volumeParams.put(VolumeDescriptor.PARAM_MIGRATION_SUSPEND_BEFORE_DELETE_SOURCE, operationsWrapper.getMigrationSuspendBeforeDeleteSource());
        }
    }
    vplexVirtualVolumeDesc.setParameters(volumeParams);
    descriptors.add(vplexVirtualVolumeDesc);
    // nothing about the backend volumes.
    if (VirtualPoolChangeAnalyzer.vpoolChangeRequiresMigration(currentVpool, newVpool)) {
        Volume migSrcVolume = getAssociatedVolumeInVArray(volume, volumeVarrayURI);
        descriptors.addAll(createBackendVolumeMigrationDescriptors(vplexSystem, volume, migSrcVolume, volumeVarray, newVpool, getVolumeCapacity(migSrcVolume != null ? migSrcVolume : volume), taskId, recommendations, false, capabilities));
    }
    if (allowHighAvailabilityMigrations) {
        // Now determine if the backend volume in the HA varray
        // needs to be migrated.
        URI haVarrayURI = VirtualPoolChangeAnalyzer.getHaVarrayURI(currentVpool);
        if (haVarrayURI != null) {
            VirtualArray haVarray = _dbClient.queryObject(VirtualArray.class, haVarrayURI);
            VirtualPool currentHaVpool = VirtualPoolChangeAnalyzer.getHaVpool(currentVpool, _dbClient);
            VirtualPool newHaVpool = VirtualPoolChangeAnalyzer.getNewHaVpool(currentVpool, newVpool, _dbClient);
            if (VirtualPoolChangeAnalyzer.vpoolChangeRequiresMigration(currentHaVpool, newHaVpool)) {
                Volume migSrcVolume = getAssociatedVolumeInVArray(volume, haVarrayURI);
                descriptors.addAll(createBackendVolumeMigrationDescriptors(vplexSystem, volume, migSrcVolume, haVarray, newHaVpool, getVolumeCapacity(migSrcVolume != null ? migSrcVolume : volume), taskId, recommendations, true, capabilities));
            }
        }
    }
    return descriptors;
}
Also used : VirtualArray(com.emc.storageos.db.client.model.VirtualArray) VolumeDescriptor(com.emc.storageos.blockorchestrationcontroller.VolumeDescriptor) HashMap(java.util.HashMap) Volume(com.emc.storageos.db.client.model.Volume) ArrayList(java.util.ArrayList) BlockObject(com.emc.storageos.db.client.model.BlockObject) DiscoveredDataObject(com.emc.storageos.db.client.model.DiscoveredDataObject) DataObject(com.emc.storageos.db.client.model.DataObject) VirtualPool(com.emc.storageos.db.client.model.VirtualPool) FCTN_STRING_TO_URI(com.emc.storageos.db.client.util.CommonTransformerFunctions.FCTN_STRING_TO_URI) NamedURI(com.emc.storageos.db.client.model.NamedURI) URI(java.net.URI) FCTN_VPLEX_MIRROR_TO_URI(com.emc.storageos.db.client.util.CommonTransformerFunctions.FCTN_VPLEX_MIRROR_TO_URI)

Example 29 with VolumeDescriptor

use of com.emc.storageos.blockorchestrationcontroller.VolumeDescriptor in project coprhd-controller by CoprHD.

the class VPlexBlockServiceApiImpl method changeVirtualArrayForVolumes.

/**
 * {@inheritDoc}
 */
@Override
public void changeVirtualArrayForVolumes(List<Volume> volumes, BlockConsistencyGroup cg, List<Volume> cgVolumes, VirtualArray newVirtualArray, String taskId) throws InternalException {
    // if they remove the snapshots, they can perform the varray change.
    for (Volume volume : volumes) {
        List<BlockSnapshot> snapshots = getSnapshots(volume);
        if (!snapshots.isEmpty()) {
            for (BlockSnapshot snapshot : snapshots) {
                if (!snapshot.getInactive()) {
                    throw APIException.badRequests.volumeForVarrayChangeHasSnaps(volume.getId().toString());
                }
            }
        }
        // If the volume has mirrors then varray change will not
        // be allowed. User needs to explicitly delete mirrors first.
        // This is applicable for both Local and Distributed volumes.
        // For distributed volume getMirrors will get mirror if any
        // on source or HA side.
        StringSet mirrorURIs = volume.getMirrors();
        if (mirrorURIs != null && !mirrorURIs.isEmpty()) {
            List<VplexMirror> mirrors = _dbClient.queryObject(VplexMirror.class, StringSetUtil.stringSetToUriList(mirrorURIs));
            if (mirrors != null && !mirrors.isEmpty()) {
                throw APIException.badRequests.volumeForVarrayChangeHasMirrors(volume.getId().toString(), volume.getLabel());
            }
        }
    }
    // vpool change.
    if ((cg != null) && (volumes.size() > _maxCgVolumesForMigration)) {
        throw APIException.badRequests.cgContainsTooManyVolumesForVArrayChange(cg.getLabel(), volumes.size(), _maxCgVolumesForMigration);
    }
    // we don't allow the varray change.
    if ((cg != null) && (cg.checkForType(Types.LOCAL)) && (cgVolumes.size() > 1)) {
        verifyTargetSystemsForCGDataMigration(volumes, null, newVirtualArray.getId());
    }
    // Create the volume descriptors for the virtual array change.
    List<VolumeDescriptor> descriptors = createVolumeDescriptorsForVarrayChange(volumes, newVirtualArray, taskId);
    try {
        // Orchestrate the virtual array change.
        BlockOrchestrationController controller = getController(BlockOrchestrationController.class, BlockOrchestrationController.BLOCK_ORCHESTRATION_DEVICE);
        controller.changeVirtualArray(descriptors, taskId);
        s_logger.info("Successfully invoked block orchestrator.");
    } catch (InternalException e) {
        s_logger.error("Controller error", e);
        for (VolumeDescriptor descriptor : descriptors) {
            // migration targets and migrations.
            if (VolumeDescriptor.Type.VPLEX_MIGRATE_VOLUME.equals(descriptor.getType())) {
                _dbClient.error(Volume.class, descriptor.getVolumeURI(), taskId, e);
                _dbClient.error(Migration.class, descriptor.getMigrationId(), taskId, e);
            }
        }
        throw e;
    }
}
Also used : VolumeDescriptor(com.emc.storageos.blockorchestrationcontroller.VolumeDescriptor) BlockOrchestrationController(com.emc.storageos.blockorchestrationcontroller.BlockOrchestrationController) Volume(com.emc.storageos.db.client.model.Volume) Migration(com.emc.storageos.db.client.model.Migration) BlockSnapshot(com.emc.storageos.db.client.model.BlockSnapshot) StringSet(com.emc.storageos.db.client.model.StringSet) VplexMirror(com.emc.storageos.db.client.model.VplexMirror) InternalException(com.emc.storageos.svcs.errorhandling.resources.InternalException)

Example 30 with VolumeDescriptor

use of com.emc.storageos.blockorchestrationcontroller.VolumeDescriptor in project coprhd-controller by CoprHD.

the class VPlexBlockServiceApiImpl method createVPlexVolumeDescriptors.

/**
 * Create the necessary volume descriptors for Vplex volumes, including the backend
 * volume descriptors and the virtual volume descriptors.
 *
 * @param param
 *            - the VolumeCreate parameters
 * @param project
 *            -- user's project
 * @param vArray
 *            -- virtual array volumes are created in
 * @param vPool
 *            -- virtual pool (ROOT) used to create the volumes
 * @param recommendations
 *            -- recommendations received from placement
 * @param task
 *            -- a task identifier
 * @param vPoolCapabilities
 *            - VirtualPoolCapabilitiesWrapper
 * @param blockConsistencyGroupURI
 *            - the block consistency group URI
 * @param taskList
 *            - OUTPUT list of tasks created
 * @param allVolumes
 *            - OUTPUT - list of volumes created
 * @param createTask
 *            -- boolean flag indicating to create tasks
 * @return
 */
public List<VolumeDescriptor> createVPlexVolumeDescriptors(VolumeCreate param, Project project, final VirtualArray vArray, final VirtualPool vPool, List<Recommendation> recommendations, String task, VirtualPoolCapabilityValuesWrapper vPoolCapabilities, URI blockConsistencyGroupURI, TaskList taskList, List<URI> allVolumes, boolean createTask) {
    s_logger.info("Request to create {} VPlex virtual volume(s)", vPoolCapabilities.getResourceCount());
    // Determine if we're processing an SRDF copy so we can set appropriate name.
    boolean srdfCopy = false;
    if (recommendations.get(0).getRecommendation() != null && recommendations.get(0).getRecommendation() instanceof SRDFCopyRecommendation) {
        srdfCopy = true;
    }
    // Sort the recommendations by VirtualArray. There can be up to two
    // VirtualArrays, the requested VirtualArray and the HA VirtualArray
    // either passed or determined by the placement when HA virtual volumes
    // are being created. We also set the VPlex storage system, which
    // should be the same for all recommendations.
    URI vplexStorageSystemURI = null;
    URI[] vplexSystemURIOut = new URI[1];
    Map<String, List<VPlexRecommendation>> varrayRecommendationsMap = sortRecommendationsByVarray(recommendations, vplexSystemURIOut);
    vplexStorageSystemURI = vplexSystemURIOut[0];
    // for the srdf copies, since they are already pre-created.
    if (!srdfCopy) {
        validateVolumeLabels(param.getName(), project, vPoolCapabilities, varrayRecommendationsMap);
    }
    // Determine the project to be used for the VPlex's artifacts
    StorageSystem vplexStorageSystem = _dbClient.queryObject(StorageSystem.class, vplexStorageSystemURI);
    Project vplexProject = getVplexProject(vplexStorageSystem, _dbClient, _tenantsService);
    // The volume size.
    long size = SizeUtil.translateSize(param.getSize());
    // The consistency group or null when not specified.
    final BlockConsistencyGroup consistencyGroup = blockConsistencyGroupURI == null ? null : _dbClient.queryObject(BlockConsistencyGroup.class, blockConsistencyGroupURI);
    // Find all volumes assigned to the group
    boolean cgContainsVolumes = false;
    if (consistencyGroup != null) {
        final List<Volume> activeCGVolumes = getActiveCGVolumes(consistencyGroup);
        cgContainsVolumes = (activeCGVolumes != null && !activeCGVolumes.isEmpty());
    }
    // If the consistency group is created but does not specify the LOCAL
    // type, the CG must be a CG created prior to 2.2 or an ingested CG. In
    // this case, we don't want a volume creation to result in backend CGs.
    // The only exception is if the CG does not reference any volumes. In
    // this case, if the LOCAL type isn't specified, we can create backend
    // CGs.
    BlockConsistencyGroup backendCG = null;
    if (consistencyGroup != null && (!consistencyGroup.created() || !cgContainsVolumes || consistencyGroup.getTypes().contains(Types.LOCAL.toString()))) {
        backendCG = consistencyGroup;
    }
    // Prepare Bourne volumes to represent the backend volumes for the
    // recommendations in each VirtualArray.
    int varrayCount = 0;
    String volumeLabel = param.getName();
    List<VolumeDescriptor> descriptors = new ArrayList<VolumeDescriptor>();
    URI[][] varrayVolumeURIs = new URI[2][vPoolCapabilities.getResourceCount()];
    Iterator<String> varrayIter = varrayRecommendationsMap.keySet().iterator();
    while (varrayIter.hasNext()) {
        String varrayId = varrayIter.next();
        s_logger.info("Processing backend recommendations for Virtual Array {}", varrayId);
        List<VPlexRecommendation> vplexRecommendations = varrayRecommendationsMap.get(varrayId);
        List<VolumeDescriptor> varrayDescriptors = makeBackendVolumeDescriptors(vplexRecommendations, project, vplexProject, vPool, volumeLabel, varrayCount, size, backendCG, vPoolCapabilities, createTask, task);
        descriptors.addAll(varrayDescriptors);
        List<URI> varrayURIs = VolumeDescriptor.getVolumeURIs(varrayDescriptors);
        allVolumes.addAll(varrayURIs);
        for (int i = 0; i < varrayURIs.size(); i++) {
            varrayVolumeURIs[varrayCount][i] = varrayURIs.get(i);
        }
        varrayCount++;
    }
    // Prepare Bourne volumes to represent the highly available virtual
    // volumes and associate the virtual volumes with their associated
    // backend volumes.
    s_logger.info("Preparing virtual volumes");
    List<URI> virtualVolumeURIs = new ArrayList<URI>();
    URI nullPoolURI = NullColumnValueGetter.getNullURI();
    vPoolCapabilities.put(VirtualPoolCapabilityValuesWrapper.AUTO_TIER__POLICY_NAME, null);
    for (int i = 0; i < vPoolCapabilities.getResourceCount(); i++) {
        // Compute the volume label based on the label of the underlying volume
        String volumeLabelBuilt = null;
        Volume associatedVolume = _dbClient.queryObject(Volume.class, varrayVolumeURIs[0][i]);
        // Get the virtual volume backing replication group instance name, if available.
        String backingReplicationGroupInstance = null;
        if (associatedVolume != null) {
            volumeLabelBuilt = generateLabelFromAssociatedVolume(volumeLabel, associatedVolume);
            backingReplicationGroupInstance = NullColumnValueGetter.isNotNullValue(associatedVolume.getReplicationGroupInstance()) ? associatedVolume.getReplicationGroupInstance() : NullColumnValueGetter.getNullStr();
        } else {
            volumeLabelBuilt = AbstractBlockServiceApiImpl.generateDefaultVolumeLabel(volumeLabel, i, vPoolCapabilities.getResourceCount());
        }
        s_logger.info("Volume label is {}", volumeLabelBuilt);
        Volume volume = StorageScheduler.getPrecreatedVolume(_dbClient, taskList, volumeLabelBuilt);
        boolean volumePrecreated = false;
        if (volume != null) {
            volumePrecreated = true;
        }
        long thinVolumePreAllocationSize = 0;
        if (null != vPool.getThinVolumePreAllocationPercentage()) {
            thinVolumePreAllocationSize = VirtualPoolUtil.getThinVolumePreAllocationSize(vPool.getThinVolumePreAllocationPercentage(), size);
        }
        volume = prepareVolume(VolumeType.VPLEX_VIRTUAL_VOLUME, volume, size, thinVolumePreAllocationSize, project, vArray, vPool, vplexStorageSystemURI, nullPoolURI, volumeLabelBuilt, consistencyGroup, vPoolCapabilities);
        StringSet associatedVolumes = new StringSet();
        associatedVolumes.add(varrayVolumeURIs[0][i].toString());
        s_logger.info("Associating volume {}", varrayVolumeURIs[0][i].toString());
        // associated with the virtual volume.
        if (varrayCount > 1) {
            associatedVolumes.add(varrayVolumeURIs[1][i].toString());
            s_logger.info("Associating volume {}", varrayVolumeURIs[1][i].toString());
        }
        volume.setAssociatedVolumes(associatedVolumes);
        if (null != backingReplicationGroupInstance) {
            s_logger.info("Setting virtual volume backingReplicationGroupInstance to {}", backingReplicationGroupInstance);
            volume.setBackingReplicationGroupInstance(backingReplicationGroupInstance);
        }
        _dbClient.updateObject(volume);
        URI volumeId = volume.getId();
        s_logger.info("Prepared virtual volume {}", volumeId);
        virtualVolumeURIs.add(volumeId);
        allVolumes.add(volumeId);
        if (createTask && !volumePrecreated) {
            Operation op = _dbClient.createTaskOpStatus(Volume.class, volume.getId(), task, ResourceOperationTypeEnum.CREATE_BLOCK_VOLUME);
            TaskResourceRep volumeTask = toTask(volume, task, op);
            taskList.getTaskList().add(volumeTask);
        }
        VolumeDescriptor descriptor = new VolumeDescriptor(VolumeDescriptor.Type.VPLEX_VIRT_VOLUME, vplexStorageSystemURI, volumeId, null, consistencyGroup == null ? null : consistencyGroup.getId(), vPoolCapabilities, volume.getCapacity());
        // Set the compute resource in the descriptor if the volume to be created will be exported
        // to a host/cluster after it has been created so that the compute resource name can be
        // included in the volume name if the custom volume naming is so configured. Do not set the
        // compute resource if the descriptor is for an SRDF target as the target is not exported
        // to the compute resource.
        URI computeResourceURI = param.getComputeResource();
        if ((computeResourceURI != null) && (!srdfCopy)) {
            s_logger.info(String.format("Volume %s - will be exported to Host/Cluster: %s", volume.getLabel(), computeResourceURI.toString()));
            descriptor.setComputeResource(computeResourceURI);
        }
        descriptors.add(descriptor);
    }
    return descriptors;
}
Also used : ArrayList(java.util.ArrayList) Operation(com.emc.storageos.db.client.model.Operation) FCTN_STRING_TO_URI(com.emc.storageos.db.client.util.CommonTransformerFunctions.FCTN_STRING_TO_URI) NamedURI(com.emc.storageos.db.client.model.NamedURI) URI(java.net.URI) FCTN_VPLEX_MIRROR_TO_URI(com.emc.storageos.db.client.util.CommonTransformerFunctions.FCTN_VPLEX_MIRROR_TO_URI) SRDFCopyRecommendation(com.emc.storageos.volumecontroller.SRDFCopyRecommendation) StringSet(com.emc.storageos.db.client.model.StringSet) ApplicationAddVolumeList(com.emc.storageos.volumecontroller.ApplicationAddVolumeList) ArrayList(java.util.ArrayList) TaskList(com.emc.storageos.model.TaskList) VolumeGroupVolumeList(com.emc.storageos.model.application.VolumeGroupUpdateParam.VolumeGroupVolumeList) URIQueryResultList(com.emc.storageos.db.client.constraint.URIQueryResultList) StorageSystemConnectivityList(com.emc.storageos.model.systems.StorageSystemConnectivityList) List(java.util.List) StorageSystem(com.emc.storageos.db.client.model.StorageSystem) VolumeDescriptor(com.emc.storageos.blockorchestrationcontroller.VolumeDescriptor) VPlexRecommendation(com.emc.storageos.volumecontroller.VPlexRecommendation) TaskResourceRep(com.emc.storageos.model.TaskResourceRep) PrefixConstraint(com.emc.storageos.db.client.constraint.PrefixConstraint) AlternateIdConstraint(com.emc.storageos.db.client.constraint.AlternateIdConstraint) ContainmentPrefixConstraint(com.emc.storageos.db.client.constraint.ContainmentPrefixConstraint) ContainmentConstraint(com.emc.storageos.db.client.constraint.ContainmentConstraint) BlockConsistencyGroup(com.emc.storageos.db.client.model.BlockConsistencyGroup) Project(com.emc.storageos.db.client.model.Project) Volume(com.emc.storageos.db.client.model.Volume)

Aggregations

VolumeDescriptor (com.emc.storageos.blockorchestrationcontroller.VolumeDescriptor)117 Volume (com.emc.storageos.db.client.model.Volume)98 URI (java.net.URI)86 NamedURI (com.emc.storageos.db.client.model.NamedURI)77 ArrayList (java.util.ArrayList)77 StorageSystem (com.emc.storageos.db.client.model.StorageSystem)38 HashMap (java.util.HashMap)38 StringSet (com.emc.storageos.db.client.model.StringSet)29 InternalException (com.emc.storageos.svcs.errorhandling.resources.InternalException)27 URIQueryResultList (com.emc.storageos.db.client.constraint.URIQueryResultList)19 FCTN_STRING_TO_URI (com.emc.storageos.db.client.util.CommonTransformerFunctions.FCTN_STRING_TO_URI)18 Workflow (com.emc.storageos.workflow.Workflow)18 ApplicationAddVolumeList (com.emc.storageos.volumecontroller.ApplicationAddVolumeList)17 ControllerException (com.emc.storageos.volumecontroller.ControllerException)17 List (java.util.List)17 BlockOrchestrationController (com.emc.storageos.blockorchestrationcontroller.BlockOrchestrationController)16 VirtualPool (com.emc.storageos.db.client.model.VirtualPool)16 InternalServerErrorException (com.emc.storageos.svcs.errorhandling.resources.InternalServerErrorException)16 URISyntaxException (java.net.URISyntaxException)16 BlockConsistencyGroup (com.emc.storageos.db.client.model.BlockConsistencyGroup)15