Tomas Jelinek has uploaded a new change for review. Change subject: webadmin: Edit pool hangs when the pool has no VMs (#852297) ......................................................................
webadmin: Edit pool hangs when the pool has no VMs (#852297) https://bugzilla.redhat.com/852297 When the pool has no VMs, it makes no sense to have the pool itself. This patch adds a behavior, that when the user detaches all the VMs from the pool, show a message to the user, and when the user approves this operation, it deletes the pool itself. This patch also enriches the GenericApiGWTService by adding a method RunMultipleActionsSynchronously which does the same as the RunMultipleActions, but waits until the actions finishes and than returns the result to the caller. Change-Id: I3b8f47e6dd5ce8149ba78c7c25455997b3bf62eb Signed-off-by: Tomas Jelinek <tjeli...@redhat.com> --- M frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/Frontend.java A frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/RunMultipleActionsCallback.java M frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/gwtservices/GenericApiGWTService.java M frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/server/gwt/GenericApiGWTServiceImpl.java M frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/pools/PoolListModel.java M frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/pools/PoolVmListModel.java M frontend/webadmin/modules/uicompat/src/main/java/org/ovirt/engine/ui/uicompat/Constants.java M frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/gin/uicommon/PoolModule.java 8 files changed, 194 insertions(+), 78 deletions(-) git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/83/7583/1 diff --git a/frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/Frontend.java b/frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/Frontend.java index 67aa2e2..bd4f10d 100644 --- a/frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/Frontend.java +++ b/frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/Frontend.java @@ -27,7 +27,6 @@ import org.ovirt.engine.ui.frontend.gwtservices.GenericApiGWTServiceAsync; import org.ovirt.engine.ui.uicompat.ConstantsManager; import org.ovirt.engine.ui.uicompat.FrontendActionAsyncResult; -import org.ovirt.engine.ui.uicompat.FrontendMultipleActionAsyncResult; import org.ovirt.engine.ui.uicompat.FrontendMultipleQueryAsyncResult; import org.ovirt.engine.ui.uicompat.FrontendQueryAsyncResult; import org.ovirt.engine.ui.uicompat.IAsyncCallback; @@ -83,7 +82,7 @@ Frontend.eventsHandler = eventHandler; } - private static void translateErrors(List<VdcReturnValueBase> errors) { + static void translateErrors(List<VdcReturnValueBase> errors) { for (VdcReturnValueBase retVal : errors) { retVal.setCanDoActionMessages(canDoActionErrorsTranslator.translateErrorText(retVal.getCanDoActionMessages())); } @@ -93,14 +92,16 @@ failureEventHandler(null, errorMessage); } - private static void failureEventHandler(Throwable caught) { + static void failureEventHandler(Throwable caught) { String errorMessage; if (caught instanceof StatusCodeException) { errorMessage = - ConstantsManager.getInstance().getConstants().requestToServerFailedWithCode()+": " //$NON-NLS-1$ + ConstantsManager.getInstance().getConstants().requestToServerFailedWithCode() + ": " //$NON-NLS-1$ + ((StatusCodeException) caught).getStatusCode(); } else { - errorMessage = ConstantsManager.getInstance().getConstants().requestToServerFailed() +": " + caught.getLocalizedMessage(); //$NON-NLS-1$ + errorMessage = + ConstantsManager.getInstance().getConstants().requestToServerFailed() + + ": " + caught.getLocalizedMessage(); //$NON-NLS-1$ } failureEventHandler(errorMessage); } @@ -495,40 +496,23 @@ final Object state) { GenericApiGWTServiceAsync service = GenericApiGWTServiceAsync.Util.getInstance(); - service.RunMultipleActions(actionType, parameters, new AsyncCallback<ArrayList<VdcReturnValueBase>>() { - @Override - public void onFailure(Throwable caught) { - logger.log(Level.SEVERE, "Failed to execute RunAction: " + caught, caught); //$NON-NLS-1$ - failureEventHandler(caught); + service.RunMultipleActions(actionType, parameters, new RunMultipleActionsCallback(actionType, + parameters, + callback, + state)); + } - if (callback != null) { - callback.Executed(new FrontendMultipleActionAsyncResult(actionType, parameters, null, state)); - } - } + public static void RunMultipleActionsSynchronously(final VdcActionType actionType, + final ArrayList<VdcActionParametersBase> parameters, + final IFrontendMultipleActionAsyncCallback callback, + final Object state) { - @Override - public void onSuccess(ArrayList<VdcReturnValueBase> result) { - logger.finer("Frontend: sucessfully executed RunAction, determining result!"); //$NON-NLS-1$ + GenericApiGWTServiceAsync service = GenericApiGWTServiceAsync.Util.getInstance(); - ArrayList<VdcReturnValueBase> failed = new ArrayList<VdcReturnValueBase>(); - ArrayList<VdcFault> faults = new ArrayList<VdcFault>(); - - for (VdcReturnValueBase v : result) { - if (!v.getCanDoAction()) { - failed.add(v); - } - } - - if (!failed.isEmpty()) { - translateErrors(failed); - getEventsHandler().runMultipleActionFailed(actionType, failed, faults); - } - - if (callback != null) { - callback.Executed(new FrontendMultipleActionAsyncResult(actionType, parameters, result, state)); - } - } - }); + service.RunMultipleActionsSynchronously(actionType, parameters, new RunMultipleActionsCallback(actionType, + parameters, + callback, + state)); } public static ArrayList<VdcReturnValueBase> RunMultipleAction(VdcActionType actionType, @@ -717,7 +701,7 @@ private static void dumpQueryDetails(VdcQueryType queryType, VdcQueryParametersBase searchParameters) { StringBuffer sb = new StringBuffer(); - sb.append("VdcQuery Type: '" + queryType + "', "); //$NON-NLS-1$//$NON-NLS-2$ + sb.append("VdcQuery Type: '" + queryType + "', "); //$NON-NLS-1$//$NON-NLS-2$ if (searchParameters instanceof SearchParameters) { SearchParameters sp = (SearchParameters) searchParameters; @@ -725,7 +709,7 @@ throw new RuntimeException("Search pattern is defined as 'Not implemented', probably because of a use of String.format()"); //$NON-NLS-1$ } - sb.append("Type value: [" + sp.getSearchTypeValue() + "], Pattern: [" + sp.getSearchPattern() + "]"); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$ + sb.append("Type value: [" + sp.getSearchTypeValue() + "], Pattern: [" + sp.getSearchPattern() + "]"); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$ } else { sb.append("Search type is base or unknown"); //$NON-NLS-1$ } @@ -735,7 +719,7 @@ private static void dumpActionDetails(VdcActionType actionType, VdcActionParametersBase parameters) { StringBuffer sb = new StringBuffer(); - sb.append("actionType Type: '" + actionType + "', "); //$NON-NLS-1$//$NON-NLS-2$ + sb.append("actionType Type: '" + actionType + "', "); //$NON-NLS-1$//$NON-NLS-2$ sb.append("Params: " + parameters); //$NON-NLS-1$ logger.fine(sb.toString()); diff --git a/frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/RunMultipleActionsCallback.java b/frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/RunMultipleActionsCallback.java new file mode 100644 index 0000000..37acea5 --- /dev/null +++ b/frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/RunMultipleActionsCallback.java @@ -0,0 +1,68 @@ +package org.ovirt.engine.ui.frontend; + +import java.util.ArrayList; +import java.util.logging.Level; +import java.util.logging.Logger; + +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.core.common.errors.VdcFault; +import org.ovirt.engine.ui.uicompat.FrontendMultipleActionAsyncResult; +import org.ovirt.engine.ui.uicompat.IFrontendMultipleActionAsyncCallback; + +import com.google.gwt.user.client.rpc.AsyncCallback; + +public class RunMultipleActionsCallback implements AsyncCallback<ArrayList<VdcReturnValueBase>> { + + private static Logger logger = Logger.getLogger(Frontend.class.getName()); + + private final VdcActionType actionType; + private final ArrayList<VdcActionParametersBase> parameters; + private final IFrontendMultipleActionAsyncCallback callback; + private final Object state; + + public RunMultipleActionsCallback( + final VdcActionType actionType, + final ArrayList<VdcActionParametersBase> parameters, + final IFrontendMultipleActionAsyncCallback callback, + final Object state) { + this.actionType = actionType; + this.parameters = parameters; + this.callback = callback; + this.state = state; + } + + @Override + public void onFailure(Throwable caught) { + logger.log(Level.SEVERE, "Failed to execute RunAction: " + caught, caught); //$NON-NLS-1$ + Frontend.failureEventHandler(caught); + + if (callback != null) { + callback.Executed(new FrontendMultipleActionAsyncResult(actionType, parameters, null, state)); + } + } + + @Override + public void onSuccess(ArrayList<VdcReturnValueBase> result) { + logger.finer("Frontend: sucessfully executed RunAction, determining result!"); //$NON-NLS-1$ + + ArrayList<VdcReturnValueBase> failed = new ArrayList<VdcReturnValueBase>(); + ArrayList<VdcFault> faults = new ArrayList<VdcFault>(); + + for (VdcReturnValueBase v : result) { + if (!v.getCanDoAction()) { + failed.add(v); + } + } + + if (!failed.isEmpty()) { + Frontend.translateErrors(failed); + Frontend.getEventsHandler().runMultipleActionFailed(actionType, failed, faults); + } + + if (callback != null) { + callback.Executed(new FrontendMultipleActionAsyncResult(actionType, parameters, result, state)); + } + } +} diff --git a/frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/gwtservices/GenericApiGWTService.java b/frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/gwtservices/GenericApiGWTService.java index 8b988b8..776cf57 100644 --- a/frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/gwtservices/GenericApiGWTService.java +++ b/frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/gwtservices/GenericApiGWTService.java @@ -31,35 +31,13 @@ VdcActionType actionType, ArrayList<VdcActionParametersBase> multipleParams); + public ArrayList<VdcReturnValueBase> RunMultipleActionsSynchronously( + VdcActionType actionType, + ArrayList<VdcActionParametersBase> multipleParams); + public VdcUser getLoggedInUser(); public VdcReturnValueBase logOff(VdcUser userToLogoff); public VdcReturnValueBase Login(String user, String password, String domain); - - // TODO: Should be implemented (most of these methods are required by - // UiCommon) - /* - * public ArrayList<VdcReturnValueBase> RunMultipleActions( VdcActionType actionType, - * ArrayList<VdcActionParametersBase> prms); - * - * public void UnregisterQuery(Guid asyncSearchId); - * - * public Guid RegisterSearch(String searchString, SearchType cluster, int searchPageSize, - * RefObject<ObservableCollection<IVdcQueryable>> tempRefObject); - * - * public VdcUser Login(String entity, String entity2, String selectedItem); - * - * public VdcReturnValueBase RunActionAsyncroniousely( VdcActionType addsanstoragedomain, VdcActionParametersBase - * param); - * - * public Guid RegisterQuery(VdcQueryType getallbookmarks, VdcQueryParametersBase vdcQueryParametersBase, - * RefObject<ObservableCollection<IVdcQueryable>> tempRefObject); - * - * public void Logoff(LogoutUserParameters tempVar); - * - * public boolean getIsUserLoggedIn(); - * - * public VdcUser getLoggedInUser(); - */ } diff --git a/frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/server/gwt/GenericApiGWTServiceImpl.java b/frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/server/gwt/GenericApiGWTServiceImpl.java index 6beec91..44b4acc 100644 --- a/frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/server/gwt/GenericApiGWTServiceImpl.java +++ b/frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/server/gwt/GenericApiGWTServiceImpl.java @@ -104,6 +104,25 @@ return returnValues; } + public ArrayList<VdcReturnValueBase> RunMultipleActionsSynchronously( + VdcActionType actionType, + ArrayList<VdcActionParametersBase> multipleParams) { + + ArrayList<VdcReturnValueBase> ret = new ArrayList<VdcReturnValueBase>(); + + if (multipleParams == null || actionType == null) { + return ret; + } + + String sessionId = getSessionId(); + for (VdcActionParametersBase param : multipleParams) { + param.setSessionId(sessionId); + ret.add(getBackend().RunAction(actionType, param)); + } + + return ret; + } + @Override public VdcReturnValueBase RunAction(VdcActionType actionType, VdcActionParametersBase params) { diff --git a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/pools/PoolListModel.java b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/pools/PoolListModel.java index c64df28..8dc25f4 100644 --- a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/pools/PoolListModel.java +++ b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/pools/PoolListModel.java @@ -753,12 +753,19 @@ private void UpdateActionAvailability() { getEditCommand().setIsExecutionAllowed(getSelectedItem() != null && getSelectedItems() != null - && getSelectedItems().size() == 1); + && getSelectedItems().size() == 1 && hasVms(getSelectedItem())); getRemoveCommand().setIsExecutionAllowed(getSelectedItems() != null && getSelectedItems().size() > 0 && VdcActionUtils.CanExecute(getSelectedItems(), vm_pools.class, VdcActionType.RemoveVmPool)); } + private boolean hasVms(Object selectedItem) { + if (selectedItem instanceof vm_pools) { + return ((vm_pools) selectedItem).getvm_assigned_count() != 0; + } + return false; + } + @Override public void ExecuteCommand(UICommand command) { diff --git a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/pools/PoolVmListModel.java b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/pools/PoolVmListModel.java index 6032c6a..e05d6a4 100644 --- a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/pools/PoolVmListModel.java +++ b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/pools/PoolVmListModel.java @@ -6,6 +6,8 @@ import org.ovirt.engine.core.common.action.RemoveVmFromPoolParameters; 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.core.common.action.VmPoolParametersBase; import org.ovirt.engine.core.common.businessentities.VM; import org.ovirt.engine.core.common.businessentities.VMStatus; import org.ovirt.engine.core.common.businessentities.vm_pools; @@ -21,7 +23,6 @@ import org.ovirt.engine.ui.uicompat.FrontendMultipleActionAsyncResult; import org.ovirt.engine.ui.uicompat.IFrontendMultipleActionAsyncCallback; -@SuppressWarnings("unused") public class PoolVmListModel extends VmListModel { @@ -88,13 +89,13 @@ public void Detach() { - if (getWindow() != null) + if (getConfirmWindow() != null) { return; } ConfirmationModel model = new ConfirmationModel(); - setWindow(model); + setConfirmWindow(model); model.setTitle(ConstantsManager.getInstance().getConstants().detachVirtualMachinesTitle()); model.setHashName("detach_virtual_machine"); //$NON-NLS-1$ @@ -106,6 +107,12 @@ } Collections.sort(list); model.setItems(list); + + if (list.size() == getEntity().getvm_assigned_count()) { + model.getLatch().setIsAvailable(true); + model.getLatch().setIsChangable(true); + model.setNote(ConstantsManager.getInstance().getConstants().detachAllVmsWarning()); + } model.setMessage(ConstantsManager.getInstance() .getConstants() @@ -123,9 +130,11 @@ public void OnDetach() { - ConfirmationModel model = (ConfirmationModel) getWindow(); + ConfirmationModel model = (ConfirmationModel) getConfirmWindow(); - if (model.getProgress() != null) + boolean latchChecked = !model.Validate(); + + if (model.getProgress() != null || latchChecked) { return; } @@ -137,17 +146,52 @@ list.add(new RemoveVmFromPoolParameters(vm.getId())); } + final boolean removeAlsoPool = list.size() == getEntity().getvm_assigned_count(); + model.StartProgress(null); - Frontend.RunMultipleAction(VdcActionType.RemoveVmFromPool, list, + Frontend.RunMultipleActionsSynchronously(VdcActionType.RemoveVmFromPool, list, new IFrontendMultipleActionAsyncCallback() { @Override public void Executed(FrontendMultipleActionAsyncResult result) { + final ConfirmationModel localModel = (ConfirmationModel) result.getState(); - ConfirmationModel localModel = (ConfirmationModel) result.getState(); - localModel.StopProgress(); - Cancel(); + boolean allOk = checkStatuses(result); + if (removeAlsoPool && allOk) { + removePool(localModel); + } else { + localModel.StopProgress(); + Cancel(); + } + + } + + private boolean checkStatuses(FrontendMultipleActionAsyncResult result) { + for (VdcReturnValueBase returnValue : result.getReturnValue()) { + if (!returnValue.getSucceeded()) { + return false; + } + } + + return true; + } + + protected void removePool(final ConfirmationModel localModel) { + ArrayList<VdcActionParametersBase> poolList = new ArrayList<VdcActionParametersBase>(); + poolList.add(new VmPoolParametersBase(getEntity().getvm_pool_id())); + + Frontend.RunMultipleAction(VdcActionType.RemoveVmPool, poolList, + new IFrontendMultipleActionAsyncCallback() { + @Override + public void Executed(FrontendMultipleActionAsyncResult result) { + + ConfirmationModel localModel = (ConfirmationModel) result.getState(); + localModel.StopProgress(); + Cancel(); + + } + }, localModel); } }, model); } diff --git a/frontend/webadmin/modules/uicompat/src/main/java/org/ovirt/engine/ui/uicompat/Constants.java b/frontend/webadmin/modules/uicompat/src/main/java/org/ovirt/engine/ui/uicompat/Constants.java index c826ab6..6ca66a8 100644 --- a/frontend/webadmin/modules/uicompat/src/main/java/org/ovirt/engine/ui/uicompat/Constants.java +++ b/frontend/webadmin/modules/uicompat/src/main/java/org/ovirt/engine/ui/uicompat/Constants.java @@ -188,6 +188,9 @@ @DefaultStringValue("Detach Virtual Machine(s)") String detachVirtualMachinesTitle(); + @DefaultStringValue("You chose to detach all VMs from the pool - this will remove the pool itself.") + String detachAllVmsWarning(); + @DefaultStringValue("Permissions") String permissionsTitle(); diff --git a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/gin/uicommon/PoolModule.java b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/gin/uicommon/PoolModule.java index 977cc3b..5b016ac 100644 --- a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/gin/uicommon/PoolModule.java +++ b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/gin/uicommon/PoolModule.java @@ -106,10 +106,23 @@ @Provides @Singleton - public SearchableDetailModelProvider<VM, PoolListModel, PoolVmListModel> getPoolVmListProvider(ClientGinjector ginjector) { - return new SearchableDetailTabModelProvider<VM, PoolListModel, PoolVmListModel>(ginjector, + public SearchableDetailModelProvider<VM, PoolListModel, PoolVmListModel> getPoolVmListProvider( + ClientGinjector ginjector, + final Provider<RemoveConfirmationPopupPresenterWidget> removeConfirmPopupProvider) { + return new SearchableDetailTabModelProvider<VM, PoolListModel, PoolVmListModel>( + ginjector, PoolListModel.class, - PoolVmListModel.class); + PoolVmListModel.class) { + @Override + public AbstractModelBoundPopupPresenterWidget<? extends ConfirmationModel, ?> getConfirmModelPopup(PoolVmListModel source, + UICommand lastExecutedCommand) { + if (lastExecutedCommand == getModel().getDetachCommand()) { + return removeConfirmPopupProvider.get(); + } else { + return super.getConfirmModelPopup(source, lastExecutedCommand); + } + } + }; } @Override -- To view, visit http://gerrit.ovirt.org/7583 To unsubscribe, visit http://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I3b8f47e6dd5ce8149ba78c7c25455997b3bf62eb Gerrit-PatchSet: 1 Gerrit-Project: ovirt-engine Gerrit-Branch: master Gerrit-Owner: Tomas Jelinek <tjeli...@redhat.com> _______________________________________________ Engine-patches mailing list Engine-patches@ovirt.org http://lists.ovirt.org/mailman/listinfo/engine-patches