package org.ovirt.engine.ui.uicommonweb.action; import java.util.ArrayList; import java.util.Collection; import org.ovirt.engine.core.common.action.VdcActionParametersBase; import org.ovirt.engine.core.common.action.VdcActionType; import org.ovirt.engine.core.common.action.VdcReturnValueBase; import org.ovirt.engine.ui.frontend.Frontend; import org.ovirt.engine.ui.uicommonweb.models.Model; import org.ovirt.engine.ui.uicompat.IFrontendMultipleActionAsyncCallback; /** * This class represents an action that runs multiple vdcActions * <code>Frontend.getInstance().runMultipleAction(..)</code>. * * The next action will be executed just after the multiple action's result is returned. A parallel action will be * invoked at the same time as this action. * * For example- * <code>actionA.then(actionB).and(actionC).and(actionD).then(actionE).and(actionF).onAllExecutionsFinish(actionG)</code> * <code>actionA.runAction()</code> * * Since the vdc actions are asynchronous the flow will be the following- * 1. actionA will execute a multiple vdcAction. * 2. actionB, actionC and actionD will be executed in a parallel manner just after the result of actionA is returned. * 3. actionE/F will be executed parallely after actionD's result is returned. * 4. actionG is the <code>final</code>, it will be executed just after the result of all the action's in the flow was returned. * * actionA->actionB ->actionC ->actionD->actionE ->actionF ->actionG * * The failures are collected and displayed after finishing the execution of the flow. */ public class UiVdcMultipleAction extends UiAction { private VdcActionType actionType; private Collection<? extends VdcActionParametersBase> parameterCollection; boolean waitForResult; boolean runNextInCaseOfError; /** * @param actionType * the <code>VdsActionType</code> * @param parameterCollection * the parameters of the multiple actions * @param model * model the model on which to start and stop the progress. * @param waitForResult * a flag to return the result after running the whole action and not just the can do actions. * @param runNextInCaseOfError * whether the next action should be executed in case the current action has an error. */ public UiVdcMultipleAction(VdcActionType actionType, Collection<? extends VdcActionParametersBase> parameterCollection, Model model, boolean waitForResult, boolean runNextInCaseOfError) { super(model); this.actionType = actionType; this.parameterCollection = parameterCollection; this.waitForResult = waitForResult; this.runNextInCaseOfError = runNextInCaseOfError; } public UiVdcMultipleAction(VdcActionType actionType, Collection<? extends VdcActionParametersBase> parametersList, Model model) { this(actionType, parametersList, model, false, true); } @Override void internalRunAction() { Frontend.getInstance().runMultipleAction(actionType, new ArrayList<>(parameterCollection), createCallback(), false, waitForResult); } private IFrontendMultipleActionAsyncCallback createCallback() { return result -> { boolean hasError = false; for (VdcReturnValueBase singleResult : result.getReturnValue()) { if (!singleResult.isValid() || (waitForResult && !singleResult.getSucceeded())) { hasError = true; getActionFlowState().addFailure(actionType, singleResult); } } if (hasError && !runNextInCaseOfError) { then(null); } runNextAction(); }; } @Override protected boolean shouldExecute() { return super.shouldExecute() && parameterCollection != null && !parameterCollection.isEmpty(); } }