/*
* Copyright (c) 2016 EMC Corporation
* All Rights Reserved
*/
package com.emc.storageos.volumecontroller.impl.validators;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.emc.storageos.db.client.DbClient;
import com.emc.storageos.db.client.model.BlockObject;
import com.emc.storageos.db.client.model.BlockSnapshot;
import com.emc.storageos.db.client.model.ExportMask;
import com.emc.storageos.db.client.model.Initiator;
import com.emc.storageos.db.client.model.StorageSystem;
import com.emc.storageos.db.client.model.Volume;
import com.emc.storageos.db.client.util.NullColumnValueGetter;
import com.emc.storageos.volumecontroller.impl.validators.contexts.ExportMaskValidationContext;
/**
* Top-level factory class for building {@link Validator} instances.
*/
public class ValidatorFactory implements StorageSystemValidatorFactory {
private DbClient dbClient;
private Map<String, StorageSystemValidatorFactory> systemFactories;
private static final Logger log = LoggerFactory.getLogger(ValidatorFactory.class);
public void setDbClient(DbClient dbClient) {
this.dbClient = dbClient;
}
public void setSystemFactories(Map<String, StorageSystemValidatorFactory> systemFactories) {
this.systemFactories = systemFactories;
}
/**
* Validates a list of Volumes
*
* @param uris
* @param delete
* @param remediate
* @param checks A list of validation checks to be made (of type ValCk).
* @return
*/
public List<URI> volumeURIs(List<URI> uris, boolean delete, boolean remediate, ValCk... checks) {
List<URI> remediatedURIs = new ArrayList<URI>();
List<Volume> volumes = dbClient.queryObject(Volume.class, uris);
List<Volume> remediatedVolumes = volumes(volumes, delete, remediate, checks);
for (Volume volume : remediatedVolumes) {
remediatedURIs.add(volume.getId());
}
return remediatedURIs;
}
public List<Volume> volumes(List<Volume> volumes, boolean delete, boolean remediate, ValCk... checks) {
// Collect remediated volumes
List<Volume> remediatedVolumes = new ArrayList<Volume>();
// Partition volumes by StorageSystem
Map<URI, List<Volume>> systemUriToVolumeList = new HashMap<URI, List<Volume>>();
for (Volume volume : volumes) {
// In many cases this method is called with ViPR volumes that have been
// pre-created for a request. These volumes don't yet exist on the
// storage system. Upon successful execution of the request, these volumes
// are updated with the native ids, wwns, etc, of the now existing volumes.
// We do not want to validate these volume as they do not yet exist and
// will surely fail validation.
String nativeGuid = volume.getNativeGuid();
if (!NullColumnValueGetter.isNullValue(nativeGuid)) {
if (!systemUriToVolumeList.containsKey(volume.getStorageController())) {
systemUriToVolumeList.put(volume.getStorageController(), new ArrayList<Volume>());
}
systemUriToVolumeList.get(volume.getStorageController()).add(volume);
} else {
log.info("Skipping validation of volume {}:{} which does not have a native guid",
volume.getId(), volume.getLabel());
}
}
// For each Storage System, do the validations
for (Map.Entry<URI, List<Volume>> entry : systemUriToVolumeList.entrySet()) {
StorageSystem system = dbClient.queryObject(StorageSystem.class, entry.getKey());
StorageSystemValidatorFactory validator = getSystemValidator(system);
if (validator != null) {
validator.volumes(system, entry.getValue(), delete, remediate, checks);
}
}
return remediatedVolumes;
}
public StorageSystemValidatorFactory vmax() {
return systemFactories.get("vmax");
}
public StorageSystemValidatorFactory xtremio() {
return systemFactories.get("xtremio");
}
public StorageSystemValidatorFactory vnxe() {
return systemFactories.get("vnxe");
}
public StorageSystemValidatorFactory unity() {
return systemFactories.get("unity");
}
/**
* Return the Vplex validator factory.
*
* @return VPlexSystemValidatorFactory instance
*/
public StorageSystemValidatorFactory vplex() {
return systemFactories.get("vplex");
}
@Override
public Validator exportMaskDelete(ExportMaskValidationContext ctx) {
return getSystemValidator(ctx.getStorage()).exportMaskDelete(ctx);
}
@Override
public Validator removeVolumes(ExportMaskValidationContext ctx) {
return getSystemValidator(ctx.getStorage()).removeVolumes(ctx);
}
@Override
public Validator removeInitiators(ExportMaskValidationContext ctx) {
return getSystemValidator(ctx.getStorage()).removeInitiators(ctx);
}
@Override
public Validator deleteVolumes(StorageSystem storage, Collection<Volume> volumes) {
return getSystemValidator(storage).deleteVolumes(storage, volumes);
}
@Override
public List<Volume> volumes(StorageSystem storageSystem, List<Volume> volumes, boolean delete, boolean remediate,
ValCk[] checks) {
return getSystemValidator(storageSystem).volumes(storageSystem, volumes, delete, remediate, checks);
}
@Override
public Validator expandVolumes(StorageSystem storage, Volume volume) {
return getSystemValidator(storage).expandVolumes(storage, volume);
}
@Override
public Validator createSnapshot(StorageSystem storage, BlockSnapshot snapshot, Volume volume) {
return getSystemValidator(storage).createSnapshot(storage, snapshot, volume);
}
@Override
public Validator addVolumes(StorageSystem storage, URI exportMaskURI, Collection<Initiator> initiators) {
return getSystemValidator(storage).addVolumes(storage, exportMaskURI, initiators);
}
@Override
public Validator addInitiators(StorageSystem storage, ExportMask exportMask, Collection<URI> volumeURIList) {
return getSystemValidator(storage).addInitiators(storage, exportMask, volumeURIList);
}
/**
* Returns the appropriate StorageSystemValidatorFactory based on StorageSystem type.
*
* @param system -- StorageSystem object
* @return -- StorageSystemValidatorFactory
*/
private StorageSystemValidatorFactory getSystemValidator(StorageSystem system) {
return systemFactories.get(system.getSystemType());
}
}