package org.ovirt.engine.ui.uicommonweb.action; 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.IFrontendActionAsyncCallback; /** * This class represents an action that runs a single vdcAction <code>Frontend.getInstance().runAction(..)</code>. * * An example for using the class- * <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 vdcAction. * 2. actionB, actionC and actionD will be executed in a parallel manner (will be sent to the server without waiting for each other's results) * 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 results of all the actions in the flow was returned. * * actionA->actionB * ->actionC * ->actionD->actionE * ->actionF * ->actionG * * In case of failures- * 1. If actionA fails- all the other action won't be executed (since they are dependent on its result). * 2. If actionB/C fails- actionG won't be executed, since it is the final action and is executed just if all the previous actions in the flow were executed. * All the other actions won't be affected since they are not dependent on actionB/C. * 3. If actionD fails actionE/F/G won't be executed. * 4. If actionE/F fails- actionG won't be executed. */ public class UiVdcAction extends UiAction { private VdcActionType actionType; private VdcActionParametersBase parameters; private boolean showErrorDialogOnFirstFailure; /** * @param actionType * the <code>VdsActionType</code> * @param parameters * the parameters of the action * @param model * model the model on which to start and stop the progress. * @param showErrorDialog * if true, in case of a error, the error dialog will be displayed immediately. Otherwise, the error will * be collected and displayed with all the other errors at the end of the flow. */ public UiVdcAction(VdcActionType actionType, VdcActionParametersBase parameters, Model model, boolean showErrorDialogOnFirstFailure) { super(model); this.actionType = actionType; this.parameters = parameters; this.showErrorDialogOnFirstFailure = showErrorDialogOnFirstFailure; } public UiVdcAction(VdcActionType actionType, VdcActionParametersBase parameters, Model model) { this(actionType, parameters, model, false); } @Override void internalRunAction() { IFrontendActionAsyncCallback callback = createCallback(); Frontend.getInstance().runAction(actionType, parameters, callback, showErrorDialogOnFirstFailure); } private IFrontendActionAsyncCallback createCallback() { return result -> { VdcReturnValueBase returnValue = result.getReturnValue(); if (returnValue == null || !returnValue.getSucceeded()) { if (!showErrorDialogOnFirstFailure && returnValue != null) { getActionFlowState().addFailure(actionType, returnValue); } // Reset the next action then(null); } runNextAction(); }; } }