/*
* Copyright (c) 2015 EMC Corporation
* All Rights Reserved
*/
package com.emc.storageos.api.mapper;
import static com.emc.storageos.api.mapper.DbObjectMapper.mapDataObjectFields;
import static com.emc.storageos.api.mapper.DbObjectMapper.mapDiscoveredDataObjectFields;
import static com.emc.storageos.api.mapper.DbObjectMapper.toLink;
import static com.emc.storageos.api.mapper.DbObjectMapper.toNamedRelatedResource;
import static com.emc.storageos.api.mapper.DbObjectMapper.toRelatedResource;
import static com.emc.storageos.db.client.constraint.ContainmentConstraint.Factory.getVolumesByConsistencyGroup;
import java.net.URI;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.emc.storageos.api.service.impl.resource.utils.CapacityUtils;
import com.emc.storageos.db.client.DbClient;
import com.emc.storageos.db.client.URIUtil;
import com.emc.storageos.db.client.constraint.AlternateIdConstraint;
import com.emc.storageos.db.client.constraint.PrefixConstraint;
import com.emc.storageos.db.client.constraint.URIQueryResultList;
import com.emc.storageos.db.client.model.AutoTieringPolicy;
import com.emc.storageos.db.client.model.BlockConsistencyGroup;
import com.emc.storageos.db.client.model.BlockMirror;
import com.emc.storageos.db.client.model.BlockObject;
import com.emc.storageos.db.client.model.BlockSnapshot;
import com.emc.storageos.db.client.model.BlockSnapshotSession;
import com.emc.storageos.db.client.model.DiscoveredDataObject;
import com.emc.storageos.db.client.model.Migration;
import com.emc.storageos.db.client.model.NamedURI;
import com.emc.storageos.db.client.model.Project;
import com.emc.storageos.db.client.model.ProtectionSet;
import com.emc.storageos.db.client.model.RemoteDirectorGroup;
import com.emc.storageos.db.client.model.StorageSystem;
import com.emc.storageos.db.client.model.StorageTier;
import com.emc.storageos.db.client.model.StringSet;
import com.emc.storageos.db.client.model.SynchronizationState;
import com.emc.storageos.db.client.model.VirtualPool;
import com.emc.storageos.db.client.model.Volume;
import com.emc.storageos.db.client.model.Volume.PersonalityTypes;
import com.emc.storageos.db.client.model.VplexMirror;
import com.emc.storageos.db.client.model.UnManagedDiscoveredObjects.UnManagedExportMask;
import com.emc.storageos.db.client.model.UnManagedDiscoveredObjects.UnManagedVolume;
import com.emc.storageos.db.client.util.NullColumnValueGetter;
import com.emc.storageos.model.RelatedResourceRep;
import com.emc.storageos.model.ResourceTypeEnum;
import com.emc.storageos.model.VirtualArrayRelatedResourceRep;
import com.emc.storageos.model.adapters.StringMapAdapter;
import com.emc.storageos.model.adapters.StringSetMapAdapter;
import com.emc.storageos.model.block.BlockConsistencyGroupRestRep;
import com.emc.storageos.model.block.BlockMirrorRestRep;
import com.emc.storageos.model.block.BlockObjectRestRep;
import com.emc.storageos.model.block.BlockSnapshotRestRep;
import com.emc.storageos.model.block.BlockSnapshotSessionRestRep;
import com.emc.storageos.model.block.MigrationRestRep;
import com.emc.storageos.model.block.UnManagedExportMaskRestRep;
import com.emc.storageos.model.block.UnManagedVolumeRestRep;
import com.emc.storageos.model.block.VolumeRestRep;
import com.emc.storageos.model.block.VolumeRestRep.FullCopyRestRep;
import com.emc.storageos.model.block.VolumeRestRep.MirrorRestRep;
import com.emc.storageos.model.block.VolumeRestRep.ProtectionRestRep;
import com.emc.storageos.model.block.VolumeRestRep.RecoverPointRestRep;
import com.emc.storageos.model.block.VolumeRestRep.SRDFRestRep;
import com.emc.storageos.model.block.VplexMirrorRestRep;
import com.emc.storageos.model.block.tier.AutoTierPolicyList;
import com.emc.storageos.model.block.tier.AutoTieringPolicyRestRep;
import com.emc.storageos.model.block.tier.StorageTierRestRep;
import com.emc.storageos.model.vpool.NamedRelatedVirtualPoolRep;
import com.emc.storageos.model.vpool.VirtualPoolChangeOperationEnum;
import com.emc.storageos.model.vpool.VirtualPoolChangeRep;
import com.emc.storageos.protectioncontroller.impl.recoverpoint.RPHelper;
import com.emc.storageos.util.VPlexSrdfUtil;
import com.emc.storageos.util.VPlexUtil;
import com.emc.storageos.volumecontroller.impl.smis.srdf.SRDFUtils;
public class BlockMapper {
private static final Logger logger = LoggerFactory.getLogger(BlockMapper.class);
public static void mapBlockObjectFields(BlockObject from, BlockObjectRestRep to) {
mapDataObjectFields(from, to);
to.setWwn(from.getWWN());
to.setStorageController(from.getStorageController());
to.setProtocols(from.getProtocol());
to.setVirtualArray(toRelatedResource(ResourceTypeEnum.VARRAY, from.getVirtualArray()));
to.setDeviceLabel(from.getDeviceLabel() != null ? from.getDeviceLabel() : "");
to.setNativeId(from.getNativeId() != null ? from.getNativeId() : "");
to.setConsistencyGroup(toRelatedResource(ResourceTypeEnum.BLOCK_CONSISTENCY_GROUP, from.getConsistencyGroup()));
to.setReplicationGroupInstance(from.getReplicationGroupInstance() != null ? from.getReplicationGroupInstance() : "");
}
public static VolumeRestRep map(Volume from) {
return map(null, from, null);
}
public static VolumeRestRep map(DbClient dbClient, Volume from) {
return map(dbClient, from, null);
}
public static VolumeRestRep map(DbClient dbClient, Volume from,
Map<URI, Boolean> projectSrdfCapableCache) {
if (from == null) {
return null;
}
VolumeRestRep to = new VolumeRestRep();
mapBlockObjectFields(from, to);
if (from.getProject() != null) {
to.setProject(toRelatedResource(ResourceTypeEnum.PROJECT, from.getProject().getURI()));
}
if (from.getTenant() != null) {
to.setTenant(toRelatedResource(ResourceTypeEnum.TENANT, from.getTenant().getURI()));
}
to.setProvisionedCapacity(CapacityUtils.convertBytesToGBInStr(from.getProvisionedCapacity()));
// For VPLEX virtual volumes return allocated capacity as provisioned capacity (cop-18608)
to.setAllocatedCapacity(CapacityUtils.convertBytesToGBInStr(from.getAllocatedCapacity()));
boolean isVplexVolume = DiscoveredDataObject.Type.vplex.name().equalsIgnoreCase(from.getSystemType());
if (isVplexVolume) {
to.setAllocatedCapacity(CapacityUtils.convertBytesToGBInStr(from.getProvisionedCapacity()));
}
to.setCapacity(CapacityUtils.convertBytesToGBInStr(from.getCapacity()));
if (from.getThinlyProvisioned()) {
to.setPreAllocationSize(CapacityUtils.convertBytesToGBInStr(from.getThinVolumePreAllocationSize()));
}
to.setVirtualPool(toRelatedResource(ResourceTypeEnum.BLOCK_VPOOL, from.getVirtualPool()));
to.setIsComposite(from.getIsComposite());
to.setAutoTierPolicyUri(toRelatedResource(ResourceTypeEnum.AUTO_TIERING_POLICY, from.getAutoTieringPolicyUri(), from.getId()));
to.setThinlyProvisioned(from.getThinlyProvisioned());
to.setAccessState(from.getAccessState());
to.setLinkStatus(from.getLinkStatus());
// Default snapshot session support to false
to.setSupportsSnapshotSessions(Boolean.FALSE);
// set compression ratio
to.setCompressionRatio(from.getCompressionRatio());
if (DiscoveredDataObject.Type.vmax3.name().equalsIgnoreCase(from.getSystemType())) {
to.setSupportsSnapshotSessions(Boolean.TRUE);
}
to.setSystemType(from.getSystemType());
// Extra checks for VPLEX volumes
Volume srdfVolume = from;
Volume sourceSideBackingVolume = null;
if (null != dbClient && null != from.getAssociatedVolumes() && !from.getAssociatedVolumes().isEmpty()) {
// For snapshot session support of a VPLEX volume, we only need to check the SOURCE side of the
// volume.
sourceSideBackingVolume = VPlexUtil.getVPLEXBackendVolume(from, true, dbClient);
// Check for null in case the VPlex vol was ingested w/o the backend volumes
if ((sourceSideBackingVolume != null)
&& DiscoveredDataObject.Type.vmax3.name().equalsIgnoreCase(sourceSideBackingVolume.getSystemType())) {
to.setSupportsSnapshotSessions(Boolean.TRUE);
}
// Get the SRDF underlying volume if present. That will be used to fill on the
// SrdfRestRep below.
if (projectSrdfCapable(dbClient, from.getProject().getURI(), projectSrdfCapableCache)) {
srdfVolume = VPlexSrdfUtil.getSrdfVolumeFromVplexVolume(dbClient, from);
srdfVolume = (srdfVolume != null ? srdfVolume : from);
}
to.setAccessState(srdfVolume.getAccessState());
to.setLinkStatus(srdfVolume.getLinkStatus());
}
if (from.getPool() != null) {
to.setPool(toRelatedResource(ResourceTypeEnum.STORAGE_POOL, from.getPool()));
}
// RecoverPoint specific section
RecoverPointRestRep toRp = null;
if (from.checkForRp()) {
toRp = new RecoverPointRestRep();
toRp.setProtectionSystem(toRelatedResource(ResourceTypeEnum.PROTECTION_SYSTEM, from.getProtectionController()));
toRp.setPersonality(from.getPersonality());
toRp.setInternalSiteName(from.getInternalSiteName());
toRp.setCopyName(from.getRpCopyName());
toRp.setRsetName(from.getRSetName());
if ((from.getRpTargets() != null) && (!from.getRpTargets().isEmpty())) {
List<VirtualArrayRelatedResourceRep> rpTargets = new ArrayList<VirtualArrayRelatedResourceRep>();
for (String target : from.getRpTargets()) {
rpTargets.add(toTargetVolumeRelatedResource(ResourceTypeEnum.VOLUME, URI.create(target), getVarray(dbClient, target)));
}
toRp.setRpTargets(rpTargets);
}
if (from.getProtectionSet() != null) {
toRp.setProtectionSet(toRelatedResource(ResourceTypeEnum.PROTECTION_SET, from.getProtectionSet().getURI(), from.getId()));
}
}
// Mirror specific section
MirrorRestRep toMirror = null;
if ((from.getMirrors() != null) && (!from.getMirrors().isEmpty())) {
toMirror = new MirrorRestRep();
List<VirtualArrayRelatedResourceRep> mirrors = new ArrayList<VirtualArrayRelatedResourceRep>();
for (String mirror : from.getMirrors()) {
mirrors.add(toTargetVolumeRelatedResource(ResourceTypeEnum.BLOCK_MIRROR, URI.create(mirror), from.getId(),
getVarray(dbClient, mirror)));
}
toMirror.setMirrors(mirrors);
}
// Full copy specific section
FullCopyRestRep toFullCopy = null;
URI fullCopySourceVolumeURI = from.getAssociatedSourceVolume();
StringSet fromFullCopies = from.getFullCopies();
if (!NullColumnValueGetter.isNullURI(fullCopySourceVolumeURI) || (fromFullCopies != null && !fromFullCopies.isEmpty())) {
toFullCopy = new FullCopyRestRep();
if (fullCopySourceVolumeURI != null) {
toFullCopy.setAssociatedSourceVolume(toRelatedResource(ResourceTypeEnum.VOLUME, fullCopySourceVolumeURI));
}
if (fromFullCopies != null) {
List<VirtualArrayRelatedResourceRep> fullCopies = new ArrayList<VirtualArrayRelatedResourceRep>();
for (String fullCopy : fromFullCopies) {
fullCopies.add(toTargetVolumeRelatedResource(ResourceTypeEnum.VOLUME, URI.create(fullCopy),
getVarray(dbClient, fullCopy)));
}
toFullCopy.setFullCopyVolumes(fullCopies);
}
if (from.getSyncActive() != null) {
toFullCopy.setSyncActive(from.getSyncActive());
}
if (from.getReplicaState() != null) {
toFullCopy.setReplicaState(from.getReplicaState());
}
if (from.getFullCopySetName() != null) {
toFullCopy.setFullCopySetName(from.getFullCopySetName());
}
}
// SRDF specific section; uses srdfVolume which is a copy of from unless
// it's a vplex underlying srdf volume
SRDFRestRep toSRDF = null;
if ((srdfVolume.getSrdfTargets() != null) && (!srdfVolume.getSrdfTargets().isEmpty())) {
toSRDF = new SRDFRestRep();
List<VirtualArrayRelatedResourceRep> targets = new ArrayList<VirtualArrayRelatedResourceRep>();
if (srdfVolume != from) {
// VPLEX; translate targets to corresponding VPLEX volume. if any
for (String target : VPlexSrdfUtil.getSrdfOrVplexTargets(dbClient, srdfVolume)) {
targets.add(toTargetVolumeRelatedResource(ResourceTypeEnum.VOLUME, URI.create(target), getVarray(dbClient, target)));
}
} else {
// Non-VPLEX
for (String target : from.getSrdfTargets()) {
targets.add(toTargetVolumeRelatedResource(ResourceTypeEnum.VOLUME, URI.create(target), getVarray(dbClient, target)));
}
}
toSRDF.setPersonality(srdfVolume.getPersonality());
toSRDF.setSRDFTargetVolumes(targets);
} else if (!NullColumnValueGetter.isNullNamedURI(srdfVolume.getSrdfParent())) {
toSRDF = new SRDFRestRep();
toSRDF.setPersonality(srdfVolume.getPersonality());
toSRDF.setAssociatedSourceVolume(toRelatedResource(ResourceTypeEnum.VOLUME, srdfVolume.getSrdfParent().getURI()));
toSRDF.setSrdfCopyMode(srdfVolume.getSrdfCopyMode());
toSRDF.setSrdfGroup(srdfVolume.getSrdfGroup());
}
// Protection object encapsulates mirrors and RP
if (toMirror != null || toRp != null || toFullCopy != null || toSRDF != null) {
ProtectionRestRep toProtection = new ProtectionRestRep();
toProtection.setMirrorRep(toMirror);
toProtection.setRpRep(toRp);
toProtection.setFullCopyRep(toFullCopy);
toProtection.setSrdfRep(toSRDF);
to.setProtection(toProtection);
}
String replicationGroupInstance = isVplexVolume ?
from.getBackingReplicationGroupInstance() : from.getReplicationGroupInstance();
if (NullColumnValueGetter.isNotNullValue(replicationGroupInstance)) {
to.setReplicationGroupInstance(replicationGroupInstance);
}
if ((from.getAssociatedVolumes() != null) && (!from.getAssociatedVolumes().isEmpty())) {
List<RelatedResourceRep> backingVolumes = new ArrayList<RelatedResourceRep>();
for (String backingVolume : from.getAssociatedVolumes()) {
backingVolumes.add(toRelatedResource(ResourceTypeEnum.VOLUME, URI.create(backingVolume)));
}
to.setHaVolumes(backingVolumes);
}
if ((from.getVolumeGroupIds() != null) && (!from.getVolumeGroupIds().isEmpty())) {
List<RelatedResourceRep> volumeGroups = new ArrayList<RelatedResourceRep>();
for (String volumeGroup : from.getVolumeGroupIds()) {
volumeGroups.add(toRelatedResource(ResourceTypeEnum.VOLUME_GROUP, URI.create(volumeGroup)));
}
to.setVolumeGroups(volumeGroups);
}
return to;
}
/**
* Maintains a cache that maps projectId to whether the project is SRDF capable.
* @param dbClient
* @param projectId
* @param projectSrdfCapableCache -- can be null
* @return
*/
private static boolean projectSrdfCapable(DbClient dbClient, URI projectId, Map<URI, Boolean> projectSrdfCapableCache) {
if (projectSrdfCapableCache == null) {
// No cache is maintained - have to assume could be SRDF capable
return true;
}
boolean srdfCapable = false;
try {
if (projectSrdfCapableCache.containsKey(projectId)) {
// Return cached value
return projectSrdfCapableCache.get(projectId);
}
// Lookup project, the project name determines possible RDF Group names
Project project = dbClient.queryObject(Project.class, projectId);
if (project != null && !project.getInactive()) {
// There are potentially several RDF group names based on the project
StringSet rdfGroupNames = SRDFUtils.getQualifyingRDFGroupNames(project);
// Look for a remote director group matching one of the names.
for (String rdfGroupName : rdfGroupNames) {
URIQueryResultList uris = new URIQueryResultList();
dbClient.queryByConstraint(
PrefixConstraint.Factory.getLabelPrefixConstraint(RemoteDirectorGroup.class,
rdfGroupName), uris);
Iterator<URI> uriIterator = uris.iterator();
if (uriIterator.hasNext()) {
srdfCapable = true;
break;
}
}
}
} catch (Exception ex) {
logger.info("Exception: " + ex.getMessage(), ex);
}
projectSrdfCapableCache.put(projectId, srdfCapable);
return srdfCapable;
}
private static URI getVarray(DbClient dbClient, String target) {
if (dbClient != null) {
if (URIUtil.isType(URI.create(target), VplexMirror.class)) {
VplexMirror mirror = dbClient.queryObject(VplexMirror.class, URI.create(target));
return mirror.getVirtualArray();
}
BlockObject volume = BlockObject.fetch(dbClient, URI.create(target));
return volume == null ? null : volume.getVirtualArray();
}
return null;
}
private static VirtualArrayRelatedResourceRep toTargetVolumeRelatedResource(
ResourceTypeEnum type, URI id, URI varray) {
VirtualArrayRelatedResourceRep resourceRep = new VirtualArrayRelatedResourceRep();
if (NullColumnValueGetter.isNullURI(id)) {
return null;
}
resourceRep.setId(id);
resourceRep.setLink(toLink(type, id));
resourceRep.setVirtualArray(toRelatedResource(ResourceTypeEnum.VARRAY, varray));
return resourceRep;
}
private static VirtualArrayRelatedResourceRep toTargetVolumeRelatedResource(
ResourceTypeEnum type, URI id, URI parentId, URI varray) {
VirtualArrayRelatedResourceRep resourceRep = new VirtualArrayRelatedResourceRep();
if (NullColumnValueGetter.isNullURI(id)) {
return null;
}
resourceRep.setId(id);
resourceRep.setLink(toLink(type, id, parentId));
resourceRep.setVirtualArray(toRelatedResource(ResourceTypeEnum.VARRAY, varray));
return resourceRep;
}
public static BlockSnapshotRestRep map(DbClient dbClient, BlockSnapshot from) {
if (from == null) {
return null;
}
BlockSnapshotRestRep to = new BlockSnapshotRestRep();
mapBlockObjectFields(from, to);
// Map the consistency group
to.setConsistencyGroup(toRelatedResource(ResourceTypeEnum.BLOCK_CONSISTENCY_GROUP, from.getConsistencyGroup()));
if (from.getParent() != null) {
URI parentURI = from.getParent().getURI();
URIQueryResultList results = new URIQueryResultList();
dbClient.queryByConstraint(AlternateIdConstraint.Factory.getVolumeByAssociatedVolumesConstraint(parentURI.toString()), results);
Iterator<URI> resultsIter = results.iterator();
if (resultsIter.hasNext()) {
parentURI = resultsIter.next();
}
to.setParent(toRelatedResource(ResourceTypeEnum.VOLUME, parentURI));
}
if (from.getProject() != null) {
to.setProject(toRelatedResource(ResourceTypeEnum.PROJECT, from.getProject().getURI()));
}
to.setNewVolumeNativeId(from.getNewVolumeNativeId());
to.setSourceNativeId(from.getSourceNativeId());
to.setSyncActive(from.getIsSyncActive());
to.setReplicaState(getReplicaState(from));
to.setReadOnly(from.getIsReadOnly());
to.setSnapsetLabel(from.getSnapsetLabel() != null ? from.getSnapsetLabel() : "");
to.setProvisionedCapacity(CapacityUtils.convertBytesToGBInStr(from.getProvisionedCapacity()));
to.setAllocatedCapacity(CapacityUtils.convertBytesToGBInStr(from.getAllocatedCapacity()));
to.setTechnologyType(from.getTechnologyType());
return to;
}
public static String getReplicaState(BlockSnapshot snapshot) {
if (snapshot.getIsSyncActive()) {
return SynchronizationState.SYNCHRONIZED.name();
} else {
return SynchronizationState.PREPARED.name();
}
}
/**
* Maps a BlockSnapshotSession instance to its Rest representation.
*
* @param dbClient A reference to a database client.
* @param from An instance of BlockSnapshotSession.
*
* @return An instance of BlockSnapshotSessionRestRep
*/
public static BlockSnapshotSessionRestRep map(DbClient dbClient, BlockSnapshotSession from) {
if (from == null) {
return null;
}
BlockSnapshotSessionRestRep to = new BlockSnapshotSessionRestRep();
// Map base class fields.
mapDataObjectFields(from, to);
// Map snapshot session consistency group.
URI consistencyGroup = from.getConsistencyGroup();
if (consistencyGroup != null) {
to.setConsistencyGroup(toRelatedResource(ResourceTypeEnum.BLOCK_CONSISTENCY_GROUP, consistencyGroup));
}
// Map snapshot session parent i.e., the snapshot session source.
NamedURI parentNamedURI = from.getParent();
if (parentNamedURI != null) {
URI parentURI = parentNamedURI.getURI();
// It may be possible that the source for the snapshot
// session is a backend source volume for a VPLEX volume
// if we support creating snapshot sessions for VPLEX
// volumes backed by storage that supports snapshot sessions.
// In this case, the parent we want to reflect in the response
// is the VPLEX volume.
URIQueryResultList results = new URIQueryResultList();
dbClient.queryByConstraint(AlternateIdConstraint.Factory.getVolumeByAssociatedVolumesConstraint(parentURI.toString()), results);
Iterator<URI> resultsIter = results.iterator();
if (resultsIter.hasNext()) {
parentURI = resultsIter.next();
}
// This theoretically could be a Volume or BlockSnspshot instance
// when we support creating a snapshot session of a linked target
// volume for an array snapshot, which is a BlockSnapshot.
if (URIUtil.isType(parentURI, Volume.class)) {
to.setParent(toRelatedResource(ResourceTypeEnum.VOLUME, parentURI));
}
else {
to.setParent(toRelatedResource(ResourceTypeEnum.BLOCK_SNAPSHOT, parentURI));
}
}
// Map project
NamedURI projectURI = from.getProject();
if (projectURI != null) {
to.setProject(toRelatedResource(ResourceTypeEnum.PROJECT, projectURI.getURI()));
}
// Map storage controller
URI storageURI = from.getStorageController();
if (storageURI != null) {
to.setStorageController(storageURI);
}
// Map linked targets.
StringSet linkedTargetIds = from.getLinkedTargets();
if ((linkedTargetIds != null) && (!linkedTargetIds.isEmpty())) {
List<RelatedResourceRep> linkedTargetReps = new ArrayList<RelatedResourceRep>();
for (String linkedTargetId : linkedTargetIds) {
URI linkedTargetURI = URI.create(linkedTargetId);
// Linked targets are instances of BlockSnapshot.
linkedTargetReps.add(toRelatedResource(ResourceTypeEnum.BLOCK_SNAPSHOT, linkedTargetURI));
}
to.setLinkedTargets(linkedTargetReps);
}
// Map session label.
to.setSessionLabel(from.getSessionLabel());
// Map replication group name.
to.setReplicationGroupInstance(from.getReplicationGroupInstance());
// Map session set name.
to.setSessionSetName(from.getSessionSetName());
return to;
}
public static BlockMirrorRestRep map(DbClient dbClient, BlockMirror from) {
if (from == null) {
return null;
}
BlockMirrorRestRep to = new BlockMirrorRestRep();
mapBlockObjectFields(from, to);
if (from.getSource() != null) {
to.setSource(toNamedRelatedResource(ResourceTypeEnum.VOLUME, from.getSource().getURI(), from.getSource().getName()));
}
to.setSyncState(from.getSyncState());
to.setSyncType(from.getSyncType());
to.setReplicaState(SynchronizationState.fromState(from.getSyncState()).name());
to.setVirtualPool(toRelatedResource(ResourceTypeEnum.BLOCK_VPOOL, from.getVirtualPool()));
if (from.getPool() != null) {
to.setPool(toRelatedResource(ResourceTypeEnum.STORAGE_POOL, from.getPool()));
}
return to;
}
public static VplexMirrorRestRep map(VplexMirror from) {
if (from == null) {
return null;
}
VplexMirrorRestRep to = new VplexMirrorRestRep();
mapDataObjectFields(from, to);
if (from.getSource() != null) {
to.setSource(toNamedRelatedResource(ResourceTypeEnum.VOLUME, from.getSource().getURI(), from.getSource().getName()));
}
to.setStorageController(from.getStorageController());
to.setVirtualArray(toRelatedResource(ResourceTypeEnum.VARRAY, from.getVirtualArray()));
to.setDeviceLabel(from.getDeviceLabel() != null ? from.getDeviceLabel() : "");
to.setNativeId(from.getNativeId() != null ? from.getNativeId() : "");
to.setVirtualPool(toRelatedResource(ResourceTypeEnum.BLOCK_VPOOL, from.getVirtualPool()));
return to;
}
public static BlockConsistencyGroupRestRep map(BlockConsistencyGroup from, Set<URI> volumes, DbClient dbClient) {
if (from == null) {
return null;
}
BlockConsistencyGroupRestRep to = new BlockConsistencyGroupRestRep();
mapDataObjectFields(from, to);
to.setVirtualArray(toRelatedResource(ResourceTypeEnum.VARRAY, from.getVirtualArray()));
to.setProject(toRelatedResource(ResourceTypeEnum.PROJECT, from.getProject().getURI()));
if (!NullColumnValueGetter.isNullURI(from.getStorageController())) {
to.setStorageController(toRelatedResource(ResourceTypeEnum.STORAGE_SYSTEM, from.getStorageController()));
}
to.setArrayConsistency(from.getArrayConsistency());
// Default snapshot session support to false
to.setSupportsSnapshotSessions(Boolean.FALSE);
if (dbClient != null && from.getSystemConsistencyGroups() != null) {
for (String systemId : from.getSystemConsistencyGroups().keySet()) {
StorageSystem system = dbClient.queryObject(StorageSystem.class, URI.create(systemId));
if (system != null && system.checkIfVmax3()) {
to.setSupportsSnapshotSessions(Boolean.TRUE);
}
}
}
try {
if (from.getSystemConsistencyGroups() != null) {
to.setSystemConsistencyGroups(new StringSetMapAdapter().marshal(from.getSystemConsistencyGroups()));
if (!to.getSupportsSnapshotSessions()) {
// If we haven't already determined that we can support snapshot sessions,
// loop through all the system cg's to find any storage systems that this
// cg resides on. If any of those entries supports snapshot sessions then
// we can flag this as true.
if (dbClient != null && to.getSystemConsistencyGroups() != null) {
for (StringSetMapAdapter.Entry entry : to.getSystemConsistencyGroups()) {
String storageSystemId = entry.getKey();
if (storageSystemId != null) {
StorageSystem system = dbClient.queryObject(StorageSystem.class, URI.create(storageSystemId));
if (system != null && system.checkIfVmax3()) {
to.setSupportsSnapshotSessions(Boolean.TRUE);
break;
}
}
}
}
}
}
} catch (Exception e) {
// internally ignored
logger.debug(e.getMessage(), e);
}
if (from.getTypes() != null) {
to.setTypes(from.getTypes());
}
if (dbClient != null) {
List<RelatedResourceRep> volumesResourceRep = new ArrayList<RelatedResourceRep>();
final URIQueryResultList cgVolumesResults = new URIQueryResultList();
dbClient.queryByConstraint(getVolumesByConsistencyGroup(from.getId()), cgVolumesResults);
Iterator<Volume> volumeIterator = dbClient.queryIterativeObjects(Volume.class, cgVolumesResults);
boolean first = true;
while(volumeIterator.hasNext()) {
// Get the first RP or SRDF volume. From this we are able to obtain the
// link status and protection set (RP) information for all volumes in the
// CG.
Volume volume = volumeIterator.next();
if (first) {
if (from.getTypes().contains(BlockConsistencyGroup.Types.RP.toString())
&& !NullColumnValueGetter.isNullNamedURI(volume.getProtectionSet())) {
// Get the protection set from the first volume and set the appropriate fields
ProtectionSet protectionSet = dbClient.queryObject(ProtectionSet.class, volume.getProtectionSet());
to.setRpConsistenyGroupId(protectionSet.getProtectionId());
to.setLinkStatus(protectionSet.getProtectionStatus());
to.setRpProtectionSystem(protectionSet.getProtectionSystem());
} else if (from.getTypes().contains(BlockConsistencyGroup.Types.SRDF.toString())) {
// Operations cannot be performed individually on volumes within an SRDF CG, hence
// we can take any one of the volume's link status and update the CG link status.
to.setLinkStatus(volume.getLinkStatus());
}
}
// Only display CG volumes that are non-RP or RP source volumes. Exclude RP+VPlex backing volumes.
if ((!volume.checkForRp() && !RPHelper.isAssociatedToAnyRpVplexTypes(volume, dbClient))
|| (volume.checkForRp() && PersonalityTypes.SOURCE.name().equals(volume.getPersonality()))) {
volumesResourceRep.add(toRelatedResource(ResourceTypeEnum.VOLUME, volume.getId()));
}
first = false;
}
to.setVolumes(volumesResourceRep);
}
return to;
}
public static MigrationRestRep map(Migration from) {
if (from == null) {
return null;
}
MigrationRestRep to = new MigrationRestRep();
to.setVolume(toRelatedResource(ResourceTypeEnum.VOLUME, from.getVolume()));
to.setSource(toRelatedResource(ResourceTypeEnum.VOLUME, from.getSource()));
to.setTarget(toRelatedResource(ResourceTypeEnum.VOLUME, from.getTarget()));
to.setStartTime(from.getStartTime());
to.setStatus(from.getMigrationStatus());
to.setPercentageDone(from.getPercentDone());
return to;
}
public static AutoTieringPolicyRestRep map(AutoTieringPolicy from) {
if (from == null) {
return null;
}
AutoTieringPolicyRestRep to = new AutoTieringPolicyRestRep();
mapDiscoveredDataObjectFields(from, to);
to.setSystemType(from.getSystemType());
to.setStorageGroupName(from.getStorageGroupName());
to.setStorageDevice(toRelatedResource(ResourceTypeEnum.STORAGE_SYSTEM, from.getStorageSystem()));
to.setStoragePools(from.getPools());
to.setPolicyName(from.getPolicyName());
to.setPolicyEnabled(from.getPolicyEnabled());
to.setProvisioningType(from.getProvisioningType());
return to;
}
public static void addAutoTierPolicy(AutoTieringPolicy policy, AutoTierPolicyList list, boolean uniquePolicyNames) {
if (DiscoveredDataObject.Type.vnxblock.toString().equalsIgnoreCase(policy.getSystemType())
|| uniquePolicyNames) {
if (!list.containsPolicy(policy.getPolicyName())) {
list.getAutoTierPolicies().add(
toNamedRelatedResource(policy, policy.getPolicyName()));
}
} else if (!uniquePolicyNames) {
list.getAutoTierPolicies().add(
toNamedRelatedResource(policy, policy.getNativeGuid()));
}
}
public static StorageTierRestRep map(StorageTier from) {
if (from == null) {
return null;
}
StorageTierRestRep to = new StorageTierRestRep();
mapDiscoveredDataObjectFields(from, to);
to.setEnabledState(from.getEnabledState());
to.setPercentage(from.getPercentage());
to.setTotalCapacity(from.getTotalCapacity());
to.setDiskDriveTechnology(from.getDiskDriveTechnology());
to.setAutoTieringPolicies(from.getAutoTieringPolicies());
return to;
}
public static UnManagedVolumeRestRep map(UnManagedVolume from) {
if (from == null) {
return null;
}
UnManagedVolumeRestRep to = new UnManagedVolumeRestRep();
mapDataObjectFields(from, to);
to.setNativeGuid(from.getNativeGuid());
try {
to.setVolumeInformation(new StringSetMapAdapter().marshal(from.getVolumeInformation()));
} catch (Exception e) {
// Intentionally ignored
}
to.setVolumeCharacteristics(new StringMapAdapter().marshal(from.getVolumeCharacterstics()));
to.setStorageSystem(toRelatedResource(ResourceTypeEnum.STORAGE_SYSTEM, from.getStorageSystemUri()));
to.setStoragePool(toRelatedResource(ResourceTypeEnum.STORAGE_POOL, from.getStoragePoolUri()));
List<String> uems = new ArrayList<String>();
for (String uem : from.getUnmanagedExportMasks()) {
uems.add(uem);
}
to.setUnManagedExportMasks(uems);
List<String> initiatorUris = new ArrayList<String>();
for (String uri : from.getInitiatorUris()) {
initiatorUris.add(uri);
}
to.setInitiatorUris(initiatorUris);
List<String> initiatorNetworkIds = new ArrayList<String>();
for (String id : from.getInitiatorNetworkIds()) {
initiatorNetworkIds.add(id);
}
to.setInitiatorNetworkIds(initiatorNetworkIds);
List<String> storagePortUris = new ArrayList<String>();
for (String uri : from.getStoragePortUris()) {
storagePortUris.add(uri);
}
to.setStoragePortUris(storagePortUris);
List<String> supportedVPoolUris = new ArrayList<String>();
for (String uri : from.getSupportedVpoolUris()) {
supportedVPoolUris.add(uri);
}
to.setSupportedVPoolUris(supportedVPoolUris);
to.setWWN(from.getWwn());
return to;
}
public static UnManagedExportMaskRestRep map(UnManagedExportMask from) {
if (from == null) {
return null;
}
UnManagedExportMaskRestRep to = new UnManagedExportMaskRestRep();
mapDataObjectFields(from, to);
to.setNativeId(from.getNativeId());
to.setMaskName(from.getMaskName());
to.setStorageSystem(toRelatedResource(ResourceTypeEnum.STORAGE_SYSTEM, from.getStorageSystemUri()));
if ((from.getKnownInitiatorUris() != null) && (!from.getKnownInitiatorUris().isEmpty())) {
List<RelatedResourceRep> reps = new ArrayList<RelatedResourceRep>();
for (String uri : from.getKnownInitiatorUris()) {
reps.add(toRelatedResource(ResourceTypeEnum.INITIATOR, URI.create(uri)));
}
to.setKnownInitiatorUris(reps);
}
if ((from.getKnownStoragePortUris() != null) && (!from.getKnownStoragePortUris().isEmpty())) {
List<RelatedResourceRep> reps = new ArrayList<RelatedResourceRep>();
for (String uri : from.getKnownStoragePortUris()) {
reps.add(toRelatedResource(ResourceTypeEnum.STORAGE_PORT, URI.create(uri)));
}
to.setKnownStoragePortUris(reps);
}
if ((from.getKnownVolumeUris() != null) && (!from.getKnownVolumeUris().isEmpty())) {
List<RelatedResourceRep> reps = new ArrayList<RelatedResourceRep>();
for (String uri : from.getKnownVolumeUris()) {
reps.add(toRelatedResource(ResourceTypeEnum.VOLUME, URI.create(uri)));
}
to.setKnownStorageVolumeUris(reps);
}
if ((from.getUnmanagedVolumeUris() != null) && (!from.getUnmanagedVolumeUris().isEmpty())) {
List<RelatedResourceRep> reps = new ArrayList<RelatedResourceRep>();
for (String uri : from.getUnmanagedVolumeUris()) {
reps.add(toRelatedResource(ResourceTypeEnum.UNMANAGED_VOLUMES, URI.create(uri)));
}
to.setUnmanagedVolumeUris(reps);
}
to.setUnmanagedInitiatorNetworkIds(from.getUnmanagedInitiatorNetworkIds());
to.setUnmanagedStoragePortNetworkIds(from.getUnmanagedStoragePortNetworkIds());
return to;
}
public static NamedRelatedVirtualPoolRep toVirtualPoolResource(VirtualPool vpool) {
ResourceTypeEnum type = BlockMapper.getResourceType(VirtualPool.Type.valueOf(vpool.getType()));
return new NamedRelatedVirtualPoolRep(vpool.getId(), toLink(type, vpool.getId()), vpool.getLabel(), vpool.getType());
}
public static VirtualPoolChangeRep toVirtualPoolChangeRep(VirtualPool vpool, List<VirtualPoolChangeOperationEnum> allowedOpertions,
String notAllowedReason) {
ResourceTypeEnum type = BlockMapper.getResourceType(VirtualPool.Type.valueOf(vpool.getType()));
return new VirtualPoolChangeRep(vpool.getId(), toLink(type, vpool.getId()), vpool.getLabel(), vpool.getType(), notAllowedReason,
allowedOpertions);
}
public static ResourceTypeEnum getResourceType(VirtualPool.Type cosType) {
if (VirtualPool.Type.block == cosType) {
return ResourceTypeEnum.BLOCK_VPOOL;
} else if (VirtualPool.Type.file == cosType) {
return ResourceTypeEnum.FILE_VPOOL;
} else if (VirtualPool.Type.object == cosType) {
return ResourceTypeEnum.OBJECT_VPOOL;
} else {
// impossible;
return ResourceTypeEnum.BLOCK_VPOOL;
}
}
}