package org.ovirt.engine.core.bll.storage.connection; import java.util.Collections; import java.util.List; import java.util.Map; import javax.inject.Inject; import org.apache.commons.lang.StringUtils; import org.ovirt.engine.core.bll.InternalCommandAttribute; import org.ovirt.engine.core.bll.LockMessagesMatchUtil; import org.ovirt.engine.core.bll.context.CommandContext; import org.ovirt.engine.core.common.action.LockProperties; import org.ovirt.engine.core.common.action.LockProperties.Scope; import org.ovirt.engine.core.common.action.StorageServerConnectionParametersBase; import org.ovirt.engine.core.common.businessentities.StorageServerConnections; import org.ovirt.engine.core.common.businessentities.VDSStatus; import org.ovirt.engine.core.common.errors.EngineError; import org.ovirt.engine.core.common.errors.EngineException; import org.ovirt.engine.core.common.errors.EngineMessage; import org.ovirt.engine.core.common.locks.LockingGroup; import org.ovirt.engine.core.common.utils.Pair; import org.ovirt.engine.core.common.validation.group.CreateEntity; import org.ovirt.engine.core.compat.Guid; import org.ovirt.engine.core.dao.StorageServerConnectionDao; @InternalCommandAttribute public class AddStorageServerConnectionCommand<T extends StorageServerConnectionParametersBase> extends ConnectStorageToVdsCommand<T> { @Inject private StorageServerConnectionDao storageServerConnectionDao; public AddStorageServerConnectionCommand(T parameters, CommandContext cmdContext) { super(parameters, cmdContext); } @Override protected LockProperties applyLockProperties(LockProperties lockProperties) { return lockProperties.withScope(Scope.Execution); } @Override protected void executeCommand() { // Attempt to connect only if a host is given. // If not, just save the connection to the database if (!Guid.isNullOrEmpty(getParameters().getVdsId())) { Pair<Boolean, Integer> result = connectHostToStorage(); boolean isValidConnection = result.getFirst(); // Process failure if (!isValidConnection) { throw new EngineException(EngineError.forValue(result.getSecond())); } } StorageServerConnections connection = getConnection(); connection.setId(Guid.newGuid().toString()); saveConnection(connection); getReturnValue().setActionReturnValue(connection.getId()); setSucceeded(true); } protected StorageServerConnections getConnectionFromDbById(String connectionId) { return storageServerConnectionDao.get(connectionId); } protected void saveConnection(StorageServerConnections connection) { storageServerConnectionDao.save(connection); } @Override protected boolean validate() { StorageServerConnections paramConnection = getConnection(); // if an id was sent - it's not ok since only the backend should allocate ids if (StringUtils.isNotEmpty(paramConnection.getId())) { return failValidation(EngineMessage.ACTION_TYPE_FAILED_STORAGE_CONNECTION_ID_NOT_EMPTY); } if (!isValidConnection(paramConnection)) { return false; } Guid storagePoolId = Guid.isNullOrEmpty(getParameters().getVdsId()) ? null : getVds().getStoragePoolId(); if (isConnWithSameDetailsExists(paramConnection, storagePoolId)) { return failValidation(EngineMessage.ACTION_TYPE_FAILED_STORAGE_CONNECTION_ALREADY_EXISTS); } // If a Guid is not supplied, we won't attempt to [dis]connect. // If one is supplied, [dis]connecting will be attempted, so we need to // validate that it's a valid VDS ID and that the VDS is up. if (!Guid.isNullOrEmpty(getParameters().getVdsId())) { if (getVds() == null) { return failValidation(EngineMessage.VDS_INVALID_SERVER_ID); } if (getVds().getStatus() != VDSStatus.Up) { return failValidation(EngineMessage.VDS_ADD_STORAGE_SERVER_STATUS_MUST_BE_UP); } } return true; } @Override protected List<Class<?>> getValidationGroups() { addValidationGroup(CreateEntity.class); return super.getValidationGroups(); } @Override protected Map<String, Pair<String, String>> getExclusiveLocks() { if (getConnection().getStorageType().isFileDomain()) { // lock the path to NFS to avoid at the same time if some other user tries to: // add new storage domain to same path or edit another storage server connection to point to same path return Collections.singletonMap(getParameters().getStorageServerConnection().getConnection(), LockMessagesMatchUtil.makeLockingPair(LockingGroup.STORAGE_CONNECTION, EngineMessage.ACTION_TYPE_FAILED_OBJECT_LOCKED)); } else { // lock target details return Collections.singletonMap(getConnection().getConnection() + ";" + getConnection().getIqn() + ";" + getConnection().getPort() + ";" + getConnection().getUserName(), LockMessagesMatchUtil.makeLockingPair(LockingGroup.STORAGE_CONNECTION, EngineMessage.ACTION_TYPE_FAILED_OBJECT_LOCKED)); } } @Override protected void setActionMessageParameters() { addValidationMessage(EngineMessage.VAR__ACTION__ADD); addValidationMessage(EngineMessage.VAR__TYPE__STORAGE__CONNECTION); } }