if (!operation.allowDuplicates() && (pending.contains(operation) || operations.contains(operation))) { VdcOperationCallback<?, ?> replacementCallback = usedCallbacks.get(operation.getCallback()); if (replacementCallback == null) { if (!(operation.getCallback() instanceof VdcOperationCallbackList)) { replacementCallback = createCallback(manager); } else { replacementCallback = createListCallback(manager); usedCallbacks.put(operation.getCallback(), (VdcOperationCallback<VdcOperation<?, ?>, ?>) replacementCallback); operations.add(new VdcOperation(operation, replacementCallback));
@Override public void onFailure(final List<VdcOperation<?, ?>> operationList, final Throwable exception) { // If the failure is recoverable, then add the request back into the queue. removePending(operationList); VdcOperation<?, ?> originalOperation = getOriginalOperation(operationList.get(0)); // If the operation allows duplicates, it means we shouldn't retry the operation. if (!operationList.get(0).allowDuplicates() && operationList.get(0).getCopyCount() < RETRY_THRESHOLD) { manager.addOperationList(operationList); } else { VdcOperationCallbackList<VdcOperation<?, ?>, Object> originalCallback = (VdcOperationCallbackList<VdcOperation<?, ?>, Object>) originalOperation.getCallback(); originalCallback.onFailure(operationList, exception); } // Finished, check for more operations. processOperation(manager); } };
&& queriesList.get(0).getCallback() instanceof VdcOperationCallbackList)) { final List<QueryType> queryTypes = new ArrayList<>(); final List<QueryParametersBase> parameters = new ArrayList<>(); if (operation.isPublic()) { queriesList.remove(operation); runPublicQuery(operation); } else { queryTypes.add((QueryType) operation.getOperation()); parameters.add((QueryParametersBase) operation.getParameter());
/** * Copy constructor that allows for a different callback. * @param sourceOperation The source {@code VdcOperation} object. * @param callback The new callback method. */ public VdcOperation(final VdcOperation<T, P> sourceOperation, final VdcOperationCallback<?, ?> callback) { this(sourceOperation.getOperation(), sourceOperation.getParameter(), callback, sourceOperation, sourceOperation.isPublic(), sourceOperation.isFromList, sourceOperation.isRunOnlyIfAllValidationPass()); }
/** * Returns {@code true} if execution of given operation caused the Engine session to be refreshed. */ boolean engineSessionRefreshed(VdcOperation<?, ?> operation) { // Actions always refresh the Engine session if (operation.isAction()) { return true; } else if (((QueryParametersBase) operation.getParameter()).getRefresh()) { // Queries optionally refresh the Engine session return true; } return false; }
@Override public void serviceFound(GenericApiGWTServiceAsync service) { service.runPublicQuery((QueryType) operation.getOperation(), (QueryParametersBase) operation.getParameter(), new AsyncCallback<QueryReturnValue>() { @Override public void onFailure(final Throwable exception) { operation.getCallback().onFailure(operation, exception); } @Override public void onSuccess(final QueryReturnValue result) { operation.getCallback().onSuccess(operation, result); } }); }
@Test public void testOnOperationAvailableSingle_failure_query_noretry() { QueryParametersBase testParameter = new QueryParametersBase(); // Setup 'previous' retries, so we have exhausted the retries. VdcOperation<QueryType, QueryParametersBase> testOperation = new VdcOperation<>(QueryType.Search, testParameter, mockCallback1); testOperation = new VdcOperation(testOperation, mockCallback2); testOperation = new VdcOperation(testOperation, mockCallback2); testOperation = new VdcOperation(testOperation, mockCallback2); testOperation = new VdcOperation(testOperation, mockCallback2); when(mockOperationManager.pollOperation()).thenReturn((VdcOperation) testOperation).thenReturn(null); testProcessor.processAvailableOperations(mockOperationManager); verify(mockProvider).transmitOperationList(operationListCaptor.capture()); Exception testException = new Exception("This is an exception"); //$NON-NLS-1$ operationListCaptor.getValue().get(0).getCallback().onFailure(testOperation, testException); // Verify that the original callback is called. verify(mockCallback1).onFailure(testOperation, testException); }
parameters.setRefresh(false); // Why do we do this? initQueryParamsFilter(parameters); operationList.add(new VdcOperation<>(queryTypeList.get(i), parameters, true, multiCallback, false));
/** * Map operations by callback, so we can properly call a single callback for all related operations. * @param operationList The list of operations to determine the map for. * @return A Map of operations keyed by the callback. */ private Map<VdcOperationCallback<?, ?>, List<VdcOperation<?, ?>>> getCallbackMap( final List<VdcOperation<?, ?>> operationList) { Map<VdcOperationCallback<?, ?>, List<VdcOperation<?, ?>>> callbackMap = new HashMap<>(); for (VdcOperation<?, ?> operation: operationList) { List<VdcOperation<?, ?>> operationsByCallback = callbackMap.get(operation.getCallback()); if (operationsByCallback == null) { operationsByCallback = new ArrayList<>(); callbackMap.put(operation.getCallback(), operationsByCallback); } operationsByCallback.add(operation); } return callbackMap; }
runOnlyIfAllValidationPass = operation.isRunOnlyIfAllValidationPass(); parameters.add((ActionParametersBase) operation.getParameter()); && allActionOperations.get(0).getCallback() instanceof VdcOperationCallbackList)) { List<VdcOperation<?, ?>> waitForResultList = getWaitForResultList(actionEntry.getValue()); if (!waitForResultList.isEmpty()) {
@Override public void transmitOperationList(final List<VdcOperation<?, ?>> operations) { // Operations can be either actions or queries. Both require different handling so lets // Split them out into two lists so we can process them independently. List<VdcOperation<?, ?>> queriesList = new ArrayList<>(); Map<ActionType, List<VdcOperation<?, ?>>> actionsMap = new HashMap<>(); for (VdcOperation<?, ?> operation: operations) { if (operation.isAction()) { List<VdcOperation<?, ?>> actionsList = actionsMap.get(operation.getOperation()); if (actionsList == null) { actionsList = new ArrayList<>(); actionsMap.put((ActionType) operation.getOperation(), actionsList); } actionsList.add(operation); } else { queriesList.add(operation); } } if (!actionsMap.isEmpty()) { // We have some actions, call method to send actions. transmitMultipleActions(actionsMap); } if (!queriesList.isEmpty()) { // We have some queries, call method to send queries. transmitMultipleQueries(queriesList); } }
/** * Transmit a single operation, with the expectation of a single result object. * @param operation The operation to execute. */ void transmitOperation(final VdcOperation<?, ?> operation) { // Figure out if this is an action or a query. if (operation.isAction()) { // Action runAction(operation); } else { // Query if (operation.isPublic()) { runPublicQuery(operation); } else { runQuery(operation); } } }
/** * Returns the number of times this operation has been copied using the copy constructor. * If this is the original returns 1. * @return The copy count. */ public int getCopyCount() { int result = 1; if (source != null) { result += source.getCopyCount(); } return result; }
/** * Check if duplicates of this are allowed. If the operation wraps an action * duplicates are allowed. * @return True if duplicates are allowed, false otherwise. */ public boolean allowDuplicates() { return isAction(); }
/** * Traverse the source operation tree to find the original one. * @param operation The operation to use to traverse. * @return The original operation. */ private VdcOperation<?, ?> getOriginalOperation(final VdcOperation<?, ?> operation) { // Get the original operation. VdcOperation<?, ?> originalOperation = operation; while (originalOperation.getSource() != null) { originalOperation = originalOperation.getSource(); } return originalOperation; }
private List<VdcOperation<?, ?>> getWaitForResultList(List<VdcOperation<?, ?>> originalList) { List<VdcOperation<?, ?>> result = new ArrayList<>(); for (VdcOperation<?, ?> operation: originalList) { if (!operation.isFromList()) { result.add(operation); } } return result; }
/** * Add operation to the queue. Fire event when operation is successfully added if fireEvent is true. * If the operation determined by equals is already in the queue, do not add it again. * @param operation The {@code VdcOperation} to add. */ private void addOperationImpl(final VdcOperation<?, ?> operation) { // If the operation is not already in the queue || the operation is an action (allows duplicates). // Then add this operation to the queue, and process the queue immediately. final boolean operationCanBeAdded = !operationQueue.contains(operation) || operation.allowDuplicates(); if (operationCanBeAdded && operationQueue.add(operation)) { processor.processOperation(this); if (engineSessionRefreshed(operation)) { EngineSessionRefreshedEvent.fire(eventBus); } } }
@Test public void testOnOperationAvailableSingle() { ActionParametersBase testParameter = new ActionParametersBase(); VdcOperation<ActionType, ActionParametersBase> testOperation = new VdcOperation<>(ActionType.AddEventSubscription, testParameter, mockCallback1); when(mockOperationManager.pollOperation()).thenReturn((VdcOperation) testOperation).thenReturn(null); testProcessor.processAvailableOperations(mockOperationManager); verify(mockProvider).transmitOperationList(operationListCaptor.capture()); // Test that we inserted the callback from the processor. assertNotEquals(operationListCaptor.getValue().get(0).getCallback(), mockCallback1, "The callbacks should not match."); //$NON-NLS-1$ }
@Test public void testTransmitOperationList_oneAction_failure() { List<VdcOperation<?, ?>> testList = new ArrayList<>(); ActionParametersBase testParameters = new ActionParametersBase(); VdcOperation<ActionType, ActionParametersBase> testOperation1 = new VdcOperation<>(ActionType.ActivateVds, testParameters, mockOperationCallbackSingle1); testList.add(testOperation1); testProvider.transmitOperationList(testList); verify(mockService).runAction(eq(ActionType.ActivateVds), eq(testParameters), actionCallback.capture()); Exception testException = new Exception("Failure"); //$NON-NLS-1$ actionCallback.getValue().onFailure(testException); verify(mockOperationCallbackSingle1).onFailure(testOperation1, testException); }
@Override public void onFailure(Throwable exception) { operation.getCallback().onFailure(operation, exception); } });