-
Notifications
You must be signed in to change notification settings - Fork 70
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #441 from zalando/feature/logging-retry-listener
Added logging retry listener
- Loading branch information
Showing
6 changed files
with
198 additions
and
7 deletions.
There are no files selected for viewing
35 changes: 35 additions & 0 deletions
35
riptide-failsafe/src/main/java/org/zalando/riptide/failsafe/CompoundRetryListener.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
package org.zalando.riptide.failsafe; | ||
|
||
import net.jodah.failsafe.ExecutionContext; | ||
import org.apiguardian.api.API; | ||
import org.springframework.http.client.ClientHttpResponse; | ||
import org.zalando.riptide.RequestArguments; | ||
|
||
import javax.annotation.Nullable; | ||
import java.util.Arrays; | ||
import java.util.Collection; | ||
|
||
import static org.apiguardian.api.API.Status.EXPERIMENTAL; | ||
|
||
@API(status = EXPERIMENTAL) | ||
public final class CompoundRetryListener implements RetryListener { | ||
|
||
private final Collection<RetryListener> listeners; | ||
|
||
public CompoundRetryListener(final RetryListener... listeners) { | ||
this(Arrays.asList(listeners)); | ||
} | ||
|
||
public CompoundRetryListener(final Collection<RetryListener> listeners) { | ||
this.listeners = listeners; | ||
} | ||
|
||
@Override | ||
public void onRetry(final RequestArguments arguments, @Nullable final ClientHttpResponse result, | ||
@Nullable final Throwable failure, final ExecutionContext context) { | ||
|
||
listeners.forEach(listener -> | ||
listener.onRetry(arguments, result, failure, context)); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
36 changes: 36 additions & 0 deletions
36
riptide-failsafe/src/main/java/org/zalando/riptide/failsafe/LoggingRetryListener.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
package org.zalando.riptide.failsafe; | ||
|
||
import net.jodah.failsafe.ExecutionContext; | ||
import org.apiguardian.api.API; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
import org.springframework.http.client.ClientHttpResponse; | ||
import org.zalando.riptide.RequestArguments; | ||
|
||
import javax.annotation.Nullable; | ||
|
||
import static org.apiguardian.api.API.Status.EXPERIMENTAL; | ||
|
||
@API(status = EXPERIMENTAL) | ||
public final class LoggingRetryListener implements RetryListener { | ||
|
||
private final Logger logger; | ||
|
||
public LoggingRetryListener() { | ||
this(LoggerFactory.getLogger(LoggingRetryListener.class)); | ||
} | ||
|
||
public LoggingRetryListener(final Logger logger) { | ||
this.logger = logger; | ||
} | ||
|
||
@Override | ||
public void onRetry(final RequestArguments arguments, @Nullable final ClientHttpResponse result, | ||
@Nullable final Throwable failure, final ExecutionContext context) { | ||
|
||
if (failure != null) { | ||
logger.warn("Retrying failure", failure); | ||
} | ||
} | ||
|
||
} |
43 changes: 43 additions & 0 deletions
43
riptide-failsafe/src/test/java/org/zalando/riptide/failsafe/CompoundRetryListenerTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
package org.zalando.riptide.failsafe; | ||
|
||
import net.jodah.failsafe.Failsafe; | ||
import net.jodah.failsafe.RetryPolicy; | ||
import org.junit.Test; | ||
import org.zalando.riptide.RequestArguments; | ||
import org.zalando.riptide.failsafe.FailsafePlugin.RetryListenersAdapter; | ||
|
||
import java.util.concurrent.atomic.AtomicBoolean; | ||
|
||
import static org.mockito.ArgumentMatchers.any; | ||
import static org.mockito.ArgumentMatchers.eq; | ||
import static org.mockito.ArgumentMatchers.isNull; | ||
import static org.mockito.Mockito.mock; | ||
import static org.mockito.Mockito.verify; | ||
|
||
public final class CompoundRetryListenerTest { | ||
|
||
private final RetryListener first = mock(RetryListener.class); | ||
private final RetryListener second = mock(RetryListener.class); | ||
|
||
private final RetryListener unit = new CompoundRetryListener(first, second); | ||
|
||
@Test | ||
public void shouldPropagateRetryToEveryListener() { | ||
final AtomicBoolean success = new AtomicBoolean(false); | ||
|
||
final RequestArguments arguments = RequestArguments.create(); | ||
final IllegalStateException exception = new IllegalStateException(); | ||
|
||
Failsafe.with(new RetryPolicy().withMaxRetries(3)) | ||
.with(new RetryListenersAdapter(unit, arguments)) | ||
.run(() -> { | ||
if (!success.getAndSet(true)) { | ||
throw exception; | ||
} | ||
}); | ||
|
||
verify(first).onRetry(eq(arguments), isNull(), eq(exception), any()); | ||
verify(second).onRetry(eq(arguments), isNull(), eq(exception), any()); | ||
} | ||
|
||
} |
70 changes: 70 additions & 0 deletions
70
riptide-failsafe/src/test/java/org/zalando/riptide/failsafe/LoggingRetryListenerTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
package org.zalando.riptide.failsafe; | ||
|
||
import com.google.gag.annotation.remark.Hack; | ||
import net.jodah.failsafe.Failsafe; | ||
import net.jodah.failsafe.RetryPolicy; | ||
import org.junit.Test; | ||
import org.slf4j.Logger; | ||
import org.zalando.riptide.RequestArguments; | ||
import org.zalando.riptide.failsafe.FailsafePlugin.RetryListenersAdapter; | ||
|
||
import java.util.Objects; | ||
import java.util.concurrent.atomic.AtomicBoolean; | ||
|
||
import static org.mockito.ArgumentMatchers.any; | ||
import static org.mockito.ArgumentMatchers.eq; | ||
import static org.mockito.Mockito.mock; | ||
import static org.mockito.Mockito.verify; | ||
import static org.mockito.Mockito.verifyNoMoreInteractions; | ||
|
||
public final class LoggingRetryListenerTest { | ||
|
||
private final Logger logger = mock(Logger.class); | ||
private final RetryListener unit = new LoggingRetryListener(logger); | ||
|
||
@Test | ||
public void shouldLogFailure() { | ||
final AtomicBoolean success = new AtomicBoolean(false); | ||
|
||
final RequestArguments arguments = RequestArguments.create(); | ||
final IllegalStateException exception = new IllegalStateException(); | ||
|
||
Failsafe.with(new RetryPolicy().withMaxRetries(3)) | ||
.with(new RetryListenersAdapter(unit, arguments)) | ||
.run(() -> { | ||
if (!success.getAndSet(true)) { | ||
throw exception; | ||
} | ||
}); | ||
|
||
verify(logger).warn(any(), eq(exception)); | ||
} | ||
|
||
@Test | ||
public void shouldNotLogResults() { | ||
final AtomicBoolean success = new AtomicBoolean(false); | ||
|
||
final RequestArguments arguments = RequestArguments.create(); | ||
|
||
Failsafe.with(new RetryPolicy() | ||
.withMaxRetries(3) | ||
.retryIf(Objects::isNull)) | ||
.with(new RetryListenersAdapter(unit, arguments)) | ||
.get(() -> { | ||
if (!success.getAndSet(true)) { | ||
return null; | ||
} | ||
|
||
return "not null"; | ||
}); | ||
|
||
verifyNoMoreInteractions(logger); | ||
} | ||
|
||
@Hack("We're not really testing anything here, since we don't want to clutter the logs.") | ||
@Test | ||
public void shouldUseDefaultLogger() { | ||
new LoggingRetryListener(); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters