/** * Resets tokens to their initial state. This effectively causes a replay. * <p> * Before attempting to reset the tokens, the caller must stop this processor, as well as any instances of the * same logical processor that may be running in the cluster. Failure to do so will cause the reset to fail, * as a processor can only reset the tokens if it is able to claim them all. */ public void resetTokens() { resetTokens(initialTrackingTokenBuilder); }
/** * Reset tokens to the position as return by the given {@code initialTrackingTokenSupplier}. This effectively causes * a replay since that position. * <p> * Note that the new token must represent a position that is <em>before</em> the current position of the processor. * <p> * Before attempting to reset the tokens, the caller must stop this processor, as well as any instances of the * same logical processor that may be running in the cluster. Failure to do so will cause the reset to fail, * as a processor can only reset the tokens if it is able to claim them all. * * @param initialTrackingTokenSupplier A function returning the token representing the position to reset to */ public void resetTokens(Function<StreamableMessageSource, TrackingToken> initialTrackingTokenSupplier) { resetTokens(initialTrackingTokenSupplier.apply(messageSource)); }
@Test(expected = IllegalStateException.class) public void testResetRejectedWhenInvokerDoesNotSupportReset() { when(mockHandler.supportsReset()).thenReturn(false); testSubject.resetTokens(); }
@Test(expected = IllegalStateException.class) public void testResetRejectedWhileRunning() { testSubject.start(); testSubject.resetTokens(); }
@Test public void testResetRejectedIfNotAllTokensCanBeClaimed() { tokenStore.initializeTokenSegments("test", 4); when(tokenStore.fetchToken("test", 3)).thenThrow(new UnableToClaimTokenException("Mock")); try { testSubject.resetTokens(); fail("Expected exception"); } catch (UnableToClaimTokenException e) { // expected } verify(tokenStore, never()).storeToken(isNull(), anyString(), anyInt()); }
@Test public void testResetBeforeStartingPerformsANormalRun() throws Exception { when(mockHandler.supportsReset()).thenReturn(true); final List<String> handled = new CopyOnWriteArrayList<>(); final List<String> handledInRedelivery = new CopyOnWriteArrayList<>(); //noinspection Duplicates doAnswer(i -> { EventMessage message = i.getArgument(0); handled.add(message.getIdentifier()); if (ReplayToken.isReplay(message)) { handledInRedelivery.add(message.getIdentifier()); } return null; }).when(mockHandler).handle(any()); testSubject.start(); testSubject.shutDown(); testSubject.resetTokens(); testSubject.start(); eventBus.publish(createEvents(4)); assertWithin(1, TimeUnit.SECONDS, () -> assertEquals(4, handled.size())); assertEquals(0, handledInRedelivery.size()); assertFalse(testSubject.processingStatus().get(0).isReplaying()); }
}).when(eventHandlerInvoker).handle(any(), any()); testSubject.resetTokens(); testSubject.start(); assertWithin(1, TimeUnit.SECONDS, () -> assertEquals(8, replayRun.size()));
@Test public void testResetToPositionCausesCertainEventsToBeReplayed() throws Exception { when(mockHandler.supportsReset()).thenReturn(true); final List<String> handled = new CopyOnWriteArrayList<>(); final List<String> handledInRedelivery = new CopyOnWriteArrayList<>(); //noinspection Duplicates doAnswer(i -> { EventMessage message = i.getArgument(0); handled.add(message.getIdentifier()); if (ReplayToken.isReplay(message)) { handledInRedelivery.add(message.getIdentifier()); } return null; }).when(mockHandler).handle(any()); eventBus.publish(createEvents(4)); testSubject.start(); assertWithin(1, TimeUnit.SECONDS, () -> assertEquals(4, handled.size())); testSubject.shutDown(); testSubject.resetTokens(source -> new GlobalSequenceTrackingToken(1L)); testSubject.start(); assertWithin(1, TimeUnit.SECONDS, () -> assertEquals(6, handled.size())); assertFalse(handledInRedelivery.contains(handled.get(0))); assertFalse(handledInRedelivery.contains(handled.get(1))); assertEquals(handled.subList(2, 4), handled.subList(4, 6)); assertEquals(handled.subList(4, 6), handledInRedelivery); assertTrue(testSubject.processingStatus().get(0).isReplaying()); eventBus.publish(createEvents(1)); assertWithin(1, TimeUnit.SECONDS, () -> assertFalse(testSubject.processingStatus().get(0).isReplaying())); }
@Test public void testResetCausesEventsToBeReplayed() throws Exception { when(mockHandler.supportsReset()).thenReturn(true); final List<String> handled = new CopyOnWriteArrayList<>(); final List<String> handledInRedelivery = new CopyOnWriteArrayList<>(); //noinspection Duplicates doAnswer(i -> { EventMessage message = i.getArgument(0); handled.add(message.getIdentifier()); if (ReplayToken.isReplay(message)) { handledInRedelivery.add(message.getIdentifier()); } return null; }).when(mockHandler).handle(any()); eventBus.publish(createEvents(4)); testSubject.start(); assertWithin(1, TimeUnit.SECONDS, () -> assertEquals(4, handled.size())); testSubject.shutDown(); testSubject.resetTokens(); // Resetting twice caused problems (see issue #559) testSubject.resetTokens(); testSubject.start(); assertWithin(1, TimeUnit.SECONDS, () -> assertEquals(8, handled.size())); assertEquals(handled.subList(0, 4), handled.subList(4, 8)); assertEquals(handled.subList(4, 8), handledInRedelivery); assertTrue(testSubject.processingStatus().get(0).isReplaying()); eventBus.publish(createEvents(1)); assertWithin(1, TimeUnit.SECONDS, () -> assertFalse(testSubject.processingStatus().get(0).isReplaying())); }
assertWithin(1, TimeUnit.SECONDS, () -> assertEquals(2, handled.size())); testSubject.shutDown(); testSubject.resetTokens(); testSubject.start(); assertWithin(1, TimeUnit.SECONDS, () -> assertEquals(4, handled.size()));
/** * Resets tokens to their initial state. This effectively causes a replay. * <p> * Before attempting to reset the tokens, the caller must stop this processor, as well as any instances of the * same logical processor that may be running in the cluster. Failure to do so will cause the reset to fail, * as a processor can only reset the tokens if it is able to claim them all. */ public void resetTokens() { resetTokens(initialTrackingTokenBuilder); }
/** * Resets tokens to their initial state. This effectively causes a replay. * <p> * Before attempting to reset the tokens, the caller must stop this processor, as well as any instances of the * same logical processor that may be running in the cluster. Failure to do so will cause the reset to fail, * as a processor can only reset the tokens if it is able to claim them all. */ public void resetTokens() { resetTokens(initialTrackingTokenBuilder); }
/** * Reset tokens to the position as return by the given {@code initialTrackingTokenSupplier}. This effectively causes * a replay since that position. * <p> * Note that the new token must represent a position that is <em>before</em> the current position of the processor. * <p> * Before attempting to reset the tokens, the caller must stop this processor, as well as any instances of the * same logical processor that may be running in the cluster. Failure to do so will cause the reset to fail, * as a processor can only reset the tokens if it is able to claim them all. * * @param initialTrackingTokenSupplier A function returning the token representing the position to reset to */ public void resetTokens(Function<StreamableMessageSource, TrackingToken> initialTrackingTokenSupplier) { resetTokens(initialTrackingTokenSupplier.apply(messageSource)); }
/** * Reset tokens to the position as return by the given {@code initialTrackingTokenSupplier}. This effectively causes * a replay since that position. * <p> * Note that the new token must represent a position that is <em>before</em> the current position of the processor. * <p> * Before attempting to reset the tokens, the caller must stop this processor, as well as any instances of the * same logical processor that may be running in the cluster. Failure to do so will cause the reset to fail, * as a processor can only reset the tokens if it is able to claim them all. * * @param initialTrackingTokenSupplier A function returning the token representing the position to reset to */ public void resetTokens(Function<StreamableMessageSource, TrackingToken> initialTrackingTokenSupplier) { resetTokens(initialTrackingTokenSupplier.apply(messageSource)); }