/*
* Copyright (c) 2012-2015 iWave Software LLC
* All Rights Reserved
*/
package com.emc.sa.asset.providers;
import static com.emc.vipr.client.core.filters.CompatibilityFilter.INCOMPATIBLE;
import static com.emc.vipr.client.core.filters.RegistrationFilter.REGISTERED;
import static com.emc.vipr.client.core.util.UnmanagedHelper.NATIVE_ID;
import static com.emc.vipr.client.core.util.UnmanagedHelper.PROVISIONED_CAPACITY;
import static com.emc.vipr.client.core.util.UnmanagedHelper.getInfoField;
import static com.emc.vipr.client.core.util.UnmanagedHelper.getLabel;
import static com.emc.vipr.client.core.util.UnmanagedHelper.getVpoolsForUnmanaged;
import static com.emc.vipr.client.core.util.UnmanagedHelper.isClone;
import static com.emc.vipr.client.core.util.UnmanagedHelper.isMirror;
import static com.emc.vipr.client.core.util.UnmanagedHelper.isNonRPExported;
import static com.emc.vipr.client.core.util.UnmanagedHelper.isSnapShot;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.springframework.stereotype.Component;
import com.emc.sa.asset.AssetOptionsContext;
import com.emc.sa.asset.AssetOptionsUtils;
import com.emc.sa.asset.BaseAssetOptionsProvider;
import com.emc.sa.asset.annotation.Asset;
import com.emc.sa.asset.annotation.AssetDependencies;
import com.emc.sa.asset.annotation.AssetNamespace;
import com.emc.sa.service.vipr.block.BlockStorageUtils;
import com.emc.sa.util.IngestionMethodEnum;
import com.emc.sa.util.SizeUtils;
import com.emc.sa.util.StringComparator;
import com.emc.storageos.db.client.model.UnManagedDiscoveredObject.ExportType;
import com.emc.storageos.model.block.UnManagedVolumeRestRep;
import com.emc.storageos.model.file.UnManagedFileSystemRestRep;
import com.emc.storageos.model.storagesystem.type.StorageSystemTypeList;
import com.emc.storageos.model.storagesystem.type.StorageSystemTypeRestRep;
import com.emc.storageos.model.systems.StorageSystemRestRep;
import com.emc.storageos.model.vpool.BlockVirtualPoolRestRep;
import com.emc.storageos.model.vpool.FileVirtualPoolRestRep;
import com.emc.storageos.model.vpool.VirtualPoolCommonRestRep;
import com.emc.vipr.client.ViPRCoreClient;
import com.emc.vipr.client.core.filters.StorageSystemTypeFilter;
import com.emc.vipr.client.core.util.ResourceUtils;
import com.emc.vipr.model.catalog.AssetOption;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
@Component
@AssetNamespace("vipr")
public class VirtualDataCenterProvider extends BaseAssetOptionsProvider {
final static int VOLUME_PAGE_ALL = -1;
final static int VOLUME_PAGE_SIZE = 500;
private static StorageSystemTypeFilter BLOCK;
private static StorageSystemTypeFilter FILE;
private static final String TRUE_STR = "true";
private static final String FALSE_STR = "false";
@Asset("blockStorageSystem")
public List<AssetOption> getBlockStorageSystem(AssetOptionsContext ctx) {
BLOCK = new StorageSystemTypeFilter(getStorageSystemType(ctx, "block"));
return createBaseResourceOptions(
api(ctx).storageSystems().getAll(BLOCK.and(REGISTERED).and(INCOMPATIBLE.not())));
}
@Asset("unmanagedBlockStorageSystem")
public List<AssetOption> getUnmanagedBlockStorageSystem(AssetOptionsContext ctx) {
BLOCK = new StorageSystemTypeFilter(getStorageSystemType(ctx, "block"));
return createBaseResourceOptions(
api(ctx).storageSystems().getAll(BLOCK.and(REGISTERED).and(INCOMPATIBLE.not())));
}
@Asset("unmanagedBlockProtectionSystem")
public List<AssetOption> getUnmanagedBlockProtectionSystem(AssetOptionsContext ctx) {
return createBaseResourceOptions(api(ctx).protectionSystems().getAll(REGISTERED.and(INCOMPATIBLE.not())));
}
@Asset("fileStorageSystem")
public List<AssetOption> getFileStorageSystem(AssetOptionsContext ctx) {
FILE = new StorageSystemTypeFilter(getStorageSystemType(ctx, "file"));
return createBaseResourceOptions(
api(ctx).storageSystems().getAll(FILE.and(REGISTERED).and(INCOMPATIBLE.not())));
}
// For locked fields
@Asset("unmanagedBlockVirtualPool")
public List<AssetOption> getUnmanagedVolumeVirtualPools(AssetOptionsContext ctx) {
Collection<BlockVirtualPoolRestRep> virtualPools = api(ctx).blockVpools().getAll();
return createBaseResourceOptions(virtualPools);
}
@Asset("unmanagedBlockVirtualPool")
@AssetDependencies({ "unmanagedBlockStorageSystem" })
public List<AssetOption> getUnmanagedVolumeVirtualPools(AssetOptionsContext ctx, URI storageSystem) {
Map<URI, Integer> vpools = getBlockVirtualPools(listUnmanagedVolumes(ctx, storageSystem));
Map<URI, BlockVirtualPoolRestRep> virtualPoolMap = BlockProvider.getBlockVirtualPools(api(ctx),
vpools.keySet());
List<AssetOption> options = Lists.newArrayList();
for (Map.Entry<URI, Integer> entry : vpools.entrySet()) {
BlockVirtualPoolRestRep vpool = virtualPoolMap.get(entry.getKey());
if (vpool != null) {
options.add(newAssetOption(vpool.getId().toString(), "block.virtualPool.unmanaged", vpool.getName(),
entry.getValue()));
}
}
AssetOptionsUtils.sortOptionsByLabel(options);
return options;
}
@Asset("unmanagedBlockVirtualPool")
@AssetDependencies({ "unmanagedBlockStorageSystem", "virtualArray" })
public List<AssetOption> getUnmanagedVolumeVirtualPools(AssetOptionsContext ctx, URI storageSystem,
URI virtualArray) {
Map<URI, Integer> vpools = getBlockVirtualPools(listUnmanagedVolumes(ctx, storageSystem));
Map<URI, BlockVirtualPoolRestRep> virtualPoolMap = BlockProvider.getBlockVirtualPools(api(ctx),
vpools.keySet());
List<AssetOption> options = Lists.newArrayList();
for (Map.Entry<URI, Integer> entry : vpools.entrySet()) {
BlockVirtualPoolRestRep vpool = virtualPoolMap.get(entry.getKey());
if (isVirtualPoolInVirtualArray(vpool, virtualArray)) {
options.add(newAssetOption(vpool.getId().toString(), "block.virtualPool.unmanaged", vpool.getName(),
entry.getValue()));
}
}
AssetOptionsUtils.sortOptionsByLabel(options);
return options;
}
@Asset("unmanagedBlockVirtualPool")
@AssetDependencies({ "host", "virtualArray" })
public List<AssetOption> getUnmanagedVolumeVirtualPoolsForHost(AssetOptionsContext ctx, URI host,
URI virtualArray) {
Map<URI, Integer> vpools = getBlockVirtualPools(listUnmanagedVolumesByHost(ctx, host));
Map<URI, BlockVirtualPoolRestRep> virtualPoolMap = BlockProvider.getBlockVirtualPools(api(ctx),
vpools.keySet());
List<AssetOption> options = Lists.newArrayList();
for (Map.Entry<URI, Integer> entry : vpools.entrySet()) {
BlockVirtualPoolRestRep vpool = virtualPoolMap.get(entry.getKey());
if (isVirtualPoolInVirtualArray(vpool, virtualArray)) {
options.add(newAssetOption(vpool.getId().toString(), "block.virtualPool.unmanaged", vpool.getName(),
entry.getValue()));
}
}
AssetOptionsUtils.sortOptionsByLabel(options);
return options;
}
@Asset("unexportedIngestionMethod")
@AssetDependencies({ "unmanagedBlockStorageSystem" })
public List<AssetOption> getUnexportedIngestionMethod(AssetOptionsContext ctx, URI storageSystemId) {
ViPRCoreClient client = api(ctx);
StorageSystemRestRep storageSystemRestRep = client.storageSystems().get(storageSystemId);
List<AssetOption> options = Lists.newArrayList();
options.add(newAssetOption(IngestionMethodEnum.FULL.toString(), "unmanagedVolume.ingestMethod.full"));
if (BlockProviderUtils.isVplex(storageSystemRestRep)) {
options.add(newAssetOption(IngestionMethodEnum.VIRTUAL_VOLUMES_ONLY.toString(),
"unmanagedVolume.ingestMethod.virtualVolumesOnly"));
}
return options;
}
@Asset("exportedIngestionMethod")
@AssetDependencies({ "unmanagedBlockVirtualPool" })
public List<AssetOption> getExportedIngestionMethod(AssetOptionsContext ctx, URI virtualPoolId) {
ViPRCoreClient client = api(ctx);
BlockVirtualPoolRestRep virtualPoolRestRep = client.blockVpools().get(virtualPoolId);
List<AssetOption> options = Lists.newArrayList();
options.add(newAssetOption(IngestionMethodEnum.FULL.toString(), "unmanagedVolume.ingestMethod.full"));
if (virtualPoolRestRep.getHighAvailability() != null) {
options.add(newAssetOption(IngestionMethodEnum.VIRTUAL_VOLUMES_ONLY.toString(),
"unmanagedVolume.ingestMethod.virtualVolumesOnly"));
}
return options;
}
@Asset("volumeFilter")
@AssetDependencies({ "host", "unmanagedBlockVirtualPool" })
public List<AssetOption> getUnmanagedVolumeFilter(AssetOptionsContext ctx, URI host, URI vpool) {
List<String> volumeNames = Lists.newArrayList();
for (UnManagedVolumeRestRep volume : listUnmanagedVolumesByHost(ctx, host)) {
if (matchesVpool(volume, vpool)) {
volumeNames.add(getLabel(volume));
}
}
Collections.sort(volumeNames, new StringComparator(false));
return getVolumeFilterOptions(volumeNames);
}
@Asset("unmanagedVolume")
@AssetDependencies({ "host", "unmanagedBlockVirtualPool", "volumeFilter" })
public List<AssetOption> getUnmanagedVolume(AssetOptionsContext ctx, URI host, URI vpool, int volumePage) {
List<AssetOption> options = Lists.newArrayList();
for (UnManagedVolumeRestRep volume : listUnmanagedVolumesByHost(ctx, host)) {
if (matchesVpool(volume, vpool)) {
options.add(toAssetOption(volume));
}
}
AssetOptionsUtils.sortOptionsByLabel(options);
return getVolumeSublist(volumePage, options);
}
public static List<AssetOption> getVolumeFilterOptions(List<String> volumeNames) {
List<AssetOption> options = Lists.newArrayList();
int volumeNamesSize = volumeNames.size();
int currentPage = 0;
options.add(new AssetOption(new Integer(VOLUME_PAGE_ALL).toString(), "All Volumes"));
for (int i = 0; i < volumeNames.size(); i += VOLUME_PAGE_SIZE) {
if (i + VOLUME_PAGE_SIZE > (volumeNamesSize - 1)) {
options.add(new AssetOption(new Integer(currentPage).toString(),
volumeNames.get(i) + " - " + volumeNames.get(volumeNamesSize - 1)));
} else {
options.add(new AssetOption(new Integer(currentPage).toString(),
volumeNames.get(i) + " - " + volumeNames.get(i + VOLUME_PAGE_SIZE)));
}
currentPage++;
}
return options;
}
public static List<AssetOption> getVolumeSublist(int volumePage, List<AssetOption> options) {
if (volumePage != VOLUME_PAGE_ALL) {
int optionsSize = options.size();
options = options.subList(VOLUME_PAGE_SIZE * volumePage,
(VOLUME_PAGE_SIZE * (volumePage + 1)) >= optionsSize ? optionsSize
: (VOLUME_PAGE_SIZE * (volumePage + 1)));
}
return options;
}
@Asset("volumeFilter")
@AssetDependencies({ "unmanagedBlockStorageSystem", "blockVirtualPool" })
public List<AssetOption> getVolumeFilter(AssetOptionsContext ctx, URI storageSystemId, URI vpool) {
List<String> volumeNames = Lists.newArrayList();
for (UnManagedVolumeRestRep volume : listUnmanagedVolumes(ctx, storageSystemId, vpool)) {
if (!isNonRPExported(volume.getVolumeCharacteristics())) {
volumeNames.add(getLabel(volume));
}
}
Collections.sort(volumeNames, new StringComparator(false));
return getVolumeFilterOptions(volumeNames);
}
@Asset("unmanagedVolumeByStorageSystemVirtualPool")
@AssetDependencies({ "unmanagedBlockStorageSystem", "blockVirtualPool" })
public List<AssetOption> getUnmanagedVolumeByStorageSystemVirtualPool(AssetOptionsContext ctx, URI storageSystemId,
URI vpool) {
List<AssetOption> options = Lists.newArrayList();
for (UnManagedVolumeRestRep volume : listUnmanagedVolumes(ctx, storageSystemId, vpool)) {
if (!isNonRPExported(volume.getVolumeCharacteristics())) {
options.add(toAssetOption(volume));
}
}
AssetOptionsUtils.sortOptionsByLabel(options);
return options;
}
@Asset("unmanagedVolumeByStorageSystemVirtualPool")
@AssetDependencies({ "unmanagedBlockStorageSystem", "blockVirtualPool", "volumeFilter" })
public List<AssetOption> getUnmanagedVolumeByStorageSystemVirtualPool(AssetOptionsContext ctx, URI storageSystemId,
URI vpool, int volumePage) {
List<AssetOption> options = Lists.newArrayList();
for (UnManagedVolumeRestRep volume : listUnmanagedVolumes(ctx, storageSystemId, vpool)) {
if (!isNonRPExported(volume.getVolumeCharacteristics())) {
options.add(toAssetOption(volume));
}
}
AssetOptionsUtils.sortOptionsByLabel(options);
return getVolumeSublist(volumePage, options);
}
@Asset("unmanagedVolumeByStorageSystem")
@AssetDependencies({ "unmanagedBlockStorageSystem", "unmanagedBlockVirtualPool" })
public List<AssetOption> getUnmanagedVolumeByStorageSystem(AssetOptionsContext ctx, URI storageSystemId,
URI vpool) {
List<AssetOption> options = Lists.newArrayList();
for (UnManagedVolumeRestRep volume : listUnmanagedVolumes(ctx, storageSystemId)) {
if (matchesVpool(volume, vpool) && !isNonRPExported(volume.getVolumeCharacteristics())) {
options.add(toAssetOption(volume));
}
}
AssetOptionsUtils.sortOptionsByLabel(options);
return options;
}
protected AssetOption toAssetOption(UnManagedVolumeRestRep volume) {
String nativeId = getInfoField(volume, NATIVE_ID);
String label = getLabel(volume);
long provisionedSize = getInfoField(volume, PROVISIONED_CAPACITY, 0L);
String resource = "block.unmanaged.volume";
if (isSnapShot(volume.getVolumeCharacteristics())) {
resource = "block.unmanaged.volume.withSnapshot";
} else if (isClone(volume.getVolumeCharacteristics())) {
resource = "block.unmanaged.volume.withClone";
} else if (isMirror(volume.getVolumeCharacteristics())) {
resource = "block.unmanaged.volume.withMirror";
}
return newAssetOption(volume.getId(), resource, label, nativeId,
SizeUtils.humanReadableByteCount(provisionedSize));
}
protected boolean isVirtualPoolInVirtualArray(VirtualPoolCommonRestRep vpool, URI virtualArrayId) {
if (vpool != null && virtualArrayId != null) {
List<URI> ids = ResourceUtils.refIds(vpool.getVirtualArrays());
return ids.contains(virtualArrayId);
}
return false;
}
// For locked fields
@Asset("unmanagedFileVirtualPool")
public List<AssetOption> getUnmanagedFileVirtualPools(AssetOptionsContext ctx) {
Collection<FileVirtualPoolRestRep> virtualPools = api(ctx).fileVpools().getAll();
return createBaseResourceOptions(virtualPools);
}
@Asset("unmanagedFileVirtualPool")
@AssetDependencies({ "fileStorageSystem" })
public List<AssetOption> getUnmanagedFileVirtualPools(AssetOptionsContext ctx, URI storageSystem) {
Map<URI, Integer> vpools = getFileVirtualPools(listUnmanagedFilesystems(ctx, storageSystem));
Map<URI, FileVirtualPoolRestRep> virtualPoolMap = FileProvider.getFileVirtualPools(api(ctx), vpools.keySet());
List<AssetOption> options = Lists.newArrayList();
for (Map.Entry<URI, Integer> entry : vpools.entrySet()) {
FileVirtualPoolRestRep vpool = virtualPoolMap.get(entry.getKey());
if (vpool != null) {
options.add(newAssetOption(vpool.getId().toString(), "file.virtualPool.unmanaged", vpool.getName(),
entry.getValue()));
}
}
AssetOptionsUtils.sortOptionsByLabel(options);
return options;
}
@Asset("unmanagedFileVirtualPool")
@AssetDependencies({ "fileStorageSystem", "virtualArray" })
public List<AssetOption> getUnmanagedFileSystemVirtualPools(AssetOptionsContext ctx, URI storageSystem,
URI virtualArray) {
Map<URI, Integer> vpools = getFileVirtualPools(listUnmanagedFilesystems(ctx, storageSystem));
Map<URI, FileVirtualPoolRestRep> virtualPoolMap = FileProvider.getFileVirtualPools(api(ctx), vpools.keySet());
List<AssetOption> options = Lists.newArrayList();
for (Map.Entry<URI, Integer> entry : vpools.entrySet()) {
FileVirtualPoolRestRep vpool = virtualPoolMap.get(entry.getKey());
if (isVirtualPoolInVirtualArray(vpool, virtualArray)) {
options.add(newAssetOption(vpool.getId().toString(), "file.virtualPool.unmanaged", vpool.getName(),
entry.getValue()));
}
}
AssetOptionsUtils.sortOptionsByLabel(options);
return options;
}
@Asset("unmanagedFileVirtualPool")
@AssetDependencies({ "fileStorageSystem", "virtualArray", "fileIngestExportType" })
public List<AssetOption> getUnmanagedFileSystemVirtualPools(AssetOptionsContext ctx, URI storageSystem,
URI virtualArray, String ingestExportType) {
Map<URI, Integer> vpools = getFileVirtualPools(listUnmanagedFilesystems(ctx, storageSystem), ingestExportType);
Map<URI, FileVirtualPoolRestRep> virtualPoolMap = FileProvider.getFileVirtualPools(api(ctx), vpools.keySet());
List<AssetOption> options = Lists.newArrayList();
for (Map.Entry<URI, Integer> entry : vpools.entrySet()) {
FileVirtualPoolRestRep vpool = virtualPoolMap.get(entry.getKey());
if (isVirtualPoolInVirtualArray(vpool, virtualArray)) {
options.add(newAssetOption(vpool.getId().toString(), "file.virtualPool.unmanaged", vpool.getName(),
entry.getValue()));
}
}
AssetOptionsUtils.sortOptionsByLabel(options);
return options;
}
private List<UnManagedVolumeRestRep> listUnmanagedVolumes(AssetOptionsContext ctx, URI storageSystem) {
return api(ctx).unmanagedVolumes().getByStorageSystem(storageSystem);
}
private List<UnManagedVolumeRestRep> listUnmanagedVolumes(AssetOptionsContext ctx, URI storageSystem,
URI virtualPool) {
return api(ctx).unmanagedVolumes().getByStorageSystemVirtualPool(storageSystem, virtualPool);
}
private List<UnManagedVolumeRestRep> listUnmanagedVolumesByHost(AssetOptionsContext ctx, URI host) {
if (BlockStorageUtils.isHost(host)) {
return api(ctx).unmanagedVolumes().getByHost(host);
}
// We have a cluster
else {
return api(ctx).unmanagedVolumes().getByCluster(host);
}
}
private List<UnManagedFileSystemRestRep> listUnmanagedFilesystems(AssetOptionsContext ctx, URI storageSystem) {
return api(ctx).unmanagedFileSystems().getByStorageSystem(storageSystem);
}
private List<String> getStorageSystemType(AssetOptionsContext ctx, String storagetype) {
List<String> storagesystemtypes = new ArrayList<String>();
StorageSystemTypeList storagetypelist = api(ctx).storageSystemType().listStorageSystemTypes("all");
for (StorageSystemTypeRestRep storagetypeRest : storagetypelist.getStorageSystemTypes()) {
if (storagetypeRest.getMetaType().equals(storagetype)
|| storagetypeRest.getMetaType().contains(storagetype)) {
storagesystemtypes.add(storagetypeRest.getStorageTypeName());
}
}
return storagesystemtypes;
}
public static boolean matchesVpool(UnManagedVolumeRestRep volume, URI vpool) {
Set<URI> vpools = getVpoolsForUnmanaged(volume.getVolumeCharacteristics(), volume.getSupportedVPoolUris());
return vpools.contains(vpool);
}
protected static Map<URI, Integer> getBlockVirtualPools(List<UnManagedVolumeRestRep> volumes) {
Map<URI, Integer> map = Maps.newLinkedHashMap();
for (UnManagedVolumeRestRep volume : volumes) {
Set<URI> vpools = getVpoolsForUnmanaged(volume.getVolumeCharacteristics(), volume.getSupportedVPoolUris());
for (URI vpool : vpools) {
if (map.containsKey(vpool)) {
map.put(vpool, map.get(vpool).intValue() + 1);
} else {
map.put(vpool, 1);
}
}
}
return map;
}
protected static Map<URI, Integer> getFileVirtualPools(List<UnManagedFileSystemRestRep> fileSystems) {
Map<URI, Integer> map = Maps.newLinkedHashMap();
for (UnManagedFileSystemRestRep fileSystem : fileSystems) {
Set<URI> vpools = getVpoolsForUnmanaged(fileSystem.getFileSystemCharacteristics(),
fileSystem.getSupportedVPoolUris());
for (URI vpool : vpools) {
if (map.containsKey(vpool)) {
map.put(vpool, map.get(vpool).intValue() + 1);
} else {
map.put(vpool, 1);
}
}
}
return map;
}
protected static Map<URI, Integer> getFileVirtualPools(List<UnManagedFileSystemRestRep> fileSystems, String exportType) {
Map<URI, Integer> map = Maps.newLinkedHashMap();
String isExportedSelected = FALSE_STR;
if (exportType != null) {
isExportedSelected = exportType.equalsIgnoreCase(ExportType.EXPORTED.name()) ? TRUE_STR
: FALSE_STR;
}
for (UnManagedFileSystemRestRep fileSystem : fileSystems) {
Set<URI> vpools = getVpoolsForUnmanaged(fileSystem.getFileSystemCharacteristics(),
fileSystem.getSupportedVPoolUris(), isExportedSelected);
for (URI vpool : vpools) {
if (map.containsKey(vpool)) {
map.put(vpool, map.get(vpool).intValue() + 1);
} else {
map.put(vpool, 1);
}
}
}
return map;
}
}