use of com.emc.storageos.db.client.util.NullColumnValueGetter.isNullURI in project coprhd-controller by CoprHD.
the class VolumeGroupService method checkForApplicationPendingTasks.
/**
* Check if the application and its CGs/volumes/snapshots/snapshotSessions have any pending tasks
*
* @param volumeGroup The volume group
* @param dbClient
* @param preventAnyPendingTask If throw error when there is any pending task
*/
private void checkForApplicationPendingTasks(VolumeGroup volumeGroup, DbClient dbClient, boolean preventAnyPendingTask) {
checkForPendingTask(volumeGroup.getId(), dbClient, preventAnyPendingTask);
Set<URI> cgs = new HashSet<URI>();
List<Volume> allVolumes = ControllerUtils.getVolumeGroupVolumes(dbClient, volumeGroup);
for (Volume vol : allVolumes) {
checkForPendingTask(vol.getId(), dbClient, preventAnyPendingTask);
URI cg = vol.getConsistencyGroup();
if (!NullColumnValueGetter.isNullURI(cg)) {
cgs.add(vol.getConsistencyGroup());
}
}
for (URI cg : cgs) {
checkForPendingTask(cg, dbClient, preventAnyPendingTask);
}
// it has a corresponding task in CG. so the above checking on CG should cover the case for clone.
for (Volume volume : allVolumes) {
Volume theVol = volume;
if (volume.isVPlexVolume(dbClient)) {
theVol = VPlexUtil.getVPLEXBackendVolume(volume, true, dbClient);
if (theVol == null || theVol.getInactive()) {
log.warn("Cannot find backend volume for VPLEX volume {}", volume.getLabel());
continue;
}
}
URIQueryResultList snapshotURIs = new URIQueryResultList();
dbClient.queryByConstraint(ContainmentConstraint.Factory.getVolumeSnapshotConstraint(theVol.getId()), snapshotURIs);
Iterator<URI> it = snapshotURIs.iterator();
while (it.hasNext()) {
URI snapURI = it.next();
checkForPendingTask(snapURI, dbClient, preventAnyPendingTask);
}
}
// Get snapshotSessions
List<BlockSnapshotSession> sessions = getVolumeGroupSnapshotSessions(volumeGroup);
for (BlockSnapshotSession session : sessions) {
checkForPendingTask(session.getId(), dbClient, preventAnyPendingTask);
}
}
use of com.emc.storageos.db.client.util.NullColumnValueGetter.isNullURI in project coprhd-controller by CoprHD.
the class VolumeGroupService method verifyReplicaForCopyRequest.
/**
* Verifies that the passed replica URI and ensure that it represents a replica for a volume in volume group represented by
* the passed
* in volume group id.
*
* @param replica
* the replica (Clone/Snapshot/Mirror)
* @param volumeGroupUri
* @return The URI of the replica's source.
*/
private URI verifyReplicaForCopyRequest(BlockObject replica, URI volumeGroupUri) {
URI sourceURI = getSourceIdForFullCopy(replica);
if (NullColumnValueGetter.isNullURI(sourceURI)) {
throw APIException.badRequests.replicaOperationNotAllowedNotAReplica(getReplicaType(replica), replica.getLabel());
}
Volume sourceVol = _dbClient.queryObject(Volume.class, sourceURI);
if (sourceVol != null && !sourceVol.getInactive() && sourceVol.getVolumeGroupIds() != null && sourceVol.getVolumeGroupIds().contains(volumeGroupUri.toString())) {
return sourceURI;
}
throw APIException.badRequests.replicaOperationNotAllowedSourceNotInVolumeGroup(getReplicaType(replica), replica.getLabel());
}
use of com.emc.storageos.db.client.util.NullColumnValueGetter.isNullURI in project coprhd-controller by CoprHD.
the class VolumeGroupService method getClonesBySetName.
/**
* Gets all clones for the given set name and volume group.
*
* @param cloneSetName
* @param volumeGroupId
* @param dbClient
* @return
*/
private List<Volume> getClonesBySetName(String cloneSetName, URI volumeGroupId) {
List<Volume> setClones = new ArrayList<Volume>();
if (cloneSetName != null) {
URIQueryResultList list = new URIQueryResultList();
_dbClient.queryByConstraint(AlternateIdConstraint.Factory.getFullCopiesBySetName(cloneSetName), list);
Iterator<Volume> iter = _dbClient.queryIterativeObjects(Volume.class, list);
while (iter.hasNext()) {
Volume vol = iter.next();
URI sourceId = getSourceIdForFullCopy(vol);
if (!NullColumnValueGetter.isNullURI(sourceId)) {
Volume sourceVol = _dbClient.queryObject(Volume.class, sourceId);
if (sourceVol != null && !sourceVol.getInactive() && sourceVol.getVolumeGroupIds() != null && sourceVol.getVolumeGroupIds().contains(volumeGroupId.toString())) {
setClones.add(vol);
}
}
}
}
return setClones;
}
use of com.emc.storageos.db.client.util.NullColumnValueGetter.isNullURI in project coprhd-controller by CoprHD.
the class BlockService method createVolume.
/**
* The fundamental abstraction in the Block Store is a
* volume. A volume is a unit of block storage capacity that has been
* allocated by a consumer to a project. This API allows the user to
* create one or more volumes. The volumes are created in the same
* storage pool.
*
* NOTE: This is an asynchronous operation.
*
* @prereq none
*
* @param param
* POST data containing the volume creation information.
*
* @brief Create volume
* @return A reference to a BlockTaskList containing a list of
* TaskResourceRep references specifying the task data for the
* volume creation tasks.
* @throws InternalException
*/
@POST
@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public TaskList createVolume(VolumeCreate param) throws InternalException {
ArgValidator.checkFieldNotNull(param, "volume_create");
// CQECC00604134
ArgValidator.checkFieldUriType(param.getProject(), Project.class, "project");
// Get and validate the project.
Project project = _permissionsHelper.getObjectById(param.getProject(), Project.class);
ArgValidator.checkEntity(project, param.getProject(), isIdEmbeddedInURL(param.getProject()));
// Verify the user is authorized.
BlockServiceUtils.verifyUserIsAuthorizedForRequest(project, getUserFromContext(), _permissionsHelper);
// Get and validate the varray
ArgValidator.checkFieldUriType(param.getVarray(), VirtualArray.class, "varray");
VirtualArray varray = BlockServiceUtils.verifyVirtualArrayForRequest(project, param.getVarray(), uriInfo, _permissionsHelper, _dbClient);
ArgValidator.checkEntity(varray, param.getVarray(), isIdEmbeddedInURL(param.getVarray()));
// Get and validate the VirtualPool.
VirtualPool vpool = getVirtualPoolForVolumeCreateRequest(project, param);
VirtualPoolCapabilityValuesWrapper capabilities = new VirtualPoolCapabilityValuesWrapper();
// Get the count indicating the number of volumes to create. If not
// passed
// assume 1. Then get the volume placement recommendations.
Integer volumeCount = 1;
Long volumeSize = 0L;
if (param.getCount() != null) {
if (param.getCount() <= 0) {
throw APIException.badRequests.parameterMustBeGreaterThan("count", 0);
}
if (param.getCount() > MAX_VOLUME_COUNT) {
throw APIException.badRequests.exceedingLimit("count", MAX_VOLUME_COUNT);
}
volumeCount = param.getCount();
capabilities.put(VirtualPoolCapabilityValuesWrapper.RESOURCE_COUNT, volumeCount);
}
if (param.getSize() != null) {
// Validate the requested volume size is greater then 0.
volumeSize = SizeUtil.translateSize(param.getSize());
if (volumeSize <= 0) {
throw APIException.badRequests.parameterMustBeGreaterThan(SIZE, 0);
}
capabilities.put(VirtualPoolCapabilityValuesWrapper.SIZE, volumeSize);
}
if (null != vpool.getThinVolumePreAllocationPercentage() && 0 < vpool.getThinVolumePreAllocationPercentage()) {
capabilities.put(VirtualPoolCapabilityValuesWrapper.THIN_VOLUME_PRE_ALLOCATE_SIZE, VirtualPoolUtil.getThinVolumePreAllocationSize(vpool.getThinVolumePreAllocationPercentage(), volumeSize));
}
if (VirtualPool.ProvisioningType.Thin.toString().equalsIgnoreCase(vpool.getSupportedProvisioningType())) {
capabilities.put(VirtualPoolCapabilityValuesWrapper.THIN_PROVISIONING, Boolean.TRUE);
}
// Does vpool supports dedup
if (null != vpool.getDedupCapable() && vpool.getDedupCapable()) {
capabilities.put(VirtualPoolCapabilityValuesWrapper.DEDUP, Boolean.TRUE);
}
// Validate the port group
URI portGroupURI = param.getPortGroup();
if (!NullColumnValueGetter.isNullURI(portGroupURI)) {
ArgValidator.checkFieldUriType(portGroupURI, StoragePortGroup.class, "portGroup");
StoragePortGroup portGroup = _dbClient.queryObject(StoragePortGroup.class, portGroupURI);
if (portGroup == null || !RegistrationStatus.REGISTERED.name().equalsIgnoreCase(portGroup.getRegistrationStatus())) {
throw APIException.internalServerErrors.invalidObject(portGroupURI.toString());
}
// check if port group's storage system is associated to the requested virtual array
ExportUtils.validatePortGroupWithVirtualArray(portGroup, varray.getId(), _dbClient);
capabilities.put(VirtualPoolCapabilityValuesWrapper.PORT_GROUP, portGroupURI);
}
// Find the implementation that services this vpool and volume request
BlockServiceApi blockServiceImpl = getBlockServiceImpl(vpool, _dbClient);
BlockConsistencyGroup consistencyGroup = null;
final Boolean isMultiVolumeConsistencyOn = vpool.getMultivolumeConsistency() == null ? FALSE : vpool.getMultivolumeConsistency();
/*
* Validate Consistency Group:
* 1. CG should be active in the database
* 2. CG project and Volume project should match
* 3. The storage system that the CG is bonded to is associated to the
* request virtual array
*/
ArrayList<String> requestedTypes = new ArrayList<String>();
final URI actualId = project.getId();
if (param.getConsistencyGroup() != null) {
// Get and validate consistency group
consistencyGroup = queryConsistencyGroup(param.getConsistencyGroup());
// Check that the Volume project and the CG project are the same
final URI expectedId = consistencyGroup.getProject().getURI();
checkProjectsMatch(expectedId, actualId);
// attribute should be true
if (!isMultiVolumeConsistencyOn) {
throw APIException.badRequests.invalidParameterConsistencyGroupProvidedButVirtualPoolHasNoMultiVolumeConsistency(param.getConsistencyGroup(), param.getVpool());
}
// Find all volumes assigned to the group
final List<Volume> activeCGVolumes = blockServiceImpl.getActiveCGVolumes(consistencyGroup);
// Validate that the number of volumes in the group plus the number
// to be added by this request does not exceed the maximum volumes
// in a CG.
int cgMaxVolCount = blockServiceImpl.getMaxVolumesForConsistencyGroup(consistencyGroup);
if ((activeCGVolumes.size() + volumeCount.intValue()) > cgMaxVolCount) {
throw APIException.badRequests.requestedVolumeCountExceedsLimitsForCG(volumeCount.intValue(), cgMaxVolCount, consistencyGroup.getLabel());
}
// Get the requested types for provisioning (RP, VPlex, etc.)
requestedTypes = getRequestedTypes(vpool);
// If the consistency group is not yet created, verify the name is OK.
if (!consistencyGroup.created()) {
blockServiceImpl.validateConsistencyGroupName(consistencyGroup, requestedTypes);
}
// Consistency Group is already a Target, hence cannot be used to create source volume
if (consistencyGroup.srdfTarget()) {
throw APIException.badRequests.consistencyGroupBelongsToTarget(consistencyGroup.getId());
}
if (VirtualPool.vPoolSpecifiesSRDF(vpool) && (consistencyGroup.getLabel().length() > 8 || !isAlphaNumeric(consistencyGroup.getLabel()))) {
throw APIException.badRequests.groupNameCannotExceedEightCharactersoronlyAlphaNumericAllowed();
}
if (!VirtualPool.vPoolSpecifiesSRDF(vpool) && consistencyGroup.checkForType(Types.SRDF)) {
throw APIException.badRequests.nonSRDFVolumeCannotbeAddedToSRDFCG();
}
if (VirtualPool.vPoolSpecifiesSRDF(vpool)) {
List<Volume> nativeVolumesInCG = BlockConsistencyGroupUtils.getActiveNativeVolumesInCG(consistencyGroup, _dbClient);
for (Volume nativeVolume : nativeVolumesInCG) {
// Cannot add volumes if in swapped state. This is a limitation that will eventually be removed.
if (Volume.LinkStatus.SWAPPED.name().equals(nativeVolume.getLinkStatus())) {
throw BadRequestException.badRequests.cannotAddVolumesToSwappedCG(consistencyGroup.getLabel());
}
}
}
// check if CG's storage system is associated to the requested virtual array
validateCGValidWithVirtualArray(consistencyGroup, varray);
// the CG's previously requested types.
if (consistencyGroup.creationInitiated()) {
if (!consistencyGroup.getRequestedTypes().containsAll(requestedTypes)) {
throw APIException.badRequests.consistencyGroupIsNotCompatibleWithRequest(consistencyGroup.getId(), consistencyGroup.getRequestedTypes().toString(), requestedTypes.toString());
}
}
Volume existingRpSourceVolume = null;
// RP consistency group validation
if (VirtualPool.vPoolSpecifiesProtection(vpool)) {
// Check to see if the CG has any RecoverPoint provisioned volumes. This is done by looking at the protectionSet field.
// The protectionSet field won't be set until the volume is provisioned in RP so this check allows concurrent
// requests to go through.
boolean cgHasRpProvisionedVolumes = false;
if (activeCGVolumes != null && !activeCGVolumes.isEmpty()) {
for (Volume vol : activeCGVolumes) {
if (!NullColumnValueGetter.isNullNamedURI(vol.getProtectionSet())) {
_log.info(String.format("Determined that consistency group %s contains RP provisioned volumes.", consistencyGroup.getId()));
cgHasRpProvisionedVolumes = true;
break;
}
}
}
// Ensure the CG is either empty or has been tagged for RP and contains properly provisioned RP volumes.
if (cgHasRpProvisionedVolumes && !consistencyGroup.getTypes().contains(BlockConsistencyGroup.Types.RP.toString())) {
throw APIException.badRequests.consistencyGroupMustBeEmptyOrContainRpVolumes(consistencyGroup.getId());
}
if (!activeCGVolumes.isEmpty()) {
// Find the first existing source volume for source/target varray comparison.
for (Volume cgVolume : activeCGVolumes) {
if (cgVolume.getPersonality() != null && cgVolume.getPersonality().equals(Volume.PersonalityTypes.SOURCE.toString())) {
existingRpSourceVolume = cgVolume;
break;
}
}
if (existingRpSourceVolume != null) {
VirtualPool existingVpool = _dbClient.queryObject(VirtualPool.class, existingRpSourceVolume.getVirtualPool());
VirtualPool requestedVpool = _dbClient.queryObject(VirtualPool.class, param.getVpool());
// The source virtual arrays must much
if (existingVpool.getVirtualArrays().size() != requestedVpool.getVirtualArrays().size() || !existingVpool.getVirtualArrays().containsAll(requestedVpool.getVirtualArrays())) {
// The source virtual arrays are not compatible with the CG
throw APIException.badRequests.vPoolSourceVarraysNotCompatibleForCG(consistencyGroup.getLabel());
}
// MetroPoint volumes in the same CG.
if (VirtualPool.vPoolSpecifiesHighAvailability(existingVpool) && VirtualPool.vPoolSpecifiesHighAvailability(requestedVpool)) {
// that we are not trying to mix MetroPoint volumes with Metro volumes.
if ((!VirtualPool.vPoolSpecifiesMetroPoint(requestedVpool) && VirtualPool.vPoolSpecifiesMetroPoint(existingVpool)) || (VirtualPool.vPoolSpecifiesMetroPoint(requestedVpool) && !VirtualPool.vPoolSpecifiesMetroPoint(existingVpool))) {
throw APIException.badRequests.cannotMixMetroPointAndNonMetroPointVolumes(consistencyGroup.getLabel());
}
}
// Check the target virtual arrays
StringMap existingProtectionVarraySettings = existingVpool.getProtectionVarraySettings();
if (existingProtectionVarraySettings == null) {
// NOTE: This will be supported in the future through Jira CTRL-10129
throw APIException.badRequests.cannotAddVolumesToSwappedCG(consistencyGroup.getLabel());
}
StringMap requestedProtectionVarraySettings = requestedVpool.getProtectionVarraySettings();
if (existingProtectionVarraySettings.size() != requestedProtectionVarraySettings.size()) {
// The target virtual arrays are not compatible with the CG
throw APIException.badRequests.vPoolTargetVarraysNotCompatibleForCG(consistencyGroup.getLabel());
}
for (String targetVarray : requestedProtectionVarraySettings.keySet()) {
if (!existingProtectionVarraySettings.containsKey(targetVarray)) {
// The target virtual arrays are not compatible with the CG
throw APIException.badRequests.vPoolTargetVarraysNotCompatibleForCG(consistencyGroup.getLabel());
}
}
// Ensure the replication mode is logically equivalent
String requestedRpCopyMode = NullColumnValueGetter.isNullValue(requestedVpool.getRpCopyMode()) ? RPCopyMode.ASYNCHRONOUS.name() : requestedVpool.getRpCopyMode();
String existingRpCopyMode = NullColumnValueGetter.isNullValue(existingVpool.getRpCopyMode()) ? RPCopyMode.ASYNCHRONOUS.name() : existingVpool.getRpCopyMode();
if (!requestedRpCopyMode.equalsIgnoreCase(existingRpCopyMode)) {
throw APIException.badRequests.vPoolRPCopyModeNotCompatibleForCG(consistencyGroup.getLabel());
}
}
}
}
// are still attached to their source volumes.
if (!activeCGVolumes.isEmpty()) {
// Pass in an active CG volume for validation. If we are dealing with a RecoverPoint
// consistency group, we need to use an RP source volume. Otherwise we can use any arbitrary
// CG volume.
Volume activeCGVolume = existingRpSourceVolume == null ? activeCGVolumes.get(0) : existingRpSourceVolume;
if (!BlockServiceUtils.checkCGVolumeCanBeAddedOrRemoved(consistencyGroup, activeCGVolume, _dbClient)) {
checkCGForMirrors(consistencyGroup, activeCGVolumes);
checkCGForSnapshots(consistencyGroup);
getFullCopyManager().verifyNewVolumesCanBeCreatedInConsistencyGroup(consistencyGroup, activeCGVolumes);
}
}
capabilities.put(VirtualPoolCapabilityValuesWrapper.BLOCK_CONSISTENCY_GROUP, param.getConsistencyGroup());
} else if (VirtualPool.vPoolSpecifiesProtection(vpool)) {
// protection is specified, a consistency group must be selected.
throw APIException.badRequests.consistencyGroupMissingForRpProtection();
}
// verify quota
long size = volumeCount * SizeUtil.translateSize(param.getSize());
TenantOrg tenant = _dbClient.queryObject(TenantOrg.class, project.getTenantOrg().getURI());
ArgValidator.checkEntity(tenant, project.getTenantOrg().getURI(), false);
CapacityUtils.validateQuotasForProvisioning(_dbClient, vpool, project, tenant, size, "volume");
// set compute param
URI computeURI = param.getComputeResource();
if (!NullColumnValueGetter.isNullURI(computeURI)) {
capabilities.put(VirtualPoolCapabilityValuesWrapper.COMPUTE, computeURI.toString());
}
// COP-14028
// Changing the return of a TaskList to return immediately while the underlying tasks are
// being built up. Steps:
// 1. Create a task object ahead of time and persist it for each requested volume.
// 2. Fire off a thread that does the placement and preparation of the volumes, which will use the pre-created
// task/volume objects during their source volume creations.
// 3. Return to the caller the new Task objects that is in the pending state.
String task = UUID.randomUUID().toString();
TaskList taskList = createVolumeTaskList(param.getSize(), project, varray, vpool, param.getName(), task, volumeCount);
// This is causing exceptions when run in the thread.
auditOp(OperationTypeEnum.CREATE_BLOCK_VOLUME, true, AuditLogManager.AUDITOP_BEGIN, param.getName(), volumeCount, varray.getId().toString(), actualId.toString());
// call thread that does the work.
CreateVolumeSchedulingThread.executeApiTask(this, _asyncTaskService.getExecutorService(), _dbClient, varray, project, vpool, capabilities, taskList, task, consistencyGroup, requestedTypes, param, blockServiceImpl);
_log.info("Kicked off thread to perform placement and scheduling. Returning " + taskList.getTaskList().size() + " tasks");
return taskList;
}
use of com.emc.storageos.db.client.util.NullColumnValueGetter.isNullURI in project coprhd-controller by CoprHD.
the class BlockService method changeVirtualArrayForVolumes.
/**
* Changes the virtual array for the passed volumes to the passed
* target virtual array.
*
* @param volumeURIs
* The URIs of the volumes to move
* @param tgtVarrayURI
* The URI of the target virtual array
*
* @return A TaskList of the tasks associated with each volume being moved.
*
* @throws InternalException,
* APIException
*/
private TaskList changeVirtualArrayForVolumes(List<URI> volumeURIs, URI tgtVarrayURI) throws InternalException, APIException {
// Create the result.
TaskList taskList = new TaskList();
// Create a unique task id.
String taskId = UUID.randomUUID().toString();
// Validate that each of the volumes passed in is eligible
// for the varray change.
VirtualArray tgtVarray = null;
BlockConsistencyGroup cg = null;
BlockServiceApi blockServiceAPI = null;
List<Volume> volumes = new ArrayList<Volume>();
List<Volume> cgVolumes = new ArrayList<Volume>();
boolean foundVolumeNotInCG = false;
for (URI volumeURI : volumeURIs) {
// Get and verify the volume.
ArgValidator.checkFieldUriType(volumeURI, Volume.class, "volume");
Volume volume = queryVolumeResource(volumeURI);
ArgValidator.checkEntity(volume, volumeURI, false);
_log.info("Found volume {}", volumeURI);
// Don't operate on VPLEX backend or RP Journal volumes.
BlockServiceUtils.validateNotAnInternalBlockObject(volume, false);
// Don't operate on ingested volumes.
VolumeIngestionUtil.checkOperationSupportedOnIngestedVolume(volume, ResourceOperationTypeEnum.CHANGE_BLOCK_VOLUME_VARRAY, _dbClient);
// Get and validate the volume's project.
URI projectURI = volume.getProject().getURI();
Project project = _permissionsHelper.getObjectById(projectURI, Project.class);
ArgValidator.checkEntity(project, projectURI, false);
_log.info("Found volume project {}", projectURI);
// Verify the user is authorized for the volume's project.
BlockServiceUtils.verifyUserIsAuthorizedForRequest(project, getUserFromContext(), _permissionsHelper);
_log.info("User is authorized for volume's project");
// Verify the current and requested virtual arrays are not the same.
if (volume.getVirtualArray().equals(tgtVarrayURI)) {
throw APIException.badRequests.currentAndRequestedVArrayAreTheSame();
}
// Get and validate the target virtual array.
if (tgtVarray == null) {
tgtVarray = BlockServiceUtils.verifyVirtualArrayForRequest(project, tgtVarrayURI, uriInfo, _permissionsHelper, _dbClient);
_log.info("Found new VirtualArray {}", tgtVarrayURI);
}
// Make sure that we don't have some pending
// operation against the volume
checkForPendingTasks(Arrays.asList(volume.getTenant().getURI()), Arrays.asList(volume));
// Get the appropriate block service implementation for the
// volume. Note that this same implementation is used to
// execute the change. If it is possible that volumes
// with multiple implementations can be selected for a
// varray change, then we would need a map of the
// implementation to use for a given volume. However,
// currently only VPLEX volumes can be moved, so valid
// volumes for a varray change will always have the same
// implementation.
blockServiceAPI = getBlockServiceImpl(volume);
// Verify that the virtual array change is allowed for the
// requested volume and virtual array.
blockServiceAPI.verifyVarrayChangeSupportedForVolumeAndVarray(volume, tgtVarray);
_log.info("Virtual array change is supported for requested volume and varray");
// All volumes must be a CG or none of the volumes can be
// in a CG. After processing individual volumes, if the
// volumes are in a CG, then we make sure all volumes in the
// CG and only the volumes in the CG are passed.
URI cgURI = volume.getConsistencyGroup();
if ((cg == null) && (!foundVolumeNotInCG)) {
if (!isNullURI(cgURI)) {
cg = _permissionsHelper.getObjectById(cgURI, BlockConsistencyGroup.class);
_log.info("All volumes should be in CG {}:{}", cgURI, cg.getLabel());
cgVolumes.addAll(blockServiceAPI.getActiveCGVolumes(cg));
} else {
_log.info("No volumes should be in CGs");
foundVolumeNotInCG = true;
}
} else if (((cg != null) && (isNullURI(cgURI))) || ((foundVolumeNotInCG) && (!isNullURI(cgURI)))) {
// A volume was in a CG, so all volumes must be in a CG.
if (cg != null) {
// Volumes should all be in the CG and this one is not.
_log.error("Volume {}:{} is not in the CG", volumeURI, volume.getLabel());
} else {
_log.error("Volume {}:{} is in CG {}", new Object[] { volumeURI, volume.getLabel(), cgURI });
}
throw APIException.badRequests.mixedVolumesinCGForVarrayChange();
}
// Add the volume to the list
volumes.add(volume);
}
// all in the same CG and all volumes are passed.
if (cg != null) {
// all volume in CG must have been passed.
_log.info("Verify all volumes in CG {}:{}", cg.getId(), cg.getLabel());
URI storageId = cg.getStorageController();
if (!NullColumnValueGetter.isNullURI(storageId)) {
StorageSystem storage = _dbClient.queryObject(StorageSystem.class, storageId);
if (DiscoveredDataObject.Type.vplex.name().equals(storage.getSystemType())) {
// in the CG.
if (!VPlexUtil.verifyVolumesInCG(volumes, cgVolumes, _dbClient)) {
throw APIException.badRequests.cantChangeVarrayNotAllCGVolumes();
}
} else {
verifyVolumesInCG(volumes, cgVolumes);
}
} else {
verifyVolumesInCG(volumes, cgVolumes);
}
}
// task state to pending.
for (Volume volume : volumes) {
Operation op = _dbClient.createTaskOpStatus(Volume.class, volume.getId(), taskId, ResourceOperationTypeEnum.CHANGE_BLOCK_VOLUME_VARRAY);
TaskResourceRep resourceTask = toTask(volume, taskId, op);
taskList.addTask(resourceTask);
}
// Now execute the varray change for the volumes.
if (cg != null) {
try {
// When the volumes are part of a CG, executed as a single workflow.
blockServiceAPI.changeVirtualArrayForVolumes(volumes, cg, cgVolumes, tgtVarray, taskId);
_log.info("Executed virtual array change for volumes");
} catch (InternalException | APIException e) {
// Fail all the tasks.
String errorMsg = String.format("Volume virtual array change error: %s", e.getMessage());
_log.error(errorMsg);
for (TaskResourceRep resourceTask : taskList.getTaskList()) {
resourceTask.setState(Operation.Status.error.name());
resourceTask.setMessage(errorMsg);
_dbClient.error(Volume.class, resourceTask.getResource().getId(), taskId, e);
}
} catch (Exception e) {
// Fail all the tasks.
String errorMsg = String.format("Volume virtual array change error: %s", e.getMessage());
_log.error(errorMsg);
for (TaskResourceRep resourceTask : taskList.getTaskList()) {
resourceTask.setState(Operation.Status.error.name());
resourceTask.setMessage(errorMsg);
_dbClient.error(Volume.class, resourceTask.getResource().getId(), taskId, InternalServerErrorException.internalServerErrors.unexpectedErrorDuringVarrayChange(e));
}
}
} else {
// When the volumes are not in a CG, then execute as individual workflows.
for (Volume volume : volumes) {
try {
blockServiceAPI.changeVirtualArrayForVolumes(Arrays.asList(volume), cg, cgVolumes, tgtVarray, taskId);
_log.info("Executed virtual array change for volume {}", volume.getId());
} catch (InternalException | APIException e) {
String errorMsg = String.format("Volume virtual array change error: %s", e.getMessage());
_log.error(errorMsg);
for (TaskResourceRep resourceTask : taskList.getTaskList()) {
// Fail the correct task.
if (resourceTask.getResource().getId().equals(volume.getId())) {
resourceTask.setState(Operation.Status.error.name());
resourceTask.setMessage(errorMsg);
_dbClient.error(Volume.class, resourceTask.getResource().getId(), taskId, e);
}
}
} catch (Exception e) {
// Fail all the tasks.
String errorMsg = String.format("Volume virtual array change error: %s", e.getMessage());
_log.error(errorMsg);
for (TaskResourceRep resourceTask : taskList.getTaskList()) {
// Fail the correct task.
if (resourceTask.getResource().getId().equals(volume.getId())) {
resourceTask.setState(Operation.Status.error.name());
resourceTask.setMessage(errorMsg);
_dbClient.error(Volume.class, resourceTask.getResource().getId(), taskId, InternalServerErrorException.internalServerErrors.unexpectedErrorDuringVarrayChange(e));
}
}
}
}
}
return taskList;
}
Aggregations