use of com.emc.storageos.volumecontroller.Recommendation in project coprhd-controller by CoprHD.
the class FileMirrorServiceApiImpl method prepareFileSystems.
/**
* Prepare the source and target filesystems
*
* @param param
* @param task
* @param taskList
* @param project
* @param varray
* @param vpool
* @param recommendations
* @param cosCapabilities
* @param createInactive
* @return
*/
public List<FileShare> prepareFileSystems(FileSystemParam param, String task, TaskList taskList, Project project, TenantOrg tenantOrg, DataObject.Flag[] flags, VirtualArray varray, VirtualPool vpool, List<Recommendation> recommendations, VirtualPoolCapabilityValuesWrapper cosCapabilities, Boolean createInactive) {
List<FileShare> preparedFileSystems = new ArrayList<>();
Iterator<Recommendation> recommendationsIter = recommendations.iterator();
while (recommendationsIter.hasNext()) {
FileMirrorRecommendation recommendation = (FileMirrorRecommendation) recommendationsIter.next();
// If id is already set in recommendation, do not prepare the fileSystem (fileSystem already exists)
if (recommendation.getId() != null) {
continue;
}
// Get the source file share!!
FileShare sourceFileShare = getPrecreatedFile(taskList, param.getLabel());
if (!cosCapabilities.createMirrorExistingFileSystem()) {
// Set the recommendation only for source file systems which are not meant for vpool change!!
_log.info(String.format("createFileSystem --- FileShare: %1$s, StoragePool: %2$s, StorageSystem: %3$s", sourceFileShare.getId(), recommendation.getSourceStoragePool(), recommendation.getSourceStorageSystem()));
validateFileSystem(recommendation, sourceFileShare);
}
// set the source mirror recommendations
setFileMirrorRecommendation(recommendation, vpool, varray, false, false, sourceFileShare);
FileShare targetFileShare = null;
StringBuilder fileLabelBuilder = null;
VirtualPool targetVpool = vpool;
String targetFsPrefix = sourceFileShare.getName();
if (cosCapabilities.getFileTargetCopyName() != null && !cosCapabilities.getFileTargetCopyName().isEmpty()) {
targetFsPrefix = cosCapabilities.getFileTargetCopyName();
}
if (FileReplicationType.LOCAL.name().equalsIgnoreCase(cosCapabilities.getFileReplicationType())) {
// Stripping out the special characters like ; /-+!@#$%^&())";:[]{}\ | but allow underscore character _
String varrayName = varray.getLabel().replaceAll("[^\\dA-Za-z\\_]", "");
fileLabelBuilder = new StringBuilder(targetFsPrefix).append("-localTarget");
_log.info("Target file system name {}", fileLabelBuilder.toString());
targetFileShare = prepareEmptyFileSystem(fileLabelBuilder.toString(), sourceFileShare.getCapacity(), project, recommendation, tenantOrg, varray, vpool, targetVpool, flags, task);
// Set target file recommendations to target file system!!!
setFileMirrorRecommendation(recommendation, vpool, varray, true, false, targetFileShare);
// Update the source and target relationship!!
setMirrorFileShareAttributes(sourceFileShare, targetFileShare);
preparedFileSystems.add(sourceFileShare);
preparedFileSystems.add(targetFileShare);
} else {
// Source file system!!
preparedFileSystems.add(sourceFileShare);
List<VirtualArray> virtualArrayTargets = new ArrayList<VirtualArray>();
if (cosCapabilities.getFileReplicationTargetVArrays() != null & !cosCapabilities.getFileReplicationTargetVArrays().isEmpty()) {
for (String strVarray : cosCapabilities.getFileReplicationTargetVArrays()) {
virtualArrayTargets.add(_dbClient.queryObject(VirtualArray.class, URI.create(strVarray)));
}
}
for (VirtualArray targetVArray : virtualArrayTargets) {
if (cosCapabilities.getFileReplicationTargetVPool() != null) {
targetVpool = _dbClient.queryObject(VirtualPool.class, cosCapabilities.getFileReplicationTargetVPool());
} else {
targetVpool = vpool;
}
// Stripping out the special characters like ; /-+!@#$%^&())";:[]{}\ | but allow underscore character _
String varrayName = targetVArray.getLabel().replaceAll("[^\\dA-Za-z\\_]", "");
fileLabelBuilder = new StringBuilder(targetFsPrefix).append("-target");
_log.info("Target file system name {}", fileLabelBuilder.toString());
targetFileShare = prepareEmptyFileSystem(fileLabelBuilder.toString(), sourceFileShare.getCapacity(), project, recommendation, tenantOrg, targetVArray, vpool, targetVpool, flags, task);
// Set target file recommendations to target file system!!!
setFileMirrorRecommendation(recommendation, targetVpool, targetVArray, true, false, targetFileShare);
// Update the source and target relationship!!
setMirrorFileShareAttributes(sourceFileShare, targetFileShare);
preparedFileSystems.add(targetFileShare);
}
}
}
return preparedFileSystems;
}
use of com.emc.storageos.volumecontroller.Recommendation in project coprhd-controller by CoprHD.
the class VPlexBlockServiceApiImpl method importVirtualVolume.
/**
* Import an existing volume to a VPLEX to make it a Virtual Volume.
* Outline: 1. Determine the VPLEX(s) that could be used. 2. If this is to
* become a distributed virtual volume, get a Recommendation for the pool
* for the haVirtualArray of the Virtual Volume. 3. Create a Virtual Volume
* and link it to the existing Volume. 4. If this is a distributed virtual
* volume, create a new Volume and link it to the virtual volume. 5. Format
* the parameters and call the controller.
*
* @param arrayURI -- the URI of the Storage Array holding the existing
* Volume.
* @param importVolume -- An existing Volume that has been provisioned.
* @param vpool -- The vpool requested on the vpool change request.
* @param taskId -- The taskId
* @throws InternalException
*/
public void importVirtualVolume(URI arrayURI, Volume importVolume, VirtualPool vpool, String taskId) throws InternalException {
VirtualArray neighborhood = _dbClient.queryObject(VirtualArray.class, importVolume.getVirtualArray());
Project project = _dbClient.queryObject(Project.class, importVolume.getProject());
URI nullPoolURI = NullColumnValueGetter.getNullURI();
BlockConsistencyGroup consistencyGroup = null;
if (importVolume.getConsistencyGroup() != null) {
consistencyGroup = _dbClient.queryObject(BlockConsistencyGroup.class, importVolume.getConsistencyGroup());
}
// Determine the VPLEX(s) that could be used.
Set<URI> vplexes = ConnectivityUtil.getVPlexSystemsAssociatedWithArray(_dbClient, arrayURI);
Iterator<URI> vplexIter = vplexes.iterator();
while (vplexIter.hasNext()) {
StorageSystem vplex = _dbClient.queryObject(StorageSystem.class, vplexIter.next());
StringSet vplexVarrays = vplex.getVirtualArrays();
if ((vplexVarrays == null) || (vplexVarrays.isEmpty()) || (!vplexVarrays.contains(neighborhood.getId().toString()))) {
vplexIter.remove();
}
}
if (vplexes.isEmpty()) {
throw APIException.badRequests.noVPlexSystemsAssociatedWithStorageSystem(arrayURI);
}
// If distributed virtual volume, get a recommendation.
// Then create the volume.
List<VolumeDescriptor> descriptors = new ArrayList<VolumeDescriptor>();
URI vplexURI = null;
StorageSystem vplexSystem = null;
Volume createVolume = null;
Project vplexProject;
if (vpool.getHighAvailability().equals(VirtualPool.HighAvailabilityType.vplex_distributed.name())) {
// Determine if the user requested a specific HA VirtualArray and an associated HA VirtualPool.
VirtualArray requestedHaVarray = null;
VirtualPool requestedHaVirtualPool = vpool;
try {
if (vpool.getHaVarrayVpoolMap() != null && !vpool.getHaVarrayVpoolMap().isEmpty()) {
for (String haNH : vpool.getHaVarrayVpoolMap().keySet()) {
if (haNH.equals(NullColumnValueGetter.getNullURI().toString())) {
continue;
}
requestedHaVarray = _dbClient.queryObject(VirtualArray.class, new URI(haNH));
String haVirtualPool = vpool.getHaVarrayVpoolMap().get(haNH);
if (haVirtualPool.equals(NullColumnValueGetter.getNullURI().toString())) {
continue;
}
requestedHaVirtualPool = _dbClient.queryObject(VirtualPool.class, new URI(haVirtualPool));
break;
}
}
} catch (URISyntaxException ex) {
s_logger.error("URISyntaxException", ex);
}
VirtualPoolCapabilityValuesWrapper cosCapabilities = new VirtualPoolCapabilityValuesWrapper();
cosCapabilities.put(VirtualPoolCapabilityValuesWrapper.SIZE, getVolumeCapacity(importVolume));
cosCapabilities.put(VirtualPoolCapabilityValuesWrapper.RESOURCE_COUNT, new Integer(1));
cosCapabilities.put(VirtualPoolCapabilityValuesWrapper.THIN_PROVISIONING, importVolume.getThinlyProvisioned());
// Get the recommendations and pick one.
List<Recommendation> recommendations = getBlockScheduler().scheduleStorageForImport(neighborhood, vplexes, requestedHaVarray, requestedHaVirtualPool, cosCapabilities);
if (recommendations.isEmpty()) {
throw APIException.badRequests.noStorageFoundForVolumeMigration(requestedHaVirtualPool.getLabel(), requestedHaVarray.getLabel(), importVolume.getId());
}
Recommendation recommendation = recommendations.get(0);
VPlexRecommendation vplexRecommendation = (VPlexRecommendation) recommendation;
vplexURI = vplexRecommendation.getVPlexStorageSystem();
vplexSystem = _dbClient.queryObject(StorageSystem.class, vplexURI);
vplexProject = getVplexProject(vplexSystem, _dbClient, _tenantsService);
// Prepare the created volume.
VirtualArray haVirtualArray = _dbClient.queryObject(VirtualArray.class, vplexRecommendation.getVirtualArray());
createVolume = prepareVolumeForRequest(getVolumeCapacity(importVolume), vplexProject, haVirtualArray, vpool, vplexRecommendation.getSourceStorageSystem(), vplexRecommendation.getSourceStoragePool(), importVolume.getLabel() + "-1", ResourceOperationTypeEnum.CREATE_BLOCK_VOLUME, taskId, _dbClient);
createVolume.addInternalFlags(Flag.INTERNAL_OBJECT);
_dbClient.updateObject(createVolume);
VolumeDescriptor desc = new VolumeDescriptor(VolumeDescriptor.Type.BLOCK_DATA, createVolume.getStorageController(), createVolume.getId(), createVolume.getPool(), cosCapabilities);
descriptors.add(desc);
} else {
vplexURI = vplexes.toArray(new URI[0])[0];
vplexSystem = _dbClient.queryObject(StorageSystem.class, vplexURI);
vplexProject = getVplexProject(vplexSystem, _dbClient, _tenantsService);
}
// Prepare the VPLEX Virtual volume.
Volume vplexVolume = prepareVolumeForRequest(getVolumeCapacity(importVolume), project, neighborhood, vpool, vplexURI, nullPoolURI, importVolume.getLabel(), ResourceOperationTypeEnum.CREATE_BLOCK_VOLUME, taskId, _dbClient);
vplexVolume.setAssociatedVolumes(new StringSet());
vplexVolume.getAssociatedVolumes().add(importVolume.getId().toString());
if (createVolume != null) {
vplexVolume.getAssociatedVolumes().add(createVolume.getId().toString());
}
if (consistencyGroup != null) {
// If the volume being converted to a virtual volume has a CG, make the virtual
// volume a member of the CG.
vplexVolume.setConsistencyGroup(consistencyGroup.getId());
consistencyGroup.addRequestedTypes(Arrays.asList(BlockConsistencyGroup.Types.VPLEX.name()));
_dbClient.updateObject(consistencyGroup);
}
vplexVolume.setVirtualPool(vpool.getId());
_dbClient.updateObject(vplexVolume);
// Add a descriptor for the VPLEX_VIRT_VOLUME
VolumeDescriptor desc = new VolumeDescriptor(VolumeDescriptor.Type.VPLEX_VIRT_VOLUME, vplexURI, vplexVolume.getId(), null, null);
descriptors.add(desc);
// Add a descriptor for the import volume too!
desc = new VolumeDescriptor(VolumeDescriptor.Type.VPLEX_IMPORT_VOLUME, importVolume.getStorageController(), importVolume.getId(), importVolume.getPool(), null);
descriptors.add(desc);
// Now send the command to the controller.
try {
s_logger.info("Calling VPlex controller.");
VPlexController controller = getController();
controller.importVolume(vplexURI, descriptors, vplexProject.getId(), vplexProject.getTenantOrg().getURI(), vpool.getId(), importVolume.getLabel() + SRC_BACKEND_VOL_LABEL_SUFFIX, null, Boolean.TRUE, taskId);
} catch (InternalException ex) {
s_logger.error("ControllerException on importVolume", ex);
String errMsg = String.format("ControllerException: %s", ex.getMessage());
Operation statusUpdate = new Operation(Operation.Status.error.name(), errMsg);
_dbClient.updateTaskOpStatus(Volume.class, vplexVolume.getId(), taskId, statusUpdate);
_dbClient.markForDeletion(vplexVolume);
if (createVolume != null) {
_dbClient.markForDeletion(createVolume);
}
throw ex;
}
}
use of com.emc.storageos.volumecontroller.Recommendation in project coprhd-controller by CoprHD.
the class VPlexBlockServiceApiImpl method makeBackendVolumeDescriptors.
/**
* Takes a list of recommendations and makes the backend volumes and volume descriptors needed to
* provision. When possible (e.g. for SRDF and Block), All recommendations must be in single varray.
* calls the underlying storage routine createVolumesAndDescriptors().
*
* @param recommendations -- a VPlex recommendation list
* @param project - Project containing the Vplex volumes
* @param vplexProject -- private project of the Vplex
* @param rootVpool -- top level Virtual Pool (VpoolUse.ROOT)
* @param varrayCount -- instance count of the varray being provisioned
* @param size -- size of each volume
* @param backendCG -- the CG to be used on the backend Storage Systems
* @param vPoolCapabilities - a VirtualPoolCapabilityValuesWrapper containing provisioning arguments
* @param createTask -- boolean if true creates a task
* @param task -- Overall task id
* @return -- list of VolumeDescriptors to be provisioned
*/
private List<VolumeDescriptor> makeBackendVolumeDescriptors(List<VPlexRecommendation> recommendations, Project project, Project vplexProject, VirtualPool rootVpool, String volumeLabel, int varrayCount, long size, BlockConsistencyGroup backendCG, VirtualPoolCapabilityValuesWrapper vPoolCapabilities, boolean createTask, String task) {
VPlexRecommendation firstRecommendation = recommendations.get(0);
List<VolumeDescriptor> descriptors = new ArrayList<VolumeDescriptor>();
URI varrayId = firstRecommendation.getVirtualArray();
VirtualPool vpool = firstRecommendation.getVirtualPool();
s_logger.info("Generated backend descriptors for {} recommendations varray {}", recommendations.size(), varrayCount);
vPoolCapabilities.put(VirtualPoolCapabilityValuesWrapper.AUTO_TIER__POLICY_NAME, vpool.getAutoTierPolicyName());
if (firstRecommendation.getRecommendation() != null) {
// If these recommendations have lower level recommendation, process them.
// This path is used for the source side of Distributed Volumes and for Local volumes
// where we support building on top of SRDF or the BlockStorage as appropriate.
List<Recommendation> childRecommendations = new ArrayList<Recommendation>();
Recommendation childRecommendation = null;
for (VPlexRecommendation recommendation : recommendations) {
childRecommendation = recommendation.getRecommendation();
childRecommendations.add(childRecommendation);
}
VirtualArray varray = _dbClient.queryObject(VirtualArray.class, varrayId);
String newVolumeLabel = generateVolumeLabel(volumeLabel, varrayCount, 0, 0);
boolean srdfTarget = (childRecommendation instanceof SRDFCopyRecommendation);
boolean srdfSource = (childRecommendation instanceof SRDFRecommendation);
if (srdfTarget) {
newVolumeLabel = newVolumeLabel + "-target";
} else if (srdfSource) {
} else {
// nothing special about these volumes, hide them in the vplex project
// We can't use the vplexProject for SRDF volumes as they determine their RDF group
// grom the project.
project = vplexProject;
}
TaskList taskList = new TaskList();
descriptors = super.createVolumesAndDescriptors(descriptors, newVolumeLabel, size, project, varray, vpool, childRecommendations, taskList, task, vPoolCapabilities);
VolumeDescriptor.Type[] types;
if (srdfTarget) {
types = new VolumeDescriptor.Type[] { VolumeDescriptor.Type.SRDF_TARGET };
} else {
types = new VolumeDescriptor.Type[] { VolumeDescriptor.Type.BLOCK_DATA, VolumeDescriptor.Type.SRDF_SOURCE, VolumeDescriptor.Type.SRDF_EXISTING_SOURCE };
}
descriptors = VolumeDescriptor.filterByType(descriptors, types);
for (VolumeDescriptor descriptor : descriptors) {
Volume volume = _dbClient.queryObject(Volume.class, descriptor.getVolumeURI());
s_logger.info(String.format("Received prepared volume %s (%s, args) type %s", volume.getLabel(), volume.getId(), descriptor.getType().name()));
volume.addInternalFlags(DataObject.Flag.INTERNAL_OBJECT);
configureCGAndReplicationGroup(rootVpool, vPoolCapabilities, backendCG, volume);
_dbClient.updateObject(volume);
}
return descriptors;
}
// Sum resourceCount across all recommendations
int totalResourceCount = 0;
for (VPlexRecommendation recommendation : recommendations) {
totalResourceCount += recommendation.getResourceCount();
}
// The code below is used for the HA side of distributed volumes.
// The HA side does not currently call the lower level schedulers to get descriptors.
s_logger.info("Processing recommendations for Virtual Array {}", varrayId);
int volumeCounter = 0;
for (VPlexRecommendation recommendation : recommendations) {
for (int i = 0; i < recommendation.getResourceCount(); i++) {
vpool = recommendation.getVirtualPool();
URI storageDeviceURI = recommendation.getSourceStorageSystem();
URI storagePoolURI = recommendation.getSourceStoragePool();
String newVolumeLabel = generateVolumeLabel(volumeLabel, varrayCount, volumeCounter, totalResourceCount);
validateVolumeLabel(newVolumeLabel, project);
s_logger.info("Volume label is {}", newVolumeLabel);
VirtualArray varray = _dbClient.queryObject(VirtualArray.class, varrayId);
// This is also handled in StorageScheduler.prepareRecomendedVolumes
long thinVolumePreAllocationSize = 0;
if (null != vpool.getThinVolumePreAllocationPercentage()) {
thinVolumePreAllocationSize = VirtualPoolUtil.getThinVolumePreAllocationSize(vpool.getThinVolumePreAllocationPercentage(), size);
}
Volume volume = prepareVolume(VolumeType.BLOCK_VOLUME, null, size, thinVolumePreAllocationSize, vplexProject, varray, vpool, storageDeviceURI, storagePoolURI, newVolumeLabel, backendCG, vPoolCapabilities);
configureCGAndReplicationGroup(rootVpool, vPoolCapabilities, backendCG, volume);
volume.addInternalFlags(Flag.INTERNAL_OBJECT);
_dbClient.persistObject(volume);
if (createTask) {
_dbClient.createTaskOpStatus(Volume.class, volume.getId(), task, ResourceOperationTypeEnum.CREATE_BLOCK_VOLUME);
}
s_logger.info("Prepared volume {} ({}) ", volume.getLabel(), volume.getId());
VolumeDescriptor descriptor = new VolumeDescriptor(VolumeDescriptor.Type.BLOCK_DATA, storageDeviceURI, volume.getId(), storagePoolURI, backendCG == null ? null : backendCG.getId(), vPoolCapabilities, size);
descriptors.add(descriptor);
volumeCounter++;
}
}
return descriptors;
}
use of com.emc.storageos.volumecontroller.Recommendation in project coprhd-controller by CoprHD.
the class FileStorageScheduler method selectStorageHADomainMatchingVpool.
/**
* Select the right StorageHADomain matching vpool protocols.
*
* @param vpool
* @param vArray
* @param poolRecommends
* recommendations after selecting matching storage pools.
* @return list of FileRecommendation
*/
private List<FileRecommendation> selectStorageHADomainMatchingVpool(VirtualPool vpool, URI vArray, List<Recommendation> poolRecommends, List<VirtualNAS> invalidNasServers) {
// Get the storage ports from invalid vnas servers!!!
List<URI> invalidPorts = getvNasStoragePortUris(invalidNasServers);
_log.debug("select matching StorageHADomain");
List<FileRecommendation> result = new ArrayList<FileRecommendation>();
for (Recommendation recommendation : poolRecommends) {
FileRecommendation rec = new FileRecommendation(recommendation);
URI storageUri = recommendation.getSourceStorageSystem();
StorageSystem storage = _dbClient.queryObject(StorageSystem.class, storageUri);
// found
if (storage.getSystemType().equals(Type.unity.toString())) {
continue;
}
if (!storage.getSystemType().equals(Type.netapp.toString()) && !storage.getSystemType().equals(Type.netappc.toString()) && !storage.getSystemType().equals(Type.vnxe.toString()) && !storage.getSystemType().equals(Type.vnxfile.toString()) && !storage.getSystemType().equals(Type.datadomain.toString())) {
result.add(rec);
continue;
}
List<StoragePort> portList = getStorageSystemPortsInVarray(storageUri, vArray);
if (portList == null || portList.isEmpty()) {
_log.info("No valid storage port found from the virtual array: " + vArray);
continue;
}
List<URI> storagePorts = new ArrayList<URI>();
boolean foundValidPort = false;
for (StoragePort port : portList) {
if (invalidPorts.contains(port.getId())) {
_log.debug("Storage port {} belongs to invalid vNas server ", port.getIpAddress());
continue;
}
foundValidPort = true;
_log.debug("Looking for port {}", port.getLabel());
URI haDomainUri = port.getStorageHADomain();
// Data Domain does not have a filer entity.
if ((haDomainUri == null) && (!storage.getSystemType().equals(Type.datadomain.toString()))) {
_log.info("No StorageHADomain URI for port {}", port.getLabel());
continue;
}
StorageHADomain haDomain = null;
if (haDomainUri != null) {
haDomain = _dbClient.queryObject(StorageHADomain.class, haDomainUri);
}
if (haDomain != null) {
StringSet protocols = haDomain.getFileSharingProtocols();
// to see if it matches virtualPool's protocols
StringSet vpoolProtocols = vpool.getProtocols();
if (protocols != null && protocols.containsAll(vpoolProtocols)) {
_log.info("Found the StorageHADomain {} for recommended storagepool: {}", haDomain.getName(), recommendation.getSourceStoragePool());
storagePorts.add(port.getId());
}
} else if (storage.getSystemType().equals(Type.datadomain.toString())) {
// The same file system on DD can support NFS and CIFS
storagePorts.add(port.getId());
} else {
_log.error("No StorageHADomain for port {}", port.getIpAddress());
}
}
// minimize collisions).
if (foundValidPort) {
Collections.shuffle(storagePorts);
rec.setStoragePorts(storagePorts);
result.add(rec);
} else {
_log.info("No valid storage port found from the storage system : " + storageUri + ", All ports belongs to invalid vNas ");
}
}
return result;
}
use of com.emc.storageos.volumecontroller.Recommendation in project coprhd-controller by CoprHD.
the class FileStorageScheduler method placeFileShare.
/**
* Schedule storage for fileshare in the varray with the given CoS
* capabilities.
*
* @param vArray
* @param vPool
* @param capabilities
* @param project
* @return list of recommended storage ports for VNAS
*/
public List<FileRecommendation> placeFileShare(VirtualArray vArray, VirtualPool vPool, VirtualPoolCapabilityValuesWrapper capabilities, Project project, Map<String, Object> optionalAttributes) {
_log.debug("Schedule storage for {} resource(s) of size {}.", capabilities.getResourceCount(), capabilities.getSize());
// create map object if null, it used to receive the error message
if (optionalAttributes == null) {
optionalAttributes = new HashMap<String, Object>();
}
if (capabilities.getFileProtectionSourceStorageDevice() != null || capabilities.getTargetStorageSystem() != null) {
Set<String> storageSystemSet = new HashSet<String>();
if (capabilities.getFileProtectionSourceStorageDevice() != null) {
storageSystemSet.add(capabilities.getFileProtectionSourceStorageDevice().toString());
} else if (capabilities.getTargetStorageSystem() != null) {
storageSystemSet.add(capabilities.getTargetStorageSystem().toString());
}
optionalAttributes.put(AttributeMatcher.Attributes.storage_system.name(), storageSystemSet);
}
// Get all storage pools that match the passed vpool params and
// protocols. In addition, the pool must have enough capacity
// to hold at least one resource of the requested size.
List<StoragePool> candidatePools = _scheduler.getMatchingPools(vArray, vPool, capabilities, optionalAttributes);
if (CollectionUtils.isEmpty(candidatePools)) {
StringBuffer errorMessage = new StringBuffer();
if (optionalAttributes.get(AttributeMatcher.ERROR_MESSAGE) != null) {
errorMessage = (StringBuffer) optionalAttributes.get(AttributeMatcher.ERROR_MESSAGE);
}
throw APIException.badRequests.noStoragePools(vArray.getLabel(), vPool.getLabel(), errorMessage.toString());
}
// Holds the invalid virtual nas servers from both
// assigned and un-assigned list.
// the invalid vnas server clould be
// over loaded or protocol not supported or
// the ports from these invalid vnas servers
// should not be considered for file provisioning!!!
List<VirtualNAS> invalidNasServers = new ArrayList<VirtualNAS>();
boolean provisioningOnVirtualNAS = true;
VirtualNAS sourcevNAsServer = null;
if (capabilities.getPersonality() != null && capabilities.getPersonality().equalsIgnoreCase(VirtualPoolCapabilityValuesWrapper.FILE_REPLICATION_TARGET)) {
// Get the source nas server, if no source vnas server, then need storage from physical nas server!!
URI sourceVNas = capabilities.getSourceVirtualNasServer();
if (sourceVNas == null) {
provisioningOnVirtualNAS = false;
} else {
sourcevNAsServer = _dbClient.queryObject(VirtualNAS.class, sourceVNas);
if (sourcevNAsServer == null || sourcevNAsServer.getInactive()) {
provisioningOnVirtualNAS = false;
}
}
}
List<FileRecommendation> fileRecommendations = new ArrayList<FileRecommendation>();
List<FileRecommendation> recommendations = null;
if (provisioningOnVirtualNAS) {
// Get the recommendation based on virtual nas servers
Map<VirtualNAS, List<StoragePool>> vNASPoolMap = getRecommendedVirtualNASBasedOnCandidatePools(vPool, vArray.getId(), candidatePools, project, invalidNasServers);
VirtualNAS currvNAS = null;
if (!vNASPoolMap.isEmpty()) {
for (Entry<VirtualNAS, List<StoragePool>> eachVNASEntry : vNASPoolMap.entrySet()) {
// If No storage pools recommended!!!
if (eachVNASEntry.getValue().isEmpty()) {
continue;
}
currvNAS = eachVNASEntry.getKey();
if (currvNAS != null) {
if (capabilities.getPersonality() != null && capabilities.getPersonality().equalsIgnoreCase(VirtualPoolCapabilityValuesWrapper.FILE_REPLICATION_TARGET)) {
if (sourcevNAsServer != null && sourcevNAsServer.getBaseDirPath().equalsIgnoreCase(currvNAS.getBaseDirPath())) {
_log.info("Target Nas server path {} is similar to source nas server {}, so considering this nas server", currvNAS.getBaseDirPath(), sourcevNAsServer.getBaseDirPath());
} else if (capabilities.getTargetNasServer() != null && capabilities.getTargetNasServer().equals(currvNAS.getId())) {
_log.info("Nas server {} is same as required target Nas server {}, so considering this nas server", currvNAS.getId(), capabilities.getTargetNasServer());
} else {
_log.info("Nas server {} is not the required target Nas server, so ignoring this nas server", currvNAS.getId());
continue;
}
}
_log.info("Best vNAS selected: {}", currvNAS.getNasName());
List<StoragePool> recommendedPools = eachVNASEntry.getValue();
// Get the recommendations for the current vnas pools.
List<Recommendation> poolRecommendations = _scheduler.getRecommendationsForPools(vArray.getId().toString(), recommendedPools, capabilities);
// Pick the pools from next available vNas recommended pools!!!
if (poolRecommendations.isEmpty()) {
_log.info("Skipping vNAS {}, as pools are not having enough resources", currvNAS.getNasName());
continue;
}
// Get the file recommendations for pool recommendation!!!
recommendations = getFileRecommendationsForVNAS(currvNAS, vArray.getId(), vPool, poolRecommendations);
if (!recommendations.isEmpty()) {
fileRecommendations.addAll(recommendations);
if (!capabilities.isVpoolProjectPolicyAssign() && !capabilities.getAllSourceRecommnedations()) {
_log.info("Selected vNAS {} for placement", currvNAS.getNasName());
break;
} else {
// Policy assignment required to create the policy on all applicable vNAS servers!!!
_log.info(" vNAS {} for Added to the list of recommendations", currvNAS.getNasName());
}
}
}
}
}
}
// Get the file recommendations
if (fileRecommendations == null || fileRecommendations.isEmpty() || capabilities.isVpoolProjectPolicyAssign() || capabilities.getAllSourceRecommnedations() || isTargetRequiredOnPhyscialNAS(capabilities)) {
// Get the recommendations for the candidate pools.
_log.info("Placement on HADomain matching pools");
List<Recommendation> poolRecommendations = _scheduler.getRecommendationsForPools(vArray.getId().toString(), candidatePools, capabilities);
recommendations = selectStorageHADomainMatchingVpool(vPool, vArray.getId(), poolRecommendations, invalidNasServers);
if (recommendations != null && !recommendations.isEmpty()) {
if (fileRecommendations != null) {
fileRecommendations.addAll(recommendations);
}
}
}
// log an error and clear the list of recommendations.
if (fileRecommendations == null || fileRecommendations.isEmpty()) {
_log.error("Could not find matching pools for virtual array {} & vpool {}", vArray.getId(), vPool.getId());
} else {
// add code for file for default recommendations for file data
for (FileRecommendation recommendation : fileRecommendations) {
FileRecommendation fileRecommendation = recommendation;
fileRecommendation.setFileType(FileType.FILE_SYSTEM_DATA);
StorageSystem system = _dbClient.queryObject(StorageSystem.class, recommendation.getSourceStorageSystem());
fileRecommendation.setDeviceType(system.getSystemType());
}
}
return fileRecommendations;
}
Aggregations