package org.ovirt.engine.core.bll.storage;
import static org.ovirt.engine.core.bll.MultiLevelAdministrationHandler.SYSTEM_OBJECT_ID;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.ovirt.engine.core.bll.Backend;
import org.ovirt.engine.core.common.AuditLogType;
import org.ovirt.engine.core.common.VdcObjectType;
import org.ovirt.engine.core.common.action.StorageDomainManagementParameter;
import org.ovirt.engine.core.common.businessentities.SANState;
import org.ovirt.engine.core.common.businessentities.StorageDomainType;
import org.ovirt.engine.core.common.businessentities.StorageFormatType;
import org.ovirt.engine.core.common.businessentities.StorageType;
import org.ovirt.engine.core.common.businessentities.storage_domain_dynamic;
import org.ovirt.engine.core.common.businessentities.storage_domain_static;
import org.ovirt.engine.core.common.businessentities.storage_domains;
import org.ovirt.engine.core.common.validation.group.CreateEntity;
import org.ovirt.engine.core.common.vdscommands.CreateStorageDomainVDSCommandParameters;
import org.ovirt.engine.core.common.vdscommands.GetStorageDomainStatsVDSCommandParameters;
import org.ovirt.engine.core.common.vdscommands.HSMGetStorageDomainInfoVDSCommandParameters;
import org.ovirt.engine.core.common.vdscommands.HSMGetStorageDomainsListVDSCommandParameters;
import org.ovirt.engine.core.common.vdscommands.VDSCommandType;
import org.ovirt.engine.core.compat.Guid;
import org.ovirt.engine.core.dal.VdcBllMessages;
import org.ovirt.engine.core.dal.dbbroker.DbFacade;
import org.ovirt.engine.core.utils.Pair;
import org.ovirt.engine.core.utils.transaction.TransactionMethod;
import org.ovirt.engine.core.utils.transaction.TransactionSupport;
public abstract class AddStorageDomainCommand<T extends StorageDomainManagementParameter> extends
StorageDomainManagementCommandBase<T> {
public AddStorageDomainCommand(T parameters) {
super(parameters);
setVdsId(parameters.getVdsId());
}
/**
* Constructor for command creation when compensation is applied on startup
*
* @param commandId
*/
protected AddStorageDomainCommand(Guid commandId) {
super(commandId);
}
protected void InitializeStorageDomain() {
getStorageDomain().setid(Guid.NewGuid());
}
protected boolean AddStorageDomainInIrs() {
// No need to run in separate transaction - counting on rollback of external transaction wrapping the command
return Backend
.getInstance()
.getResourceManager()
.RunVdsCommand(
VDSCommandType.CreateStorageDomain,
new CreateStorageDomainVDSCommandParameters(getVds().getvds_id(), getStorageDomain()
.getStorageStaticData(), getStorageArgs())).getSucceeded();
}
protected void AddStorageDomainInDb() {
TransactionSupport.executeInNewTransaction(new TransactionMethod<Void>() {
@Override
public Void runInTransaction() {
DbFacade.getInstance().getStorageDomainStaticDAO().save(getStorageDomain().getStorageStaticData());
getCompensationContext().snapshotNewEntity(getStorageDomain().getStorageStaticData());
storage_domain_dynamic newStorageDynamic =
new storage_domain_dynamic(null, getStorageDomain().getid(), null);
getReturnValue().setActionReturnValue(getStorageDomain().getid());
DbFacade.getInstance().getStorageDomainDynamicDAO().save(newStorageDynamic);
getCompensationContext().snapshotNewEntity(newStorageDynamic);
getCompensationContext().stateChanged();
return null;
}
});
}
protected void UpdateStorageDomainDynamicFromIrs() {
final storage_domains sd =
(storage_domains) Backend
.getInstance()
.getResourceManager()
.RunVdsCommand(VDSCommandType.GetStorageDomainStats,
new GetStorageDomainStatsVDSCommandParameters(getVds().getvds_id(),
getStorageDomain().getid()))
.getReturnValue();
TransactionSupport.executeInNewTransaction(new TransactionMethod<Void>() {
@Override
public Void runInTransaction() {
getCompensationContext().snapshotEntity(getStorageDomain().getStorageDynamicData());
DbFacade.getInstance().getStorageDomainDynamicDAO().update(sd.getStorageDynamicData());
getCompensationContext().stateChanged();
return null;
}
});
}
@Override
protected void executeCommand() {
InitializeStorageDomain();
AddStorageDomainInDb();
if (AddStorageDomainInIrs()) {
UpdateStorageDomainDynamicFromIrs();
setSucceeded(true);
}
}
@Override
public AuditLogType getAuditLogTypeValue() {
return getSucceeded() ? AuditLogType.USER_ADD_STORAGE_DOMAIN : AuditLogType.USER_ADD_STORAGE_DOMAIN_FAILED;
}
@Override
protected boolean canDoAction() {
addCanDoActionMessage(VdcBllMessages.VAR__ACTION__ADD);
boolean returnValue = super.canDoAction() && InitializeVds() && CheckStorageDomainNameLengthValid();
if (returnValue && IsStorageWithSameNameExists()) {
addCanDoActionMessage(VdcBllMessages.ACTION_TYPE_FAILED_STORAGE_DOMAIN_NAME_ALREADY_EXIST);
returnValue = false;
}
if (returnValue && getStorageDomain().getstorage_domain_type() == StorageDomainType.ISO
&& getStorageDomain().getstorage_type() != StorageType.NFS) {
addCanDoActionMessage(VdcBllMessages.ACTION_TYPE_FAILED_STORAGE_DOMAIN_TYPE_ILLEGAL);
returnValue = false;
}
if (returnValue && getStorageDomain().getstorage_domain_type() == StorageDomainType.ImportExport
&& getStorageDomain().getstorage_type() == StorageType.LOCALFS) {
addCanDoActionMessage(VdcBllMessages.ACTION_TYPE_FAILED_STORAGE_DOMAIN_TYPE_ILLEGAL);
returnValue = false;
}
if (returnValue && getStorageDomain().getstorage_domain_type() == StorageDomainType.Master) {
addCanDoActionMessage(VdcBllMessages.ACTION_TYPE_FAILED_STORAGE_DOMAIN_TYPE_ILLEGAL);
returnValue = false;
}
if (returnValue && !correctStorageDomainFormat()) {
addCanDoActionMessage(VdcBllMessages.ACTION_TYPE_FAILED_STORAGE_DOMAIN_FORMAT_ILLEGAL_HOST);
getReturnValue().getCanDoActionMessages().add(
String.format("$storageFormat %1$s", getStorageDomain().getStorageFormat().toString()));
returnValue = false;
}
return returnValue && CanAddDomain();
}
private boolean correctStorageDomainFormat() {
Set<StorageFormatType> supportedStorageFormats =
getSupportedStorageFormatSet(getVds().getvds_group_compatibility_version());
if (!supportedStorageFormats.contains(getStorageDomain().getStorageFormat())
|| (getStorageDomain().getStorageFormat() != StorageFormatType.V1 &&
(getStorageDomain().getstorage_type() == StorageType.NFS
|| getStorageDomain().getstorage_type() == StorageType.LOCALFS || getStorageDomain().getstorage_domain_type() == StorageDomainType.ImportExport))) {
return false;
}
return true;
}
protected boolean CheckExistingStorageDomain() {
boolean returnValue = true;
// prevent importing DATA domain
if (getParameters().getStorageDomain().getstorage_domain_type() == StorageDomainType.Data) {
addCanDoActionMessage(VdcBllMessages.ACTION_TYPE_FAILED_IMPORT_DATA_DOMAIN_PROHIBITED);
return false;
}
if (DbFacade.getInstance().getStorageDomainStaticDAO().get(getStorageDomain().getid()) != null) {
addCanDoActionMessage(VdcBllMessages.ACTION_TYPE_FAILED_STORAGE_DOMAIN_NOT_EXIST);
returnValue = false;
}
if (returnValue) {
java.util.ArrayList<Guid> storageIds = (java.util.ArrayList<Guid>) Backend
.getInstance()
.getResourceManager()
.RunVdsCommand(
VDSCommandType.HSMGetStorageDomainsList,
new HSMGetStorageDomainsListVDSCommandParameters(getVdsId(), Guid.Empty, getStorageDomain()
.getstorage_type(), getStorageDomain().getstorage_domain_type(), ""))
.getReturnValue();
if (!storageIds.contains(getStorageDomain().getid())) {
addCanDoActionMessage(VdcBllMessages.ACTION_TYPE_FAILED_STORAGE_DOMAIN_ALREADY_EXIST);
returnValue = false;
} else {
Pair<storage_domain_static, SANState> domainFromIrs =
(Pair<storage_domain_static, SANState>) Backend
.getInstance()
.getResourceManager()
.RunVdsCommand(VDSCommandType.HSMGetStorageDomainInfo,
new HSMGetStorageDomainInfoVDSCommandParameters(getVdsId(),
getStorageDomain().getid()))
.getReturnValue();
if (domainFromIrs != null
&& domainFromIrs.getFirst().getstorage_domain_type() != getStorageDomain().getstorage_domain_type()) {
addCanDoActionMessage(VdcBllMessages.ACTION_TYPE_FAILED_CANNOT_CHANGE_STORAGE_DOMAIN_TYPE);
returnValue = false;
}
returnValue = returnValue && ConcreteCheckExistingStorageDomain(domainFromIrs);
}
}
return returnValue;
}
protected boolean ConcreteCheckExistingStorageDomain(Pair<storage_domain_static, SANState> domainFromIrs) {
return true;
}
protected String getStorageArgs() {
return getStorageDomain().getstorage();
}
protected abstract boolean CanAddDomain();
@Override
public Map<Guid, VdcObjectType> getPermissionCheckSubjects() {
return Collections.singletonMap(SYSTEM_OBJECT_ID, VdcObjectType.System);
}
@Override
protected List<Class<?>> getValidationGroups() {
addValidationGroup(CreateEntity.class);
return super.getValidationGroups();
}
}