/*
* Copyright (c) 2012-2015 iWave Software LLC
* All Rights Reserved
*/
package com.emc.sa.asset.providers;
import java.net.URI;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
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.storageos.model.file.FileShareRestRep;
import com.emc.storageos.model.file.policy.FilePolicyRestRep;
import com.emc.storageos.model.ports.StoragePortRestRep;
import com.emc.storageos.model.varray.VirtualArrayRestRep;
import com.emc.storageos.model.vpool.BlockVirtualPoolRestRep;
import com.emc.storageos.model.vpool.FileVirtualPoolRestRep;
import com.emc.storageos.model.vpool.ObjectVirtualPoolRestRep;
import com.emc.vipr.client.ViPRCoreClient;
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;
import com.google.common.collect.Sets;
@Component
@AssetNamespace("vipr")
public class VirtualArrayProvider extends BaseAssetOptionsProvider {
@Asset("virtualArray")
public List<AssetOption> getVirtualArray(AssetOptionsContext ctx) {
return createBaseResourceOptions(api(ctx).varrays().getByTenant(ctx.getTenant()));
}
@Asset("virtualArray")
@AssetDependencies("unmanagedBlockStorageSystem")
public List<AssetOption> getBlockVirtualArrays(AssetOptionsContext ctx, URI storageSystem) {
return getVirtualArrayForStorageSystem(ctx, storageSystem);
}
@Asset("virtualArray")
@AssetDependencies({ "mobilityGroupMethod", "project" })
public List<AssetOption> getBlockVirtualArrays(AssetOptionsContext ctx, String mobilityGroupMethod, URI project) {
if (mobilityGroupMethod.equalsIgnoreCase(BlockProvider.INGEST_AND_MIGRATE_OPTION_KEY)) {
return createBaseResourceOptions(api(ctx).varrays().getByTenant(ctx.getTenant()));
} else {
return Lists.newArrayList();
}
}
@Asset("virtualArray")
@AssetDependencies("fileStorageSystem")
public List<AssetOption> getFileVirtualArrays(AssetOptionsContext ctx, URI storageSystem) {
return getVirtualArrayForStorageSystem(ctx, storageSystem);
}
protected List<AssetOption> getVirtualArrayForStorageSystem(AssetOptionsContext context, URI storageSystem) {
ViPRCoreClient client = api(context);
Set<String> virtualArrayIds = Sets.newHashSet();
for (StoragePortRestRep storagePortRestRep : client.storagePorts().getByStorageSystem(storageSystem)) {
virtualArrayIds.addAll(storagePortRestRep.getAssignedVirtualArrays());
virtualArrayIds.addAll(storagePortRestRep.getConnectedVirtualArrays());
}
List<VirtualArrayRestRep> virtualArrays = client.varrays().getByIds(ResourceUtils.uris(virtualArrayIds));
filterByContextTenant(virtualArrays, client.varrays().getByTenant(context.getTenant()));
return createBaseResourceOptions(virtualArrays);
}
@Asset("virtualArray")
@AssetDependencies({ "linuxHost" })
public List<AssetOption> getVirtualArrayForLinux(AssetOptionsContext context, URI linuxHostOrCluster) {
return getVirtualArray(context, linuxHostOrCluster);
}
@Asset("virtualArray")
@AssetDependencies({ "aixHost" })
public List<AssetOption> getVirtualArrayForAix(AssetOptionsContext context, URI aixHostOrCluster) {
return getVirtualArray(context, aixHostOrCluster);
}
@Asset("virtualArray")
@AssetDependencies({ "windowsHost" })
public List<AssetOption> getVirtualArrayForWindows(AssetOptionsContext context, URI windowsHostOrCluster) {
return getVirtualArray(context, windowsHostOrCluster);
}
@Asset("virtualArray")
@AssetDependencies({ "host" })
public List<AssetOption> getVirtualArray(AssetOptionsContext context, URI hostOrClusterId) {
ViPRCoreClient client = api(context);
List<URI> hostIds = HostProvider.getHostIds(client, hostOrClusterId);
Map<URI, VirtualArrayRestRep> virtualArrays = null;
Map<URI, VirtualArrayRestRep> allVirtualArrays = Maps.newHashMap();
for (URI hostId : hostIds) {
Map<URI, VirtualArrayRestRep> connectedVirtualArrays = ResourceUtils.mapById(client.varrays()
.findByConnectedHost(hostId));
if (virtualArrays == null) {
virtualArrays = connectedVirtualArrays;
} else {
virtualArrays.keySet().retainAll(connectedVirtualArrays.keySet());
}
allVirtualArrays.putAll(connectedVirtualArrays);
}
// Creates options for the virtual arrays, showing an indication whether the virtual array is only
// partially connected to the cluster
List<AssetOption> fullyConnectedOptions = new ArrayList<>();
List<AssetOption> partiallyConnectedOptions = new ArrayList<>();
List<VirtualArrayRestRep> varraysByTenant = client.varrays().getByTenant(context.getTenant());
for (VirtualArrayRestRep varray : allVirtualArrays.values()) {
if (!contains(varray.getId(), varraysByTenant)) {
continue;
}
boolean fullyConnected = virtualArrays.containsKey(varray.getId());
if (fullyConnected) {
fullyConnectedOptions.add(new AssetOption(varray.getId(), varray.getName()));
} else {
String label = getMessage("virtualArray.partiallyConnected", varray.getName());
partiallyConnectedOptions.add(new AssetOption(varray.getId(), label));
}
}
AssetOptionsUtils.sortOptionsByLabel(fullyConnectedOptions);
AssetOptionsUtils.sortOptionsByLabel(partiallyConnectedOptions);
// Place the fully connected options first
List<AssetOption> options = new ArrayList<>();
options.addAll(fullyConnectedOptions);
options.addAll(partiallyConnectedOptions);
return options;
}
@Asset("virtualArray")
@AssetDependencies({ "esxHost" })
public List<AssetOption> getVirtualArrayForVMware(AssetOptionsContext context, URI vmwareHostOrCluster) {
return getVirtualArray(context, vmwareHostOrCluster);
}
@Asset("fileVirtualArray")
public List<AssetOption> getFileVirtualArrays(AssetOptionsContext context) {
ViPRCoreClient client = api(context);
// Get the set of virtual arrays that are associated with file vpools
Set<URI> varrayIds = new HashSet<>();
for (FileVirtualPoolRestRep vpool : client.fileVpools().getByTenant(context.getTenant())) {
varrayIds.addAll(ResourceUtils.refIds(vpool.getVirtualArrays()));
}
filterByContextTenant(varrayIds, client.varrays().getByTenant(context.getTenant()));
return createBaseResourceOptions(client.varrays().getByIds(varrayIds));
}
@Asset("fileTargetVirtualArray")
@AssetDependencies({ "fileFilePolicy", "fileFilesystemAssociation" })
public List<AssetOption> getFileTargetVirtualArrays(AssetOptionsContext context, URI filePolicy, URI fsId) {
ViPRCoreClient client = api(context);
FilePolicyRestRep policyRest = client.fileProtectionPolicies().getFilePolicy(filePolicy);
if (policyRest.getType().equals("file_snapshot")) {
VirtualArrayRestRep vArray = null;
List<AssetOption> options = Lists.newArrayList();
FileShareRestRep fsObj = client.fileSystems().get(fsId);
if (fsObj != null) {
vArray = client.varrays().get(fsObj.getVirtualArray().getId());
options.add(createBaseResourceOption(vArray));
}
return options;
} else {
return getFileVirtualArrays(context);
}
}
@Asset("fileTargetVirtualArray")
@AssetDependencies({ "fileFilePolicy", "unprotectedFilesystem" })
public List<AssetOption> getTargetVirtualArrays(AssetOptionsContext context, URI filePolicy, URI fsId) {
ViPRCoreClient client = api(context);
FilePolicyRestRep policyRest = client.fileProtectionPolicies().getFilePolicy(filePolicy);
if (policyRest.getType().equals("file_snapshot")) {
VirtualArrayRestRep vArray = null;
List<AssetOption> options = Lists.newArrayList();
FileShareRestRep fsObj = client.fileSystems().get(fsId);
if (fsObj != null) {
vArray = client.varrays().get(fsObj.getVirtualArray().getId());
options.add(createBaseResourceOption(vArray));
}
return options;
} else {
return getFileVirtualArrays(context);
}
}
@Asset("blockVirtualArray")
public List<AssetOption> getBlockVirtualArrays(AssetOptionsContext context) {
ViPRCoreClient client = api(context);
// Get the set of virtual arrays that are associated with block vpools
Set<URI> varrayIds = new HashSet<>();
for (BlockVirtualPoolRestRep vpool : client.blockVpools().getByTenant(context.getTenant())) {
varrayIds.addAll(ResourceUtils.refIds(vpool.getVirtualArrays()));
}
filterByContextTenant(varrayIds, client.varrays().getByTenant(context.getTenant()));
return createBaseResourceOptions(client.varrays().getByIds(varrayIds));
}
@Asset("objectVirtualArray")
public List<AssetOption> getObjectVirtualArrays(AssetOptionsContext context) {
ViPRCoreClient client = api(context);
// Get the set of virtual arrays that are associated with object vpools
Set<URI> varrayIds = new HashSet<>();
for (ObjectVirtualPoolRestRep vpool : client.objectVpools().getByTenant(context.getTenant())) {
varrayIds.addAll(ResourceUtils.refIds(vpool.getVirtualArrays()));
}
filterByContextTenant(varrayIds, client.varrays().getByTenant(context.getTenant()));
return createBaseResourceOptions(client.varrays().getByIds(varrayIds));
}
/**
* remove any varrays, which context's tenant doesn't have access to, from inputArrays
*
* @param inputArrays
*/
private void filterByContextTenant(List<VirtualArrayRestRep> inputArrays, List<VirtualArrayRestRep> virtualArraysByTenant) {
Iterator<VirtualArrayRestRep> iterator = inputArrays.iterator();
while (iterator.hasNext()) {
VirtualArrayRestRep rep = iterator.next();
if (!contains(rep.getId(), virtualArraysByTenant)) {
iterator.remove();
}
}
}
private void filterByContextTenant(Set<URI> inputArrays, List<VirtualArrayRestRep> virtualArraysByTenant) {
Iterator<URI> iterator = inputArrays.iterator();
while (iterator.hasNext()) {
URI rep = iterator.next();
if (!contains(rep, virtualArraysByTenant)) {
iterator.remove();
}
}
}
private boolean contains(URI varrayID, List<VirtualArrayRestRep> varrayList) {
for (VirtualArrayRestRep rep : varrayList) {
if (rep.getId().toString().equalsIgnoreCase(varrayID.toString())) {
return true;
}
}
return false;
}
}