/*
* Copyright (c) 2008-2011 EMC Corporation
* All Rights Reserved
*/
package com.emc.storageos.db.client.model;
import com.emc.storageos.model.valid.EnumType;
import java.net.URI;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
@Cf("StoragePool")
public class StoragePool extends VirtualArrayTaggedResource {
private static final long KB = 1024;
// device native ID
private String _nativeId;
// pool name
private String _poolName;
// storage controller where this pool is located
private URI _storageDevice;
// storage protocols supported by pool
private StringSet _protocols;
// set controller specific parameter extensions for the pool
private StringMap _controllerParams;
// Current total storage capacity held by the pool (KBytes)
private Long _totalCapacity;
// Total free capacity available for allocating volumes from the pool (KBytes)
private Long _freeCapacity;
// In case of ThinPools, this would indicate how much real storage is being used by
// the allocated devices in the pool (KBytes)
private Long _subscribedCapacity;
// Whether limit on number of Resources has been set
private Boolean isResourceLimitSet = false;
// Max Resources limit
private Integer maxResources;
// DeviceStoragePools in VNXBlock & VMAX considered as THICK Pools
// UnifiedStoragePool in VNXBlock & VirtualProvisioningPool in VMAX considered as THIN Pools
private String _poolClassName;
// Supported Raid Levels in Pool
private StringSet _supportedRaidLevels;
// Setting Id to be used if Tier policy set to Auto
private String _autoTierSettingId;
// Setting Id to be used if Tier policy set to No_DataMovement
private String _noDataMovementId;
// Setting Id to be used if Tier policy set to Highest_Available_Tier
private String _highAvailableTierId;
// Setting Id to be used if Tier policy set to Lowest_Available_Tier
private String _lowAvailableTierId;
// Setting Id to be used if Tier policy set to Start_High_Then_Auto
private String _startHighThenAutoTierId;
// Max Retention days
private Integer maxRetention;
// Number of Data Centers on which this pool is spread
//This is required only for object storage pools
private Integer dataCenters;
// Stroage pools supporting de-duplication feature
private Boolean dedupCapable;
// Storage Tier Information for each Pool
// VNX Pools have multiple tiers and VMAX has single Tier always
private StringSet _tiers;
private StringSet _supportedDriveTypes;
private StringMap _tierUtilizationPercentage;
private StringSet _supportedCopyTypes;
private Integer _maxPoolUtilizationPercentage;
private Integer _maxThinPoolSubscriptionPercentage;
// limit set on array
private Integer _maxThinPoolSubscriptionPercentageFromArray;
private String _registrationStatus = RegistrationStatus.REGISTERED.toString();
private Boolean thinVolumePreAllocationSupported = false;
private Boolean autoTieringEnabled;
private Boolean compressionEnabled;
// used in finding out whether or not the pool is Compatible
private String _compatibilityStatus = CompatibilityStatus.UNKNOWN.name();
private Double _avgStorageDevicePortMetrics;
private String _discoveryStatus = DiscoveryStatus.VISIBLE.name();
public static enum PoolClassNames {
Symm_VirtualProvisioningPool,
Clar_UnifiedStoragePool,
Clar_DeviceStoragePool,
Symm_DeviceStoragePool,
VNXe_Pool,
IBMTSDS_VirtualPool,
Symm_SRPStoragePool;
public static boolean isThinPool(String poolClassName) {
return (Symm_VirtualProvisioningPool.name().equals(poolClassName)
|| Symm_SRPStoragePool.name().equals(poolClassName)
|| Clar_UnifiedStoragePool.name().equals(poolClassName)
|| VNXe_Pool.name().equals(poolClassName));
}
public static boolean isThickPool(String poolClassName) {
return (Clar_DeviceStoragePool.name().equals(poolClassName)
|| Symm_DeviceStoragePool.name().equals(poolClassName));
}
}
public static enum RaidLevels {
RAID0, RAID1, RAID2, RAID3, RAID4, RAID5, RAID6, RAID10
}
public static enum CopyTypes {
ASYNC, SYNC, UNSYNC_ASSOC, UNSYNC_UNASSOC
}
public static enum SupportedDriveTypeValues {
FC("FC"),
SAS("SAS"),
SATA("SATA SATA2 ATA"),
NL_SAS("NL_SAS"),
SSD("FC_SSD SATA2_SSD SAS_SSD EFD SSD SAS_SSD_VP"),
UNKNOWN("UNKNOWN");
private String _diskDriveValues;
SupportedDriveTypeValues(String diskDriveValues) {
_diskDriveValues = diskDriveValues;
}
public String getDiskDriveValues() {
return _diskDriveValues;
}
public static String getDiskDriveDisplayName(String diskDrive) {
for (SupportedDriveTypeValues driveType : copyOfValues) {
if (driveType.getDiskDriveValues().contains(diskDrive)) {
return driveType.toString();
}
}
return null;
}
private static final SupportedDriveTypeValues[] copyOfValues = values();
public static SupportedDriveTypeValues lookup(String name) {
for (SupportedDriveTypeValues value : copyOfValues) {
if (value.name().equals(name)) {
return value;
}
}
return null;
}
}
// Operational Status of Pool
private String _operationalStatus;
public static enum PoolOperationalStatus {
READY, NOTREADY
}
// Maximum size of Thin Volume which can be carved out of this Storage Pool in KiloBytes
private Long _maximumThinVolumeSize;
// Minimum size of Thin Volume which can be carved out of this Storage Pool in KiloBytes.
private Long _minimumThinVolumeSize;
// Maximum size of Thick Volume which can be carved out of this Storage Pool in KiloBytes
private Long _maximumThickVolumeSize;
// Minimum size of Thick Volume which can be carved out of this Storage Pool in KiloBytes.
private Long _minimumThickVolumeSize;
public static enum ControllerParam {
PoolType, NativeId,
}
public static enum SupportedResourceTypes {
THICK_ONLY,
THIN_ONLY,
THIN_AND_THICK
}
private String _supportedResourceTypes;
public static enum PoolServiceType {
block,
file,
object,
block_file;
}
// tells the type of pool in which it belongs Ex. block, file, object.
private String _poolServiceType;
// tells
public Boolean _longTermRetention;
// Map of reserved capacity in this storage pool.
// Key: volume URI, value: capacity
private StringMap _reservedCapacityMap;
// Custom properties that are array specific
private StringMap _customProperties;
/**********************************************
* AlternateIDIndex - nativeID [Clariion+APM12345+C+00000] *
* RelationIndex - StorageDevice *
* *
**********************************************/
@RelationIndex(cf = "RelationIndex", type = StorageSystem.class)
@Name("storageDevice")
public URI getStorageDevice() {
return _storageDevice;
}
public void setStorageDevice(URI storageDevice) {
this._storageDevice = storageDevice;
setChanged("storageDevice");
}
@Name("protocols")
public StringSet getProtocols() {
return _protocols;
}
public void setProtocols(StringSet protocols) {
_protocols = protocols;
setChanged("protocols");
}
@Name("nativeId")
public String getNativeId() {
return _nativeId;
}
public void setNativeId(String nativeId) {
this._nativeId = nativeId;
setChanged("nativeId");
}
@Name("poolName")
public String getPoolName() {
return _poolName;
}
public void setPoolName(String poolName) {
_poolName = poolName;
setChanged("poolName");
}
@Name("controllerParams")
public StringMap getControllerParams() {
return _controllerParams;
}
/**
* Set extensions map - overwrites existing one
*
* @param controllerParams
* StringMap of extensions to set
*/
public void setControllerParams(StringMap controllerParams) {
_controllerParams = controllerParams;
setChanged("controllerParams");
}
@Name("operationalStatus")
public void setOperationalStatus(String operationalStatus) {
_operationalStatus = operationalStatus;
setChanged("operationalStatus");
}
@Name("operationalStatus")
public String getOperationalStatus() {
return _operationalStatus;
}
public void setPoolClassName(String poolClassName) {
_poolClassName = poolClassName;
setChanged("poolClassName");
}
@Name("poolClassName")
public String getPoolClassName() {
return _poolClassName;
}
@Name("totalCapacity")
@AggregatedIndex(cf = "AggregatedIndex", classGlobal = true)
public Long getTotalCapacity() {
return (_totalCapacity != null) ? _totalCapacity : -1;
}
public void setTotalCapacity(Long totalCapacity) {
if (_totalCapacity == null || !_totalCapacity.equals(totalCapacity)) {
_totalCapacity = totalCapacity;
setChanged("totalCapacity");
}
}
@Name("freeCapacity")
@AggregatedIndex(cf = "AggregatedIndex", classGlobal = true)
public Long getFreeCapacity() {
return (_freeCapacity != null) ? _freeCapacity - calculateReservedCapacity() : -1;
}
public void setFreeCapacity(Long freeCapacity) {
if (_freeCapacity == null || !_freeCapacity.equals(freeCapacity)) {
_freeCapacity = freeCapacity;
setChanged("freeCapacity");
}
}
public Long calculateFreeCapacityWithoutReservations() {
return (_freeCapacity != null) ? _freeCapacity : -1;
}
@Name("subscribedCapacity")
@AggregatedIndex(cf = "AggregatedIndex", classGlobal = true)
public Long getSubscribedCapacity() {
return ((_subscribedCapacity != null) ? _subscribedCapacity : -1);
}
public void setSubscribedCapacity(Long subscribedCapacity) {
if (_subscribedCapacity == null || !_subscribedCapacity.equals(subscribedCapacity)) {
_subscribedCapacity = subscribedCapacity;
setChanged("subscribedCapacity");
}
}
@Name("isResourceLimitSet")
public Boolean getIsResourceLimitSet() {
return isResourceLimitSet;
}
public void setIsResourceLimitSet(Boolean isResourceLimitSet) {
this.isResourceLimitSet = isResourceLimitSet;
setChanged("isResourceLimitSet");
}
@Name("maxResources")
public Integer getMaxResources() {
return ((isResourceLimitSet) ? maxResources : -1);
}
public void setMaxResources(Integer maxResources) {
this.maxResources = (maxResources > 0) ? maxResources : 0;
setChanged("maxResources");
}
@Name("maxRetention")
public Integer getMaxRetention() {
return (null != maxRetention) ? maxRetention : 0;
}
public void setMaxRetention(Integer maxRetention) {
this.maxRetention = (maxRetention > 0) ? maxRetention : 0;
setChanged("maxRetention");
}
@Name("dataCenters")
public Integer getDataCenters() {
return (null != dataCenters) ? dataCenters : 0;
}
public void setDataCenters(Integer dataCenters) {
this.dataCenters = (dataCenters > 0) ? dataCenters : 0;
setChanged("dataCenters");
}
@Name("dedupCapable")
public Boolean getDedupCapable() {
if (null == dedupCapable) {
return false;
} else {
return dedupCapable;
}
}
public void setDedupCapable(Boolean dedupCapable) {
if (null == dedupCapable) {
this.dedupCapable = false;
} else {
this.dedupCapable = dedupCapable;
}
setChanged("dedupCapable");
}
public boolean supportsProtocols(Set<String> protocols) {
if (_protocols == null) {
return false;
}
return _protocols.containsAll(protocols);
}
public void addProtocols(Set<String> protocolSet) {
if (_protocols == null) {
setProtocols(new StringSet());
} else {
_protocols.clear();
}
_protocols.addAll(protocolSet);
}
public void addControllerParams(Map<String, String> controllerParams) {
if (controllerParams == null) {
return;
}
setControllerParams(new StringMap());
_controllerParams.putAll(controllerParams);
}
public void setMaximumThinVolumeSize(Long maximumThinVolumeSize) {
_maximumThinVolumeSize = maximumThinVolumeSize;
setChanged("maximumThinVolumeSize");
}
@Name("maximumThinVolumeSize")
public Long getMaximumThinVolumeSize() {
return _maximumThinVolumeSize == null ? 0L : _maximumThinVolumeSize;
}
public void setMinimumThinVolumeSize(Long minimumThinVolumeSize) {
_minimumThinVolumeSize = minimumThinVolumeSize;
setChanged("minimumThinVolumeSize");
}
@Name("minimumThinVolumeSize")
public Long getMinimumThinVolumeSize() {
return _minimumThinVolumeSize == null ? 0L : _minimumThinVolumeSize;
}
public void setMaximumThickVolumeSize(Long maximumThickVolumeSize) {
_maximumThickVolumeSize = maximumThickVolumeSize;
setChanged("maximumThickVolumeSize");
}
@Name("maximumThickVolumeSize")
public Long getMaximumThickVolumeSize() {
return _maximumThickVolumeSize == null ? 0L : _maximumThickVolumeSize;
}
public void setMinimumThickVolumeSize(Long minimumThickVolumeSize) {
_minimumThickVolumeSize = minimumThickVolumeSize;
setChanged("minimumThickVolumeSize");
}
@Name("minimumThickVolumeSize")
public Long getMinimumThickVolumeSize() {
return _minimumThickVolumeSize == null ? 0L : _minimumThickVolumeSize;
}
public void setSupportedResourceTypes(String supportedResourceTypes) {
_supportedResourceTypes = supportedResourceTypes;
setChanged("supportedResourceTypes");
}
/**
* Get support volume types by the pool.
*
* @return supported volume types
*/
@EnumType(SupportedResourceTypes.class)
@Name("supportedResourceTypes")
public String getSupportedResourceTypes() {
return _supportedResourceTypes;
}
public void setAutoTierSettingId(String autoTierSettingId) {
_autoTierSettingId = autoTierSettingId;
setChanged("autoTierSettingId");
}
@Name("autoTierSettingId")
public String getAutoTierSettingId() {
return _autoTierSettingId;
}
public void setNoDataMovementId(String noDataMovementId) {
_noDataMovementId = noDataMovementId;
setChanged("noDataMovementTierSettingId");
}
@Name("noDataMovementTierSettingId")
public String getNoDataMovementId() {
return _noDataMovementId;
}
public void setHighAvailableTierId(String highAvailableTierId) {
_highAvailableTierId = highAvailableTierId;
setChanged("highAvailabilityTierSettingId");
}
@Name("highAvailabilityTierSettingId")
public String getHighAvailableTierId() {
return _highAvailableTierId;
}
public void setLowAvailableTierId(String lowAvailableTierId) {
_lowAvailableTierId = lowAvailableTierId;
setChanged("lowAvailabilityTierSettingId");
}
@Name("lowAvailabilityTierSettingId")
public String getLowAvailableTierId() {
return _lowAvailableTierId;
}
public void setStartHighThenAutoTierId(String startHighThenAutoTierId) {
_startHighThenAutoTierId = startHighThenAutoTierId;
setChanged("startHighThenAutoTierSettingId");
}
@Name("startHighThenAutoTierSettingId")
public String getStartHighThenAutoTierId() {
return _startHighThenAutoTierId;
}
public void addSupportedRaidLevels(Set<String> raidLevels) {
if (null == _supportedRaidLevels) {
_supportedRaidLevels = new StringSet();
} else {
_supportedRaidLevels.clear();
}
if (!raidLevels.isEmpty()) {
_supportedRaidLevels.addAll(raidLevels);
}
}
public void setSupportedRaidLevels(StringSet raidLevels) {
_supportedRaidLevels = raidLevels;
setChanged("supportedRaidLevels");
}
@Name("supportedRaidLevels")
public StringSet getSupportedRaidLevels() {
return _supportedRaidLevels;
}
@EnumType(PoolServiceType.class)
@Name("poolServiceType")
public String getPoolServiceType() {
return _poolServiceType;
}
public void setPoolServiceType(String poolServiceType) {
_poolServiceType = poolServiceType;
setChanged("poolServiceType");
}
@Name("longTermRetention")
public Boolean getLongTermRetention() {
return (_longTermRetention != null) ?
_longTermRetention : false;
}
public void setLongTermRetention(Boolean longTermRetention) {
_longTermRetention = longTermRetention;
setChanged("longTermRetention");
}
public void addTiers(Set<String> tiers) {
if (null != _tiers) {
_tiers.clear();
} else {
setTiers(new StringSet());
}
if (!tiers.isEmpty()) {
_tiers.addAll(tiers);
}
}
public void setTiers(StringSet tiers) {
_tiers = tiers;
setChanged("tiers");
}
@Name("tiers")
public StringSet getTiers() {
return _tiers;
}
public void addDriveTypes(Set<String> driveTypes) {
if (null != _supportedDriveTypes) {
_supportedDriveTypes.clear();
} else {
setSupportedDriveTypes(new StringSet());
}
if (!driveTypes.isEmpty()) {
_supportedDriveTypes.addAll(driveTypes);
}
}
public void setSupportedDriveTypes(StringSet supportedDriveTypes) {
_supportedDriveTypes = supportedDriveTypes;
setChanged("supportedDriveTypes");
}
@AlternateId("DriveTypeToPools")
@EnumType(SupportedDriveTypeValues.class)
@Name("supportedDriveTypes")
public StringSet getSupportedDriveTypes() {
return _supportedDriveTypes;
}
public void setSupportedCopyTypes(StringSet supportedCopyTypes) {
_supportedCopyTypes = supportedCopyTypes;
setChanged("supportedCopyTypes");
}
@EnumType(CopyTypes.class)
@Name("supportedCopyTypes")
public StringSet getSupportedCopyTypes() {
return _supportedCopyTypes;
}
public void addTierUtilizationPercentage(Map<String, String> tierUtilizationPercentage) {
if (null == _tierUtilizationPercentage) {
setTierUtilizationPercentage(new StringMap());
} else {
_tierUtilizationPercentage.clear();
}
if (tierUtilizationPercentage.size() > 0) {
_tierUtilizationPercentage.putAll(tierUtilizationPercentage);
}
}
public void setTierUtilizationPercentage(StringMap tierUtilizationPercentage) {
this._tierUtilizationPercentage = tierUtilizationPercentage;
setChanged("tierUtilizationPercentage");
}
@Name("tierUtilizationPercentage")
public StringMap getTierUtilizationPercentage() {
return _tierUtilizationPercentage;
}
@Name("maxPoolUtilizationPercentage")
public Integer getMaxPoolUtilizationPercentage() {
return _maxPoolUtilizationPercentage;
}
public void setMaxPoolUtilizationPercentage(Integer maxPoolUtilizationPercentage) {
_maxPoolUtilizationPercentage = maxPoolUtilizationPercentage;
setChanged("maxPoolUtilizationPercentage");
}
@Name("maxThinPoolSubscriptionPercentage")
public Integer getMaxThinPoolSubscriptionPercentage() {
return _maxThinPoolSubscriptionPercentage;
}
public void setMaxThinPoolSubscriptionPercentage(Integer maxThinPoolSubscriptionPercentage) {
_maxThinPoolSubscriptionPercentage = maxThinPoolSubscriptionPercentage;
setChanged("maxThinPoolSubscriptionPercentage");
}
@Name("maxThinPoolSubscriptionPercentageFromArray")
public Integer getMaxThinPoolSubscriptionPercentageFromArray() {
return _maxThinPoolSubscriptionPercentageFromArray;
}
public void setMaxThinPoolSubscriptionPercentageFromArray(Integer maxThinPoolSubscriptionPercentageFromArray) {
_maxThinPoolSubscriptionPercentageFromArray = maxThinPoolSubscriptionPercentageFromArray;
setChanged("maxThinPoolSubscriptionPercentageFromArray");
}
public void setRegistrationStatus(String registrationStatus) {
_registrationStatus = registrationStatus;
setChanged("registrationStatus");
}
@EnumType(RegistrationStatus.class)
@Name("registrationStatus")
public String getRegistrationStatus() {
return _registrationStatus;
}
@Name("thinVolumePreAllocationSupported")
public Boolean getThinVolumePreAllocationSupported() {
return thinVolumePreAllocationSupported;
}
public void setThinVolumePreAllocationSupported(Boolean thinVolumePreAllocationSupported) {
this.thinVolumePreAllocationSupported = thinVolumePreAllocationSupported;
setChanged("thinVolumePreAllocationSupported");
}
@Ttl(60 * 10)
// set to 10 minutes
@Name("reservedCapacityMap")
public
StringMap getReservedCapacityMap() {
if (_reservedCapacityMap == null) {
_reservedCapacityMap = new StringMap();
}
return _reservedCapacityMap;
}
public void setReservedCapacityMap(StringMap reservedCapacityMap) {
this._reservedCapacityMap = reservedCapacityMap;
setChanged("reservedCapacityMap");
}
@Name("customProperties")
public StringMap getCustomProperties() {
if (_customProperties == null) {
_customProperties = new StringMap();
}
return _customProperties;
}
public void setCustomProperties(StringMap customProperties) {
this._customProperties = customProperties;
}
@EnumType(CompatibilityStatus.class)
@Name("compatibilityStatus")
public String getCompatibilityStatus() {
return _compatibilityStatus;
}
public void setCompatibilityStatus(String compatibilityStatus) {
_compatibilityStatus = compatibilityStatus;
setChanged("compatibilityStatus");
}
public void setAutoTieringEnabled(final Boolean autoTieringEnabled) {
this.autoTieringEnabled = autoTieringEnabled;
setChanged("autoTieringEnabled");
}
@Name("autoTieringEnabled")
public Boolean getAutoTieringEnabled() {
return this.autoTieringEnabled == null ? false : autoTieringEnabled;
}
public void setCompressionEnabled(final Boolean compressionEnabled) {
this.compressionEnabled = compressionEnabled;
setChanged("compressionEnabled");
}
@Name("compressionEnabled")
public Boolean getCompressionEnabled() {
return this.compressionEnabled == null ? false : compressionEnabled;
}
@Name("avgStorageDevicePortMetrics")
public Double getAvgStorageDevicePortMetrics() {
return _avgStorageDevicePortMetrics;
}
public void setAvgStorageDevicePortMetrics(Double avgStorageDevicePortMetrics) {
this._avgStorageDevicePortMetrics = avgStorageDevicePortMetrics;
setChanged("avgStorageDevicePortMetrics");
}
@EnumType(DiscoveryStatus.class)
@Name("discoveryStatus")
public String getDiscoveryStatus() {
return _discoveryStatus;
}
public void setDiscoveryStatus(String discoveryStatus) {
this._discoveryStatus = discoveryStatus;
setChanged("discoveryStatus");
}
/**
* Helper method to get total reserved capacity of the pool.
*
* @return reserved capacity in KBytes
*/
private Long calculateReservedCapacity() {
Long reservedCapacity = 0L;
if (_reservedCapacityMap != null) {
Collection<String> capacityCollection = _reservedCapacityMap.values();
for (String capacity : capacityCollection) {
reservedCapacity = reservedCapacity + Long.valueOf(capacity);
}
}
Long reservedCapacityKB = (reservedCapacity % KB == 0) ? reservedCapacity / KB : reservedCapacity / KB + 1;
return reservedCapacityKB; // in KB
}
/**
* Removes each mapping from the reservedCapacityMap
*
* @param objectIdStrings - list of Volume/BlockObject ids
*/
public void removeReservedCapacityForVolumes(Collection<String> objectIdStrings) {
if (objectIdStrings != null && _reservedCapacityMap != null) {
for (String idString : objectIdStrings) {
_reservedCapacityMap.remove(idString);
}
}
}
}