package org.ovirt.engine.ui.uicommonweb.models.hosts; import java.util.Objects; import org.ovirt.engine.core.common.action.ChangeVDSClusterParameters; import org.ovirt.engine.core.common.action.ClusterParametersBase; import org.ovirt.engine.core.common.action.StoragePoolManagementParameter; import org.ovirt.engine.core.common.action.StoragePoolParametersBase; import org.ovirt.engine.core.common.action.VdcActionType; import org.ovirt.engine.core.common.action.VdcReturnValueBase; import org.ovirt.engine.core.common.businessentities.StoragePool; import org.ovirt.engine.core.common.businessentities.StoragePoolStatus; import org.ovirt.engine.core.common.businessentities.VDS; import org.ovirt.engine.core.common.businessentities.VDSStatus; import org.ovirt.engine.core.compat.Guid; import org.ovirt.engine.core.compat.StringHelper; import org.ovirt.engine.ui.frontend.AsyncQuery; import org.ovirt.engine.ui.frontend.Frontend; import org.ovirt.engine.ui.uicommonweb.Linq; import org.ovirt.engine.ui.uicommonweb.dataprovider.AsyncDataProvider; import org.ovirt.engine.ui.uicommonweb.models.datacenters.DataCenterModel; import org.ovirt.engine.ui.uicompat.Enlistment; import org.ovirt.engine.ui.uicompat.IEnlistmentNotification; import org.ovirt.engine.ui.uicompat.PreparingEnlistment; @SuppressWarnings("unused") public class AddDataCenterRM extends IEnlistmentNotification { public AddDataCenterRM(String correlationId) { super(correlationId); } @Override public void prepare(PreparingEnlistment enlistment) { context.enlistment = enlistment; // Fetch all necessary data to make code flat. prepare1(); } private void prepare1() { EnlistmentContext enlistmentContext = (EnlistmentContext) context.enlistment.getContext(); HostListModel<?> model = enlistmentContext.getModel(); ConfigureLocalStorageModel configureModel = (ConfigureLocalStorageModel) model.getWindow(); DataCenterModel dataCenterModel = configureModel.getDataCenter(); String dataCenterName = dataCenterModel.getName().getEntity(); if (!StringHelper.isNullOrEmpty(dataCenterName)) { AsyncDataProvider.getInstance().getDataCenterListByName(new AsyncQuery<>( returnValue -> { context.dataCenterFoundByName = Linq.firstOrNull(returnValue); prepare2(); }), dataCenterName); } else { prepare2(); } } private void prepare2() { PreparingEnlistment enlistment = (PreparingEnlistment) context.enlistment; EnlistmentContext enlistmentContext = (EnlistmentContext) enlistment.getContext(); HostListModel<?> model = enlistmentContext.getModel(); ConfigureLocalStorageModel configureModel = (ConfigureLocalStorageModel) model.getWindow(); StoragePool candidate = configureModel.getCandidateDataCenter(); DataCenterModel dataCenterModel = configureModel.getDataCenter(); String dataCenterName = dataCenterModel.getName().getEntity(); if (candidate == null || !Objects.equals(candidate.getName(), dataCenterName)) { // Try to find existing data center with the specified name. StoragePool dataCenter = context.dataCenterFoundByName; if (dataCenter != null) { enlistmentContext.setDataCenterId(dataCenter.getId()); context.enlistment = null; enlistment.prepared(); } else { dataCenter = new StoragePool(); dataCenter.setName(dataCenterName); dataCenter.setdescription(dataCenterModel.getDescription().getEntity()); dataCenter.setComment(dataCenterModel.getComment().getEntity()); dataCenter.setIsLocal(dataCenterModel.getStoragePoolType().getSelectedItem()); dataCenter.setCompatibilityVersion(dataCenterModel.getVersion().getSelectedItem()); StoragePoolManagementParameter parameters = new StoragePoolManagementParameter(dataCenter); parameters.setCorrelationId(getCorrelationId()); Frontend.getInstance().runAction(VdcActionType.AddEmptyStoragePool, parameters, result -> { context.addDataCenterReturnValue = result.getReturnValue(); prepare3(); }); } } else { enlistmentContext.setDataCenterId(configureModel.getDataCenter().getDataCenterId()); context.enlistment = null; enlistment.prepared(); } } private void prepare3() { PreparingEnlistment enlistment = (PreparingEnlistment) context.enlistment; EnlistmentContext enlistmentContext = (EnlistmentContext) enlistment.getContext(); VdcReturnValueBase returnValue = context.addDataCenterReturnValue; context.enlistment = null; if (returnValue != null && returnValue.getSucceeded()) { enlistmentContext.setDataCenterId((Guid) returnValue.getActionReturnValue()); enlistment.prepared(); } else { enlistment.forceRollback(); } } @Override public void commit(Enlistment enlistment) { enlistment.done(); } @Override public void rollback(Enlistment enlistment) { context.enlistment = enlistment; // Fetch all necessary data to make code flat. rollback1(); } public void rollback1() { Enlistment enlistment = context.enlistment; EnlistmentContext enlistmentContext = (EnlistmentContext) enlistment.getContext(); if (enlistmentContext.getDataCenterId() != null) { AsyncDataProvider.getInstance().getDataCenterById(new AsyncQuery<>( returnValue -> { context.dataCenterFoundById = returnValue; rollback2(); }), enlistmentContext.getDataCenterId()); } else { rollback3(); } } public void rollback2() { Enlistment enlistment = context.enlistment; EnlistmentContext enlistmentContext = (EnlistmentContext) enlistment.getContext(); HostListModel<?> model = enlistmentContext.getModel(); VDS host = model.getSelectedItem(); // Retrieve host to make sure we have an updated status etc. AsyncDataProvider.getInstance().getHostById(new AsyncQuery<>( returnValue -> { context.hostFoundById = returnValue; rollback3(); }), host.getId()); } public void rollback3() { Enlistment enlistment = context.enlistment; EnlistmentContext enlistmentContext = (EnlistmentContext) enlistment.getContext(); HostListModel<?> model = enlistmentContext.getModel(); VDS host = context.hostFoundById; boolean abort = false; if (model.getSelectedItem() != null) { // Perform rollback only when the host is in maintenance. if (host.getStatus() != VDSStatus.Maintenance) { abort = true; } } else { abort = true; } if (abort) { context.enlistment = null; enlistment.done(); return; } StoragePool dataCenter = context.dataCenterFoundById; // Perform rollback only when the Data Center is un uninitialized. if (dataCenter.getStatus() != StoragePoolStatus.Uninitialized) { context.enlistment = null; enlistment.done(); return; } if (enlistmentContext.getOldClusterId() != null) { // Switch host back to previous cluster. Frontend.getInstance().runAction(VdcActionType.ChangeVDSCluster, new ChangeVDSClusterParameters(enlistmentContext.getOldClusterId(), host.getId()), result -> { VdcReturnValueBase returnValue = result.getReturnValue(); context.changeVDSClusterReturnValue = returnValue; rollback4(); }); } else { context.enlistment = null; enlistment.done(); } } private void rollback4() { Enlistment enlistment = context.enlistment; EnlistmentContext enlistmentContext = (EnlistmentContext) enlistment.getContext(); VdcReturnValueBase returnValue = context.changeVDSClusterReturnValue; if (returnValue != null && returnValue.getSucceeded()) { // Remove cluster. if (enlistmentContext.getClusterId() != null) { Frontend.getInstance().runAction(VdcActionType.RemoveCluster, new ClusterParametersBase(enlistmentContext.getClusterId()), result -> rollback5()); } } else { context.enlistment = null; enlistment.done(); } } private void rollback5() { Enlistment enlistment = context.enlistment; EnlistmentContext enlistmentContext = (EnlistmentContext) enlistment.getContext(); // Try to remove data center. if (enlistmentContext.getDataCenterId() != null) { Frontend.getInstance().runAction(VdcActionType.RemoveStoragePool, new StoragePoolParametersBase(enlistmentContext.getDataCenterId())); } // Call done, no matter whether the data center deletion was successful. context.enlistment = null; enlistment.done(); } private final Context context = new Context(); public static final class Context { public Enlistment enlistment; public StoragePool dataCenterFoundByName; public StoragePool dataCenterFoundById; public VDS hostFoundById; public VdcReturnValueBase addDataCenterReturnValue; public VdcReturnValueBase changeVDSClusterReturnValue; } }