use of com.emc.storageos.db.client.model.NamedURI in project coprhd-controller by CoprHD.
the class BlockVplexVolumeIngestOrchestrator method ingestBackendVolumes.
/**
* Ingests the backend volumes and any related replicas.
*
* Calls ingestBlockObjects by getting a nested IngestStrategy
* for each backend volume or replica from the IngestStrategyFactory.
*
* @param backendRequestContext the VplexBackendIngestionContext for the parent virtual volume
*
* @throws IngestionException
*/
private void ingestBackendVolumes(IngestionRequestContext requestContext, VplexVolumeIngestionContext backendRequestContext) throws IngestionException {
while (backendRequestContext.hasNext()) {
UnManagedVolume associatedVolume = backendRequestContext.next();
String sourceClusterId = getClusterNameForVarray(backendRequestContext.getVarray(associatedVolume), requestContext.getStorageSystem());
String haClusterId = getClusterNameForVarray(backendRequestContext.getHaVarray(associatedVolume), requestContext.getStorageSystem());
_logger.info("the source cluster id is {} and the high availability cluster id is {}", sourceClusterId, haClusterId);
backendRequestContext.setHaClusterId(haClusterId);
_logger.info("Ingestion started for vplex backend volume {}", associatedVolume.getNativeGuid());
try {
validateBackendVolumeVpool(associatedVolume, backendRequestContext.getVpool(associatedVolume));
IngestStrategy ingestStrategy = ingestStrategyFactory.buildIngestStrategy(associatedVolume, IngestStrategyFactory.DISREGARD_PROTECTION);
@SuppressWarnings("unchecked") BlockObject blockObject = ingestStrategy.ingestBlockObjects(backendRequestContext, VolumeIngestionUtil.getBlockObjectClass(associatedVolume));
if (null == blockObject) {
// ingestion did not succeed, but in case it wasn't, throw one
throw IngestionException.exceptions.generalVolumeException(associatedVolume.getLabel(), "check the logs for more details");
}
// Note that a VPLEX backend volume could also be a snapshot target volume.
// When this is the case, the local volume ingest strategy is what will be
// retrieved and executed. As a result, the object returned will be a
// Volume instance not a BlockSnapshot instance. However, the local volume
// ingest strategy realizes that the volume may also be a snapshot target
// volume and creates the BlockSnapshot instance to represent the snapshot
// target volume and adds this BlockSnapshot instance to the created objects
// list. Because the BlockSnapshot and Volume instances will have the same
// native GUID, as they represent the same physical volume, we can't
// add the Volume to the created objects list as it would just replace
// the BlockSnapshot instance and only the Volume would get created. So,
// we first move the snapshot to the created snapshots list before adding
// the volume to the created objects list.
Map<String, BlockObject> createdObjectMap = backendRequestContext.getBlockObjectsToBeCreatedMap();
String blockObjectNativeGuid = blockObject.getNativeGuid();
if (createdObjectMap.containsKey(blockObjectNativeGuid)) {
BlockObject createdBlockObject = createdObjectMap.get(blockObjectNativeGuid);
if (createdBlockObject instanceof BlockSnapshot) {
_logger.info("Backend ingestion created block snapshot {}", blockObjectNativeGuid);
// The snapshot will be created with the backend volume project, so we
// need to update that to the frontend project.
((BlockSnapshot) createdBlockObject).setProject(new NamedURI(backendRequestContext.getFrontendProject().getId(), createdBlockObject.getLabel()));
backendRequestContext.getCreatedSnapshotMap().put(blockObjectNativeGuid, (BlockSnapshot) createdBlockObject);
createdObjectMap.put(blockObjectNativeGuid, blockObject);
} else {
// This should not happen. If there is an instance in the created
// objects list with the same guid as the ingested block object
// it must be that the backend volume is also a snapshot target
// volume and the strategy created the BlockSnapshot instance and
// added it to the created objects list.
_logger.warn("Unexpected object in created objects list during backend ingestion {}:{}", blockObjectNativeGuid, createdBlockObject.getLabel());
}
} else {
createdObjectMap.put(blockObjectNativeGuid, blockObject);
}
backendRequestContext.getProcessedUnManagedVolumeMap().put(associatedVolume.getNativeGuid(), backendRequestContext.getVolumeContext());
_logger.info("Ingestion ended for backend volume {}", associatedVolume.getNativeGuid());
} catch (Exception ex) {
_logger.error(ex.getLocalizedMessage());
backendRequestContext.rollback();
throw ex;
}
}
}
use of com.emc.storageos.db.client.model.NamedURI in project coprhd-controller by CoprHD.
the class VplexVolumeIngestionContext method createVplexMirrorObjects.
/**
* Create a VplexMirror database object if a VPLEX native mirror is present.
* This should be called after the parent virtual volume has already been ingested.
*
* @param context the VplexBackendIngestionContext
* @param virtualVolume the ingested virtual volume's Volume object.
*/
private void createVplexMirrorObjects() {
if (!getUnmanagedVplexMirrors().isEmpty()) {
Volume virtualVolume = (Volume) _parentRequestContext.getProcessedBlockObject(getUnmanagedVirtualVolume().getNativeGuid());
_logger.info("creating VplexMirror object for virtual volume " + virtualVolume.getLabel());
for (Entry<UnManagedVolume, String> entry : getUnmanagedVplexMirrors().entrySet()) {
// find mirror and create a VplexMirror object
BlockObject mirror = getBlockObjectsToBeCreatedMap().get(entry.getKey().getNativeGuid().replace(VolumeIngestionUtil.UNMANAGEDVOLUME, VolumeIngestionUtil.VOLUME));
if (null != mirror) {
_logger.info("processing mirror " + mirror.getLabel());
if (mirror instanceof Volume) {
Volume mirrorVolume = (Volume) mirror;
// create VplexMirror set all the basic properties
VplexMirror vplexMirror = new VplexMirror();
vplexMirror.setId(URIUtil.createId(VplexMirror.class));
vplexMirror.setCapacity(mirrorVolume.getCapacity());
vplexMirror.setLabel(mirrorVolume.getLabel());
vplexMirror.setNativeId(entry.getValue());
// For Vplex virtual volumes set allocated capacity to 0 (cop-18608)
vplexMirror.setAllocatedCapacity(0L);
vplexMirror.setProvisionedCapacity(mirrorVolume.getProvisionedCapacity());
vplexMirror.setSource(new NamedURI(virtualVolume.getId(), virtualVolume.getLabel()));
vplexMirror.setStorageController(virtualVolume.getStorageController());
vplexMirror.setTenant(mirrorVolume.getTenant());
vplexMirror.setThinPreAllocationSize(mirrorVolume.getThinVolumePreAllocationSize());
vplexMirror.setThinlyProvisioned(mirrorVolume.getThinlyProvisioned());
vplexMirror.setVirtualArray(mirrorVolume.getVirtualArray());
vplexMirror.setVirtualPool(mirrorVolume.getVirtualPool());
// set the associated volume for this VplexMirror
StringSet associatedVolumes = new StringSet();
associatedVolumes.add(mirrorVolume.getId().toString());
vplexMirror.setAssociatedVolumes(associatedVolumes);
// VplexMirror will have the same project
// as the virtual volume (i.e., the front-end project)
// but the mirror backend will have the backend project
vplexMirror.setProject(new NamedURI(getFrontendProject().getId(), mirrorVolume.getLabel()));
mirrorVolume.setProject(new NamedURI(getBackendProject().getId(), mirrorVolume.getLabel()));
// update flags on mirror volume
Set<DataObject> updatedObjects = getDataObjectsToBeUpdatedMap().get(mirrorVolume.getNativeGuid());
if (updatedObjects == null) {
updatedObjects = new HashSet<DataObject>();
getDataObjectsToBeUpdatedMap().put(mirrorVolume.getNativeGuid(), updatedObjects);
}
VolumeIngestionUtil.clearInternalFlags(this, mirrorVolume, updatedObjects, _dbClient);
// VPLEX backend volumes should still have the INTERNAL_OBJECT flag
mirrorVolume.addInternalFlags(Flag.INTERNAL_OBJECT);
// deviceLabel will be the very last part of the native guid
String[] devicePathParts = entry.getValue().split("/");
String deviceName = devicePathParts[devicePathParts.length - 1];
vplexMirror.setDeviceLabel(deviceName);
// save the new VplexMirror & persist backend & updated objects
getCreatedVplexMirrors().add(vplexMirror);
// set mirrors property on the parent virtual volume
StringSet mirrors = virtualVolume.getMirrors();
if (mirrors == null) {
mirrors = new StringSet();
}
mirrors.add(vplexMirror.getId().toString());
virtualVolume.setMirrors(mirrors);
}
}
}
}
}
use of com.emc.storageos.db.client.model.NamedURI in project coprhd-controller by CoprHD.
the class ConsistencyGroupService method createConsistencyGroup.
/**
* Create Consistency group
*
* @param openstackTenantId openstack tenant id
* @param param pojo class to bind request
* @param isV1Call cinder V1 api
* @param header HTTP header
* @brief Create Consistency group
* @return Response
*/
@POST
@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public Response createConsistencyGroup(@PathParam("tenant_id") String openstackTenantId, ConsistencyGroupCreateRequest param, @HeaderParam("X-Cinder-V1-Call") String isV1Call, @Context HttpHeaders header) {
_log.info("Creating Consistency Group : " + param.consistencygroup.name);
ConsistencyGroupCreateResponse cgResponse = new ConsistencyGroupCreateResponse();
final Project project = getCinderHelper().getProject(openstackTenantId, getUserFromContext());
final String volumeTypes = param.consistencygroup.volume_types;
VirtualPool vPool = getCinderHelper().getVpool(volumeTypes);
if (null != project && vPool != null) {
if (!vPool.getMultivolumeConsistency()) {
_log.error("Bad Request : Multi volume consistency is not enabled in the volume type {}", volumeTypes);
return CinderApiUtils.createErrorResponse(400, "Bad Request : Multi volume consistency is not enabled");
}
// Validate name
ArgValidator.checkFieldNotEmpty(param.consistencygroup.name, "name");
checkForDuplicateName(param.consistencygroup.name, BlockConsistencyGroup.class);
// Validate name not greater than 64 characters
ArgValidator.checkFieldLengthMaximum(param.consistencygroup.name, CG_MAX_LIMIT, "name");
// Create Consistency Group in db
final BlockConsistencyGroup consistencyGroup = new BlockConsistencyGroup();
consistencyGroup.setId(URIUtil.createId(BlockConsistencyGroup.class));
consistencyGroup.setLabel(param.consistencygroup.name);
consistencyGroup.setProject(new NamedURI(project.getId(), project.getLabel()));
consistencyGroup.setTenant(project.getTenantOrg());
consistencyGroup.setCreationTime(Calendar.getInstance());
ScopedLabelSet tagSet = new ScopedLabelSet();
consistencyGroup.setTag(tagSet);
tagSet.add(new ScopedLabel("volume_types", volumeTypes));
tagSet.add(new ScopedLabel("status", "available"));
tagSet.add(new ScopedLabel("availability_zone", (param.consistencygroup.availability_zone != null) ? param.consistencygroup.availability_zone : "nova"));
tagSet.add(new ScopedLabel("description", (param.consistencygroup.description != null) ? param.consistencygroup.description : "No Description"));
tagSet.add(new ScopedLabel(project.getTenantOrg().getURI().toString(), CinderApiUtils.splitString(consistencyGroup.getId().toString(), ":", 3)));
_dbClient.createObject(consistencyGroup);
cgResponse.id = CinderApiUtils.splitString(consistencyGroup.getId().toString(), ":", 3);
cgResponse.name = consistencyGroup.getLabel();
return CinderApiUtils.getCinderResponse(cgResponse, header, true, CinderConstants.STATUS_OK);
} else {
return CinderApiUtils.createErrorResponse(400, "Bad Request : can't create consistency group due to invalid argument");
}
}
use of com.emc.storageos.db.client.model.NamedURI in project coprhd-controller by CoprHD.
the class VPlexBlockServiceApiImpl method prepareVolumeForRequest.
/**
* Prepare a new Bourne volume.
*
* TODO: Use existing function (prepareVolume) when VirtualPool capabilities change
* completed by Stalin. Just pass size instead of getting from VolumeCreate
* parameter.
*
* @param size The volume size.
* @param project A reference to the volume's Project.
* @param neighborhood A reference to the volume's varray.
* @param vpool A reference to the volume's VirtualPool.
* @param storageSystemURI The URI of the volume's storage system.
* @param storagePoolURI The URI of the volume's storage pool.
* @param label The volume label.
* @param token The task id for volume creation.
* @param dbClient A reference to a database client.
*
* @return A reference to the new volume.
*/
public static Volume prepareVolumeForRequest(Long size, Project project, VirtualArray neighborhood, VirtualPool vpool, URI storageSystemURI, URI storagePoolURI, String label, ResourceOperationTypeEnum opType, String token, DbClient dbClient) {
Volume volume = new Volume();
volume.setId(URIUtil.createId(Volume.class));
volume.setLabel(label);
volume.setCapacity(size);
volume.setThinlyProvisioned(VirtualPool.ProvisioningType.Thin.toString().equalsIgnoreCase(vpool.getSupportedProvisioningType()));
volume.setVirtualPool(vpool.getId());
volume.setProject(new NamedURI(project.getId(), volume.getLabel()));
volume.setTenant(new NamedURI(project.getTenantOrg().getURI(), volume.getLabel()));
volume.setVirtualArray(neighborhood.getId());
StoragePool storagePool = null;
if (!NullColumnValueGetter.getNullURI().toString().equals(storagePoolURI.toString())) {
storagePool = dbClient.queryObject(StoragePool.class, storagePoolURI);
if (null != storagePool) {
volume.setProtocol(new StringSet());
volume.getProtocol().addAll(VirtualPoolUtil.getMatchingProtocols(vpool.getProtocols(), storagePool.getProtocols()));
}
} else {
// Must be preparing a VPLEX volume which does not
// have a storage pool so a null URI is passed. Set
// the volume protocols to FC.
StringSet protocols = new StringSet();
protocols.add(StorageProtocol.Block.FC.name());
volume.setProtocol(protocols);
}
volume.setStorageController(storageSystemURI);
StorageSystem storageSystem = dbClient.queryObject(StorageSystem.class, storageSystemURI);
String systemType = storageSystem.checkIfVmax3() ? DiscoveredDataObject.Type.vmax3.name() : storageSystem.getSystemType();
volume.setSystemType(systemType);
volume.setPool(storagePoolURI);
volume.setOpStatus(new OpStatusMap());
// Set the auto tiering policy.
if (null != vpool.getAutoTierPolicyName()) {
URI autoTierPolicyUri = StorageScheduler.getAutoTierPolicy(storagePoolURI, vpool.getAutoTierPolicyName(), dbClient);
if (null != autoTierPolicyUri) {
volume.setAutoTieringPolicyUri(autoTierPolicyUri);
}
}
if (opType != null) {
Operation op = new Operation();
op.setResourceType(opType);
volume.getOpStatus().createTaskStatus(token, op);
}
dbClient.createObject(volume);
return volume;
}
use of com.emc.storageos.db.client.model.NamedURI in project coprhd-controller by CoprHD.
the class VPlexBlockServiceApiImpl method preparePromotedVolumes.
/**
* This method creates volume objects for the copiesToStop which will used as
* independent virtual volumes if detach mirror action completes successfully.
*/
private List<URI> preparePromotedVolumes(List<VplexMirror> copiesToStop, TaskList taskList, String opId) {
List<URI> promotedVolumes = new ArrayList<URI>();
for (VplexMirror copy : copiesToStop) {
Volume v = new Volume();
v.setId(URIUtil.createId(Volume.class));
Volume sourceVplexVolume = _dbClient.queryObject(Volume.class, copy.getSource());
String promotedLabel = String.format("%s-%s", sourceVplexVolume.getLabel(), copy.getLabel());
v.setProject(new NamedURI(copy.getProject().getURI(), promotedLabel));
StringSet protocols = new StringSet();
protocols.add(StorageProtocol.Block.FC.name());
v.setProtocol(protocols);
v.setTenant(new NamedURI(copy.getTenant().getURI(), promotedLabel));
_dbClient.createObject(v);
Operation op = _dbClient.createTaskOpStatus(Volume.class, v.getId(), opId, ResourceOperationTypeEnum.PROMOTE_COPY_TO_VPLEX, copy.getId().toString());
taskList.getTaskList().add(toTask(v, Arrays.asList(copy), opId, op));
promotedVolumes.add(v.getId());
}
return promotedVolumes;
}
Aggregations