Ravi Nori has uploaded a new change for review. Change subject: core : Remove Placeholder mechanism ......................................................................
core : Remove Placeholder mechanism Remove place holder mechanism from backend Change-Id: Iae746ec8e328740aa4c48a08df7e793e85e17093 Signed-off-by: Ravi Nori <rn...@redhat.com> --- M backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/Backend.java M backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/CommandBase.java M backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/MultipleActionsRunner.java M backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/RunVmCommandBase.java M backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/tasks/AsyncTaskManager.java M backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/tasks/CommandCoordinatorUtil.java M backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/CommandBaseTest.java M backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/VdcActionParametersBase.java 8 files changed, 148 insertions(+), 218 deletions(-) git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/50/37150/1 diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/Backend.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/Backend.java index e0eedb0..a98d7d4 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/Backend.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/Backend.java @@ -429,7 +429,6 @@ command.setInternalExecution(runAsInternal); ExecutionHandler.prepareCommandForMonitoring(command, command.getActionType(), runAsInternal); - command.insertAsyncTaskPlaceHolders(); returnValue = command.executeAction(); returnValue.setCorrelationId(command.getParameters().getCorrelationId()); returnValue.setJobId(command.getJobId()); @@ -574,7 +573,6 @@ case LoginUser: case LoginAdminUser: CommandBase<?> command = CommandsFactory.createCommand(parameters.getActionType(), parameters); - command.insertAsyncTaskPlaceHolders(); return command.executeAction(); default: return getErrorCommandReturnValue(VdcBllMessages.USER_NOT_AUTHORIZED_TO_PERFORM_ACTION); diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/CommandBase.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/CommandBase.java index f07815c..4ccdc9f 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/CommandBase.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/CommandBase.java @@ -9,7 +9,6 @@ import java.util.Iterator; import java.util.List; import java.util.Map; -import java.util.Map.Entry; import java.util.Set; import javax.ejb.TransactionRolledbackLocalException; @@ -114,7 +113,6 @@ /* Multiplier used to convert GB to bytes or vice versa. */ protected static final long BYTES_IN_GB = 1024 * 1024 * 1024; - private static final String DEFAULT_TASK_KEY = "DEFAULT_TASK_KEY"; private T _parameters; private VdcReturnValueBase _returnValue; private CommandActionState _actionState = CommandActionState.EXECUTE; @@ -141,27 +139,7 @@ /** Handlers for performing the logical parts of the command */ private List<SPMAsyncTaskHandler> taskHandlers; - private Map<Guid, CommandBase<?>> childCommandsMap = new HashMap<>(); - private Map<Guid, Pair<VdcActionType, VdcActionParametersBase>> childCommandInfoMap = new HashMap<>(); private CommandStatus commandStatus = CommandStatus.NOT_STARTED; - - public void addChildCommandInfo(Guid id, VdcActionType vdcActionType, VdcActionParametersBase parameters) { - childCommandInfoMap.put(id, new Pair<>(vdcActionType, parameters)); - } - - protected List<VdcReturnValueBase> executeChildCommands() { - List<VdcReturnValueBase> results = new ArrayList<>(childCommandsMap.size()); - for (Entry<Guid, CommandBase<?>> entry : childCommandsMap.entrySet()) { - results.add(executeChildCommand(entry.getKey())); - } - return results; - } - - protected VdcReturnValueBase executeChildCommand(Guid idInCommandsMap) { - CommandBase<?> command = childCommandsMap.get(idInCommandsMap); - return commandObjectsHandlerProvider.get().runAction(command, getExecutionContext()); - } - protected CommandActionState getActionState() { return _actionState; @@ -235,7 +213,7 @@ * @return result of the command execution */ protected VdcReturnValueBase attemptRollback(VdcActionType commandType, - VdcActionParametersBase params) { + VdcActionParametersBase params) { if (canPerformRollbackUsingCommand(commandType, params)) { params.setExecutionReason(CommandExecutionReason.ROLLBACK_FLOW); params.setTransactionScopeOption(TransactionScopeOption.RequiresNew); @@ -258,7 +236,7 @@ * @return result of the command execution */ protected VdcReturnValueBase checkAndPerformRollbackUsingCommand(VdcActionType commandType, - VdcActionParametersBase params) { + VdcActionParametersBase params) { return attemptRollback(commandType, params); } @@ -272,8 +250,8 @@ * @return true if it is possible to run rollback using command */ protected boolean canPerformRollbackUsingCommand - (VdcActionType commandType, - VdcActionParametersBase params) { + (VdcActionType commandType, + VdcActionParametersBase params) { return true; } @@ -286,7 +264,7 @@ * @return The compensation context to use. */ private CompensationContext createCompensationContext(TransactionScopeOption transactionScopeOption, - boolean forceCompensation) { + boolean forceCompensation) { if (transactionScopeOption == TransactionScopeOption.Suppress && !forceCompensation) { return NoOpCompensationContext.getInstance(); } @@ -357,20 +335,12 @@ execute(); } else { getReturnValue().setCanDoAction(false); - clearChildAsyncTasksWithOutVdsmId(); } } finally { freeLockExecute(); clearAsyncTasksWithOutVdsmId(); } return getReturnValue(); - } - - private void clearChildAsyncTasksWithOutVdsmId() { - for (Entry<Guid, CommandBase<?>> entry : childCommandsMap.entrySet()) { - entry.getValue().clearAsyncTasksWithOutVdsmId(); - entry.getValue().clearChildAsyncTasksWithOutVdsmId(); - } } private void clearAsyncTasksWithOutVdsmId() { @@ -457,25 +427,25 @@ DbFacade.getInstance().getDaoForEntity(entityClass); switch (snapshot.getSnapshotType()) { - case CHANGED_STATUS_ONLY: - EntityStatusSnapshot entityStatusSnapshot = (EntityStatusSnapshot) snapshotData; - ((StatusAwareDao<Serializable, Enum<?>>) daoForEntity).updateStatus( - entityStatusSnapshot.getId(), entityStatusSnapshot.getStatus()); - break; - case DELETED_OR_UPDATED_ENTITY: - BusinessEntity<Serializable> entitySnapshot = (BusinessEntity<Serializable>) snapshotData; - if (daoForEntity.get(entitySnapshot.getId()) == null) { - daoForEntity.save(entitySnapshot); - } else { - daoForEntity.update(entitySnapshot); - } - break; - case UPDATED_ONLY_ENTITY: - daoForEntity.update((BusinessEntity<Serializable>)snapshotData); - break; - case NEW_ENTITY_ID: - daoForEntity.remove(snapshotData); - break; + case CHANGED_STATUS_ONLY: + EntityStatusSnapshot entityStatusSnapshot = (EntityStatusSnapshot) snapshotData; + ((StatusAwareDao<Serializable, Enum<?>>) daoForEntity).updateStatus( + entityStatusSnapshot.getId(), entityStatusSnapshot.getStatus()); + break; + case DELETED_OR_UPDATED_ENTITY: + BusinessEntity<Serializable> entitySnapshot = (BusinessEntity<Serializable>) snapshotData; + if (daoForEntity.get(entitySnapshot.getId()) == null) { + daoForEntity.save(entitySnapshot); + } else { + daoForEntity.update(entitySnapshot); + } + break; + case UPDATED_ONLY_ENTITY: + daoForEntity.update((BusinessEntity<Serializable>)snapshotData); + break; + case NEW_ENTITY_ID: + daoForEntity.remove(snapshotData); + break; } } @@ -884,7 +854,7 @@ // cluster level ok check storage_pool level if (actionVersionMap != null && ((getVdsGroup() != null && getVdsGroup().getCompatibilityVersion().compareTo( - new Version(actionVersionMap.getcluster_minimal_version())) < 0) || + new Version(actionVersionMap.getcluster_minimal_version())) < 0) || (!"*".equals(actionVersionMap.getstorage_pool_minimal_version()) && getStoragePool() != null && getStoragePool() .getCompatibilityVersion().compareTo( new Version(actionVersionMap.getstorage_pool_minimal_version())) < 0))) { @@ -906,9 +876,9 @@ * @return <code>true</code> if the current user is authorized to run the action, <code>false</code> otherwise */ protected boolean checkUserAuthorization(Guid userId, - final ActionGroup actionGroup, - final Guid object, - final VdcObjectType type) { + final ActionGroup actionGroup, + final Guid object, + final VdcObjectType type) { // Grant if there is matching permission in the database: final Guid permId = getDbFacade().getPermissionDao().getEntityPermissions(userId, actionGroup, object, type); @@ -952,11 +922,11 @@ * @return <code>true</code> if the current user is authorized to run the action, <code>false</code> otherwise */ protected boolean checkUserAndGroupsAuthorization(Guid userId, - Collection<Guid> groupIds, - final ActionGroup actionGroup, - final Guid object, - final VdcObjectType type, - final boolean ignoreEveryone) { + Collection<Guid> groupIds, + final ActionGroup actionGroup, + final Guid object, + final VdcObjectType type, + final boolean ignoreEveryone) { // Grant if there is matching permission in the database: if (log.isDebugEnabled()) { log.debug("Checking whether user '{}' or groups '{}' have action group '{}' on object type '{}'", @@ -1054,8 +1024,8 @@ for (PermissionSubject permSubject : permSubjects) { if (!checkSinglePermission(permSubject, getReturnValue().getCanDoActionMessages())) { log.info("No permission found for user '{}' or one of the groups he is member of," - + " when running action '{}', Required permissions are: Action type: '{}' Action group: '{}'" - + " Object type: '{}' Object ID: '{}'.", + + " when running action '{}', Required permissions are: Action type: '{}' Action group: '{}'" + + " Object type: '{}' Object ID: '{}'.", getCurrentUser().getId(), getActionType(), permSubject.getActionGroup().getRoleType().name(), @@ -1164,7 +1134,7 @@ * @param parameters parameter of the creating command */ protected VdcActionParametersBase getParametersForTask(VdcActionType parentCommandType, - VdcActionParametersBase parameters) { + VdcActionParametersBase parameters) { // If there is no parent command, the command that its type // will be stored in the DB for thr task is the one creating the command VdcActionParametersBase parentParameters = parameters.getParentParameters(); @@ -1210,7 +1180,6 @@ } // If we failed to execute due to exception or some other reason, we compensate for the failure. if (exceptionOccurred || !getSucceeded()) { - clearChildAsyncTasksWithOutVdsmId(); setCommandStatus(CommandStatus.FAILED); setSucceeded(false); compensate(); @@ -1388,33 +1357,6 @@ return annotation != null && annotation.forceCompensation(); } - /** - * This method is called before executeAction to insert the async task - * placeholders for the child commands. - */ - protected void insertAsyncTaskPlaceHolders() { - TransactionSupport.executeInScope(TransactionScopeOption.Required, - new TransactionMethod<Void>() { - @Override - public Void runInTransaction() { - buildChildCommandInfos(); - for (Map.Entry<Guid, Pair<VdcActionType, VdcActionParametersBase>> entry : childCommandInfoMap.entrySet()) { - CommandBase<?> command = - commandObjectsHandlerProvider.get().createAction(entry.getValue() - .getFirst(), - entry.getValue().getSecond(), - context); - log.info("Command '{}' persisting async task placeholder for child command '{}'", - getCommandId(), - command.getCommandId()); - command.insertAsyncTaskPlaceHolders(); - childCommandsMap.put(entry.getKey(), command); - } - return null; - } - }); - } - protected abstract void executeCommand(); /** @@ -1488,7 +1430,7 @@ _returnValue.getExecuteFailedMessages().add(fault.getError().name()); _returnValue.setFault(fault); } - + private static final String DEFAULT_TASK_KEY = "DEFAULT_TASK_KEY"; Map<String, Guid> taskKeyToTaskIdMap = new HashMap<>(); public Guid persistAsyncTaskPlaceHolder(VdcActionType parentCommand) { @@ -1496,9 +1438,6 @@ } public Guid persistAsyncTaskPlaceHolder(VdcActionType parentCommand, final String taskKey) { - if (taskKeyToTaskIdMap.containsKey(taskKey)) { - return taskKeyToTaskIdMap.get(taskKey); - } Guid taskId = Guid.Empty; try { @@ -1531,17 +1470,6 @@ return taskId; } - private void saveTaskAndPutInMap(String taskKey, AsyncTask task) { - CommandCoordinatorUtil.saveAsyncTaskToDb(task); - taskKeyToTaskIdMap.put(taskKey, task.getTaskId()); - } - - private void addToReturnValueTaskPlaceHolderIdList(Guid taskId) { - if (!getReturnValue().getTaskPlaceHolderIdList().contains(taskId)) { - getReturnValue().getTaskPlaceHolderIdList().add(taskId); - } - } - public void deleteAsyncTaskPlaceHolder() { deleteAsyncTaskPlaceHolder(DEFAULT_TASK_KEY); } @@ -1551,6 +1479,11 @@ if (!Guid.isNullOrEmpty(taskId)) { CommandCoordinatorUtil.removeTaskFromDbByTaskId(taskId); } + } + + private void saveTaskAndPutInMap(String taskKey, AsyncTask task) { + CommandCoordinatorUtil.saveAsyncTaskToDb(task); + taskKeyToTaskIdMap.put(taskKey, task.getTaskId()); } public Guid getAsyncTaskId() { @@ -1563,6 +1496,13 @@ } return taskKeyToTaskIdMap.get(taskKey); } + + private void addToReturnValueTaskPlaceHolderIdList(Guid taskId) { + if (!getReturnValue().getTaskPlaceHolderIdList().contains(taskId)) { + getReturnValue().getTaskPlaceHolderIdList().add(taskId); + } + } + /** * Use this method in order to create task in the CommandCoordinatorUtil in a safe way. If you use this method within a * certain command, make sure that the command implemented the ConcreteCreateTask method. @@ -1578,9 +1518,9 @@ * @return Guid of the created task. */ protected Guid createTask(Guid taskId, - AsyncTaskCreationInfo asyncTaskCreationInfo, - VdcActionType parentCommand, - Map<Guid, VdcObjectType> entitiesMap) { + AsyncTaskCreationInfo asyncTaskCreationInfo, + VdcActionType parentCommand, + Map<Guid, VdcObjectType> entitiesMap) { return createTask(taskId, asyncTaskCreationInfo, parentCommand, null, entitiesMap); } @@ -1596,10 +1536,10 @@ * @see {@link #createTask(Guid, AsyncTaskCreationInfo, VdcActionType, VdcObjectType, Guid...)} */ protected Guid createTaskInCurrentTransaction(Guid taskId, - AsyncTaskCreationInfo asyncTaskCreationInfo, - VdcActionType parentCommand, - VdcObjectType entityType, - Guid... entityIds) { + AsyncTaskCreationInfo asyncTaskCreationInfo, + VdcActionType parentCommand, + VdcObjectType entityType, + Guid... entityIds) { return createTaskImpl(taskId, asyncTaskCreationInfo, parentCommand, null, entityType, entityIds); } @@ -1626,9 +1566,9 @@ } protected Guid createTask(Guid taskId, AsyncTaskCreationInfo asyncTaskCreationInfo, - VdcActionType parentCommand, - VdcObjectType vdcObjectType, - Guid... entityIds) { + VdcActionType parentCommand, + VdcObjectType vdcObjectType, + Guid... entityIds) { return createTask(taskId, asyncTaskCreationInfo, @@ -1637,11 +1577,11 @@ } protected Guid createTask(Guid taskId, - AsyncTaskCreationInfo asyncTaskCreationInfo, - VdcActionType parentCommand, - String description, - VdcObjectType entityType, - Guid... entityIds) { + AsyncTaskCreationInfo asyncTaskCreationInfo, + VdcActionType parentCommand, + String description, + VdcObjectType entityType, + Guid... entityIds) { return createTask(taskId, asyncTaskCreationInfo, @@ -1663,8 +1603,8 @@ * @param entitiesMap - map of entities */ protected Guid createTask(Guid taskId, AsyncTaskCreationInfo asyncTaskCreationInfo, - VdcActionType parentCommand, - String description, Map<Guid, VdcObjectType> entitiesMap) { + VdcActionType parentCommand, + String description, Map<Guid, VdcObjectType> entitiesMap) { Transaction transaction = TransactionSupport.suspend(); @@ -1681,7 +1621,7 @@ } private Guid createTaskImpl(Guid taskId, AsyncTaskCreationInfo asyncTaskCreationInfo, VdcActionType parentCommand, - String description, VdcObjectType entityType, Guid... entityIds) { + String description, VdcObjectType entityType, Guid... entityIds) { return createTaskImpl(taskId, asyncTaskCreationInfo, parentCommand, @@ -1698,10 +1638,10 @@ } private Guid createTaskImpl(Guid taskId, - AsyncTaskCreationInfo asyncTaskCreationInfo, - VdcActionType parentCommand, - String description, - Map<Guid, VdcObjectType> entitiesMap) { + AsyncTaskCreationInfo asyncTaskCreationInfo, + VdcActionType parentCommand, + String description, + Map<Guid, VdcObjectType> entitiesMap) { return CommandCoordinatorUtil.createTask(taskId, this, asyncTaskCreationInfo, parentCommand, description, entitiesMap); } @@ -1860,7 +1800,7 @@ } else { log.info("Failed to Acquire Lock to object '{}'", lock); getReturnValue().getCanDoActionMessages() - .addAll(extractVariableDeclarations(lockAcquireResult.getSecond())); + .addAll(extractVariableDeclarations(lockAcquireResult.getSecond())); return false; } } @@ -2285,33 +2225,33 @@ } protected VdcReturnValueBase runInternalAction(VdcActionType actionType, - VdcActionParametersBase parameters, - CommandContext internalCommandContext) { + VdcActionParametersBase parameters, + CommandContext internalCommandContext) { return getBackend().runInternalAction(actionType, parameters, internalCommandContext); } protected ArrayList<VdcReturnValueBase> runInternalMultipleActions(VdcActionType actionType, - ArrayList<VdcActionParametersBase> parameters) { + ArrayList<VdcActionParametersBase> parameters) { return getBackend().runInternalMultipleActions(actionType, parameters, context.clone()); } protected ArrayList<VdcReturnValueBase> runInternalMultipleActions(VdcActionType actionType, - ArrayList<VdcActionParametersBase> parameters, - ExecutionContext executionContext) { + ArrayList<VdcActionParametersBase> parameters, + ExecutionContext executionContext) { return getBackend().runInternalMultipleActions(actionType, parameters, context.clone().withExecutionContext(executionContext)); } protected VdcReturnValueBase runInternalActionWithTasksContext(VdcActionType actionType, - VdcActionParametersBase parameters) { + VdcActionParametersBase parameters) { return runInternalActionWithTasksContext(actionType, parameters, null); } protected VdcReturnValueBase runInternalActionWithTasksContext(VdcActionType actionType, - VdcActionParametersBase parameters, EngineLock lock) { + VdcActionParametersBase parameters, EngineLock lock) { return runInternalAction( actionType, parameters, diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/MultipleActionsRunner.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/MultipleActionsRunner.java index cc0e015..b73509e 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/MultipleActionsRunner.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/MultipleActionsRunner.java @@ -190,7 +190,6 @@ command.isInternalExecution()); } CorrelationIdTracker.setCorrelationId(command.getCorrelationId()); - command.insertAsyncTaskPlaceHolders(); command.executeAction(); } diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/RunVmCommandBase.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/RunVmCommandBase.java index 85ad9b9..b4929bc 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/RunVmCommandBase.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/RunVmCommandBase.java @@ -131,7 +131,6 @@ JobRepositoryFactory.getJobRepository().closeCompletedJobSteps(job.getId(), JobExecutionStatus.FAILED); } } - insertAsyncTaskPlaceHolders(); executeAction(); } diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/tasks/AsyncTaskManager.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/tasks/AsyncTaskManager.java index 16c51a2..cbb8d1d 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/tasks/AsyncTaskManager.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/tasks/AsyncTaskManager.java @@ -110,21 +110,27 @@ public void initAsyncTaskManager() { tasksInDbAfterRestart = new ConcurrentHashMap(); Map<Guid, List<AsyncTask>> rootCommandIdToTasksMap = groupTasksByRootCommandId(coco.getAllAsyncTasksFromDb()); - int numberOfCommandsWithEmptyVdsmId = 0; + int numberOfCommandsPartiallyExecuted = 0; for (Entry<Guid, List<AsyncTask>> entry : rootCommandIdToTasksMap.entrySet()) { - if (hasTasksWithoutVdsmId(rootCommandIdToTasksMap.get(entry.getKey()))) { - log.info("Root Command '{}' has tasks without vdsm id.", entry.getKey()); - numberOfCommandsWithEmptyVdsmId++; + if (isPartiallyExecutedCommand(rootCommandIdToTasksMap.get(entry.getKey()))) { + log.info("Root Command '{}' has partially executed task.", entry.getKey()); + numberOfCommandsPartiallyExecuted++; } } - irsBrokerLatch = new CountDownLatch(numberOfCommandsWithEmptyVdsmId); + irsBrokerLatch = new CountDownLatch(numberOfCommandsPartiallyExecuted); for (Entry<Guid, List<AsyncTask>> entry : rootCommandIdToTasksMap.entrySet()) { - if (hasTasksWithoutVdsmId(rootCommandIdToTasksMap.get(entry.getKey()))) { - log.info("Root Command '{}' has tasks without vdsm id.", entry.getKey()); - handleTasksOfCommandWithEmptyVdsmId(rootCommandIdToTasksMap.get(entry.getKey())); + boolean isPartiallyExecutedCommand = isPartiallyExecutedCommand(rootCommandIdToTasksMap.get(entry.getKey())); + if (isPartiallyExecutedCommand) { + log.info("Root Command '{}' has partially executed tasks.", entry.getKey()); + handlePartiallyExecuteTasksOfCommand(rootCommandIdToTasksMap.get(entry.getKey())); } for (AsyncTask task : entry.getValue()) { - if (!hasEmptyVdsmId(task)) { + if (isPartiallyExecutedCommand) { + if (!isPartiallyExecutedTask(task) && waitAndPollOnRestart(task)) { + tasksInDbAfterRestart.putIfAbsent(task.getStoragePoolId(), new ArrayList<AsyncTask>()); + tasksInDbAfterRestart.get(task.getStoragePoolId()).add(task); + } + } else if (!isPartiallyExecutedTask(task)) { tasksInDbAfterRestart.putIfAbsent(task.getStoragePoolId(), new ArrayList<AsyncTask>()); tasksInDbAfterRestart.get(task.getStoragePoolId()).add(task); } @@ -184,7 +190,7 @@ // for SubtractMinutesAsMills of minutes. return (task.getState() == AsyncTaskState.Cleared || task.getState() == AsyncTaskState.ClearFailed) && task.getLastAccessToStatusSinceEnd() < (System - .currentTimeMillis() - SubtractMinutesAsMills); + .currentTimeMillis() - SubtractMinutesAsMills); } public synchronized boolean hasTasksByStoragePoolId(Guid storagePoolID) { @@ -212,7 +218,7 @@ return false; } - public void handleTasksOfCommandWithEmptyVdsmId(final List<AsyncTask> tasks) { + public void handlePartiallyExecuteTasksOfCommand(final List<AsyncTask> tasks) { ThreadPoolUtil.execute(new Runnable() { @SuppressWarnings("synthetic-access") @Override @@ -221,9 +227,8 @@ @Override public Object runInTransaction() { try { - boolean isPartiallySubmittedCommand = isPartiallySubmittedCommand(tasks); for (AsyncTask task : tasks) { - handleTaskOfCommandWithEmptyVdsmId(isPartiallySubmittedCommand, task); + handlePartiallyExecutedTaskOfCommand(task); } return null; } finally { @@ -235,22 +240,16 @@ }); } - /** - * A command is considered partially submitted to the vdsm if some of its - * place holders have vdsm id and some have empty vdsm id, indicating that - * the server was restarted during command execution. - * @param tasks - * @return - */ - private boolean isPartiallySubmittedCommand(List<AsyncTask> tasks) { - for (AsyncTask task : tasks) { - // if one of the tasks has a vdsm id, the command was partially - // submitted to vdsm - if (!hasEmptyVdsmId(task)) { - return true; - } - } - return false; + private boolean isPartiallyExecutedCommand(List<AsyncTask> tasks) { + return tasks.isEmpty() ? false : !tasks.get(0).getRootCmdEntity().isExecuted(); + } + + private boolean waitAndPollOnRestart(AsyncTask task) { + return task.getActionParameters().isWaitAndPollOnRestart(); + } + + private static boolean hasEmptyVdsmId(AsyncTask task) { + return Guid.Empty.equals(task.getVdsmTaskId()); } /** @@ -267,22 +266,8 @@ return rootCommandIdToCommandsMap; } - /** - * Determines if any of the tasks has an empty vdsm id. - * @param tasks - * @return - */ - private boolean hasTasksWithoutVdsmId(List<AsyncTask> tasks) { - for (AsyncTask task : tasks) { - if (hasEmptyVdsmId(task)) { - return true; - } - } - return false; - } - - private static boolean hasEmptyVdsmId(AsyncTask task) { - return Guid.Empty.equals(task.getVdsmTaskId()); + private static boolean isPartiallyExecutedTask(AsyncTask task) { + return !task.getChildCmdEntity().isExecuted(); } /** @@ -294,41 +279,41 @@ * If none of the tasks were submitted to vdsm, the empty place holders * are deleted from the database and we endAction on the command with * failure - * @param isPartiallySubmittedCommand * @param task */ - private void handleTaskOfCommandWithEmptyVdsmId( - final boolean isPartiallySubmittedCommand, + private void handlePartiallyExecutedTaskOfCommand( final AsyncTask task) { - if (isPartiallySubmittedCommand) { - if (hasEmptyVdsmId(task)) { - removeTaskFromDbByTaskId(task.getTaskId()); - return; - } - partiallyCompletedCommandTasks.put(task.getVdsmTaskId(), task); + + if (hasEmptyVdsmId(task)) { + removeTaskFromDbByTaskId(task.getTaskId()); return; } - TransactionSupport.executeInScope(TransactionScopeOption.Required, - new TransactionMethod<Void>() { - @Override - public Void runInTransaction() { - logAndFailTaskOfCommandWithEmptyVdsmId(task, - "Engine was restarted before all tasks of the command could be submitted to vdsm."); - return null; - } - }); + + if (waitAndPollOnRestart(task)) { + partiallyCompletedCommandTasks.put(task.getVdsmTaskId(), task); + } else { + TransactionSupport.executeInScope(TransactionScopeOption.Required, + new TransactionMethod<Void>() { + @Override + public Void runInTransaction() { + logAndFailPartiallySubmittedTaskOfCommand(task, + "Engine was restarted before all tasks of the command could be submitted to vdsm."); + return null; + } + }); + } } public void logAndFailTaskOfCommandWithEmptyVdsmId(Guid asyncTaskId, String message) { AsyncTask task = coco.getAsyncTaskFromDb(asyncTaskId); if (task != null) { - logAndFailTaskOfCommandWithEmptyVdsmId(task, message); + logAndFailPartiallySubmittedTaskOfCommand(task, message); } } - public void logAndFailTaskOfCommandWithEmptyVdsmId(final AsyncTask task, String message) { + public void logAndFailPartiallySubmittedTaskOfCommand(final AsyncTask task, String message) { log.info( - "Failing task with empty vdsm id AsyncTaskType '{}': Task '{}' Parent Command '{}'", + "Failing partially submitted task AsyncTaskType '{}': Task '{}' Parent Command '{}'", task.getTaskType(), task.getTaskId(), (task.getActionType())); @@ -336,13 +321,13 @@ if (task.getActionType() == VdcActionType.Unknown) { removeTaskFromDbByTaskId(task.getTaskId()); log.info( - "Not calling endAction for task with out vdsm id and AsyncTaskType '{}': Task '{}' Parent Command '{}'", + "Not calling endAction for partially submitted task and AsyncTaskType '{}': Task '{}' Parent Command '{}'", task.getTaskType(), task.getTaskId(), (task.getActionType())); return; } - log.info("Calling updateTask for task with out vdsm id and AsyncTaskType '{}': Task '{}' Parent Command" + log.info("Calling updateTask for partially submitted task and AsyncTaskType '{}': Task '{}' Parent Command" + " '{}' Parameters class '{}'", task.getTaskType(), task.getTaskId(), @@ -449,7 +434,7 @@ private void pollAndUpdateAsyncTasks() { if (logChangedMap) { log.info("Polling and updating Async Tasks: {} tasks, {} tasks to poll now", - _tasks.size(), numberOfTasksToPoll()); + _tasks.size(), numberOfTasksToPoll()); } // Fetch Set of pool id's @@ -468,7 +453,7 @@ * @param asyncTaskMap - Task statuses Map fetched from VDSM. */ private void updateTaskStatuses( - Map<Guid, Map<Guid, AsyncTaskStatus>> poolsAllTasksMap) { + Map<Guid, Map<Guid, AsyncTaskStatus>> poolsAllTasksMap) { for (SPMTask task : _tasks.values()) { if (task.getShouldPoll()) { Map<Guid, AsyncTaskStatus> asyncTasksForPoolMap = poolsAllTasksMap @@ -658,7 +643,7 @@ _tasks.get(vdsmTaskId).setLastStatusAccessTime(); returnValue.add(_tasks.get(vdsmTaskId).getLastTaskStatus()); } else { // task doesn't exist in the manager (shouldn't happen) -> - // assume it has been ended successfully. + // assume it has been ended successfully. log.warn( "Polling tasks. Task ID '{}' doesn't exist in the manager -> assuming 'finished'.", vdsmTaskId); @@ -717,8 +702,8 @@ newlyAddedTasks.add(task); } catch (Exception e) { log.error("Failed to load task of type '{}' with id '{}': {}.", - creationInfo.getTaskType(), creationInfo.getVdsmTaskId(), - ExceptionUtils.getRootCauseMessage(e)); + creationInfo.getTaskType(), creationInfo.getVdsmTaskId(), + ExceptionUtils.getRootCauseMessage(e)); log.debug("Exception", e); } } diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/tasks/CommandCoordinatorUtil.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/tasks/CommandCoordinatorUtil.java index c928eba..6231cf8 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/tasks/CommandCoordinatorUtil.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/tasks/CommandCoordinatorUtil.java @@ -109,7 +109,7 @@ } public static void logAndFailTaskOfCommandWithEmptyVdsmId(AsyncTask task, String message) { - getAsyncTaskManager().logAndFailTaskOfCommandWithEmptyVdsmId(task, message); + getAsyncTaskManager().logAndFailPartiallySubmittedTaskOfCommand(task, message); } public static Collection<Guid> getUserIdsForVdsmTaskIds(ArrayList<Guid> tasksIDs) { diff --git a/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/CommandBaseTest.java b/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/CommandBaseTest.java index 8621bf1..4accb0e 100644 --- a/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/CommandBaseTest.java +++ b/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/CommandBaseTest.java @@ -142,7 +142,6 @@ when(parameterMock.getTransactionScopeOption()).thenReturn(TransactionScopeOption.Required); when(parameterMock.getLockProperties()).thenReturn(LockProperties.create(LockProperties.Scope.None)); CommandBase<VdcActionParametersBase> command = spy(new CommandBaseDummy(parameterMock)); - command.insertAsyncTaskPlaceHolders(); command.executeAction(); verify(command).executeCommand(); } diff --git a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/VdcActionParametersBase.java b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/VdcActionParametersBase.java index b5195f8..7326a5c 100644 --- a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/VdcActionParametersBase.java +++ b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/VdcActionParametersBase.java @@ -21,6 +21,7 @@ private Guid commandId; private transient String sessionid; private boolean shouldbelogged; + private boolean waitAndPollOnRestart; private DbUser parametersCurrentUser; private TransactionScopeOption transctionOption; @@ -67,6 +68,7 @@ public VdcActionParametersBase() { shouldbelogged = true; + waitAndPollOnRestart = true; transctionOption = TransactionScopeOption.Required; setTaskGroupSuccess(true); setParentCommand(VdcActionType.Unknown); @@ -264,6 +266,14 @@ executionIndex--; } + public boolean isWaitAndPollOnRestart() { + return waitAndPollOnRestart; + } + + public void setWaitAndPollOnRestart(boolean waitAndPollOnRestart) { + this.waitAndPollOnRestart = waitAndPollOnRestart; + } + /** * Enum for determining the execution reason of the command. */ -- To view, visit http://gerrit.ovirt.org/37150 To unsubscribe, visit http://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Iae746ec8e328740aa4c48a08df7e793e85e17093 Gerrit-PatchSet: 1 Gerrit-Project: ovirt-engine Gerrit-Branch: master Gerrit-Owner: Ravi Nori <rn...@redhat.com> _______________________________________________ Engine-patches mailing list Engine-patches@ovirt.org http://lists.ovirt.org/mailman/listinfo/engine-patches