/*
* Copyright (c) 2008-2013 EMC Corporation
* All Rights Reserved
*/
package com.emc.storageos.api.service.impl.resource.utils.vpoolvalidators;
import java.net.URI;
import com.emc.storageos.api.service.impl.resource.ArgValidator;
import com.emc.storageos.api.service.impl.resource.utils.VirtualPoolValidator;
import com.emc.storageos.db.client.DbClient;
import com.emc.storageos.db.client.model.StringSet;
import com.emc.storageos.db.client.model.VirtualArray;
import com.emc.storageos.db.client.model.VirtualPool;
import com.emc.storageos.db.client.util.NullColumnValueGetter;
import com.emc.storageos.model.vpool.BlockVirtualPoolParam;
import com.emc.storageos.model.vpool.BlockVirtualPoolUpdateParam;
import com.emc.storageos.model.vpool.VirtualPoolHighAvailabilityParam;
import com.emc.storageos.svcs.errorhandling.resources.APIException;
public class HighAvailabilityValidator extends VirtualPoolValidator<BlockVirtualPoolParam, BlockVirtualPoolUpdateParam> {
@Override
public void setNextValidator(VirtualPoolValidator validator) {
_nextValidator = validator;
}
@Override
protected void validateVirtualPoolUpdateAttributeValue(
VirtualPool virtualPool, BlockVirtualPoolUpdateParam updateParam, DbClient dbClient) {
validateHighAvailabilityTypeForUpdate(virtualPool, updateParam);
validateDistributedHighAvailabilityForUpdate(virtualPool, updateParam, dbClient);
validateVplexHANotSRDFProtected(updateParam.getHighAvailability(), dbClient);
}
@Override
protected boolean isUpdateAttributeOn(BlockVirtualPoolUpdateParam updateParam) {
if (null != updateParam && updateParam.getHighAvailability() != null) {
return true;
}
return false;
}
@Override
protected void validateVirtualPoolCreateAttributeValue(BlockVirtualPoolParam createParam, DbClient dbClient) {
/*
* Validations similar to the update ones in this class are currently defined
* in the BlockVirtualPoolService.createBlockVirtualPool() - for create. These
* should be moved over here. Validations for mixed protection are done in the
* ProtectionValidator so no need to have them in this class.
*/
validateVplexHANotSRDFProtected(createParam.getHighAvailability(), dbClient);
}
/**
* Validates that the high availability type is one of the required
* values.
*
* @param virtualPool The virtual pool being updated
* @param updateParam The paramater containing the updates
*/
public void validateHighAvailabilityTypeForUpdate(
VirtualPool virtualPool, BlockVirtualPoolUpdateParam updateParam) {
// If the type is null high availability is attempting to be removed so skip the validation.
if (updateParam.getHighAvailability().getType() != null) {
final boolean condition = updateParam.specifiesHighAvailability();
if (!condition) {
throw APIException.badRequests.invalidParameterHighAvailabilityType(updateParam.getHighAvailability().getType());
}
}
}
/**
* Validates high availability on a block virtual pool update.
*
* @param virtualPool The virtual pool being updated
* @param updateParam The parameter containing the updates
* @param dbClient The dbclient
*/
public void validateDistributedHighAvailabilityForUpdate(
VirtualPool virtualPool, BlockVirtualPoolUpdateParam updateParam, DbClient dbClient) {
// If the high availability type is distributed, then the user must also specify the high
// availability varray. The user may also specify the high availability VirtualPool.
if (VirtualPool.HighAvailabilityType.vplex_distributed.name().equals(
updateParam.getHighAvailability().getType())) {
if ((updateParam.getHighAvailability().getHaVirtualArrayVirtualPool() == null)
|| updateParam.getHighAvailability().getHaVirtualArrayVirtualPool().getVirtualArray() == null
|| String.valueOf(updateParam.getHighAvailability().getHaVirtualArrayVirtualPool().getVirtualArray()).isEmpty()) {
throw APIException.badRequests.invalidParameterHighAvailabilityVirtualArrayRequiredForType(updateParam
.getHighAvailability().getType());
}
// High availability varray must be specified and valid.
_logger.debug("HA varray VirtualPool map specifies the HA varray {}",
updateParam.getHighAvailability().getHaVirtualArrayVirtualPool().getVirtualArray());
VirtualArray haVirtualArray = dbClient.queryObject(VirtualArray.class,
updateParam.getHighAvailability().getHaVirtualArrayVirtualPool().getVirtualArray());
ArgValidator.checkEntity(haVirtualArray,
updateParam.getHighAvailability().getHaVirtualArrayVirtualPool().getVirtualArray(), false);
String haVirtualArrayId = updateParam.getHighAvailability().getHaVirtualArrayVirtualPool().getVirtualArray()
.toString();
// Check the HA varray VirtualPool, which is not required.
String haNhVirtualPoolId = null;
if (updateParam.getHighAvailability().getHaVirtualArrayVirtualPool().getVirtualPool() != null &&
!String.valueOf(updateParam.getHighAvailability().getHaVirtualArrayVirtualPool().getVirtualPool()).isEmpty()) {
_logger.debug("HA varray VirtualPool map specifies the HA vpool {}",
updateParam.getHighAvailability().getHaVirtualArrayVirtualPool().getVirtualPool());
VirtualPool haVirtualPool = dbClient.queryObject(VirtualPool.class,
updateParam.getHighAvailability().getHaVirtualArrayVirtualPool().getVirtualPool());
ArgValidator.checkEntity(haVirtualPool,
updateParam.getHighAvailability().getHaVirtualArrayVirtualPool().getVirtualPool(), false);
haNhVirtualPoolId = updateParam.getHighAvailability().getHaVirtualArrayVirtualPool().getVirtualPool()
.toString();
// Further validate that this VirtualPool is valid for the
// specified high availability varray.
StringSet haVirtualPoolNHs = haVirtualPool.getVirtualArrays();
if ((haVirtualPoolNHs != null) && (!haVirtualPoolNHs.isEmpty())) {
if (!haVirtualPoolNHs.contains(haVirtualArrayId)) {
throw APIException.badRequests.invalidParameterHighAvailabilityVirtualPoolNotValidForVirtualArray(
haNhVirtualPoolId, haVirtualArrayId);
}
}
}
} else if (updateParam.getHighAvailability().getType() != null
&& !String.valueOf(updateParam.getHighAvailability().getType()).isEmpty()) {
if (updateParam.getHighAvailability().getHaVirtualArrayVirtualPool() != null
&& (updateParam.getHighAvailability().getHaVirtualArrayVirtualPool().getVirtualArray() != null
&& !String.valueOf(updateParam.getHighAvailability().getHaVirtualArrayVirtualPool().getVirtualArray()).isEmpty())) {
throw APIException.badRequests.invalidParameterVirtualArrayAndVirtualPoolDoNotApplyForType(updateParam
.getHighAvailability().getType());
}
}
}
@Override
protected boolean isCreateAttributeOn(BlockVirtualPoolParam createParam) {
if (null != createParam && createParam.getHighAvailability() != null) {
return true;
}
return false;
}
private void validateVplexHANotSRDFProtected(VirtualPoolHighAvailabilityParam haParam, DbClient dbClient) {
if (haParam == null) {
return;
}
if (haParam.getHaVirtualArrayVirtualPool() != null) {
// Look up the high availability virtual pool.
URI haVpoolURI = haParam.getHaVirtualArrayVirtualPool().getVirtualPool();
if (!NullColumnValueGetter.isNullURI(haVpoolURI)) {
VirtualPool haVpool = dbClient.queryObject(VirtualPool.class, haVpoolURI);
if (VirtualPool.vPoolSpecifiesSRDF(haVpool)) {
throw APIException.badRequests.srdfNotSupportedOnHighAvailabilityVpool();
}
}
}
}
}