[英]Spring Retry Junit: Testing Retry template with Custom Retry Policy
我正在嘗試測試使用自定義重試策略的重試模板。 為了做到這一點,我使用以下示例:
基本上,我的目標是在收到某些特定的http錯誤狀態(例如,http 500錯誤狀態)時測試重試邏輯。
這是我的junit的xml上下文:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:int="http://www.springframework.org/schema/integration"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:int-http="http://www.springframework.org/schema/integration/http"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/integration
http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/http
http://www.springframework.org/schema/integration/http/spring-integration-http.xsd">
<bean id="retryTemplate_test" class="org.springframework.retry.support.RetryTemplate">
<property name="retryPolicy">
<bean
class="util.CustomRetryPolicy">
<property name="maxAttempts" value="5" />
</bean>
</property>
<property name="backOffPolicy">
<bean class="org.springframework.retry.backoff.ExponentialBackOffPolicy">
<property name="initialInterval" value="1000" />
<property name="multiplier" value="6" />
</bean>
</property>
</bean>
</beans>
CustomRetryPolicy
類似於:
public class CustomRetryPolicy extends ExceptionClassifierRetryPolicy {
private String maxAttempts;
@PostConstruct
public void init() {
this.setExceptionClassifier(new Classifier<Throwable, RetryPolicy>() {
@Override
public RetryPolicy classify(Throwable classifiable) {
Throwable exceptionCause = classifiable.getCause();
if (exceptionCause instanceof HttpStatusCodeException) {
int statusCode = ((HttpStatusCodeException) classifiable.getCause()).getStatusCode().value();
return handleHttpErrorCode(statusCode);
}
return neverRetry();
}
});
}
public void setMaxAttempts(String maxAttempts) {
this.maxAttempts = maxAttempts;
}
private RetryPolicy handleHttpErrorCode(int statusCode) {
RetryPolicy retryPolicy = null;
switch(statusCode) {
case 404 :
case 500 :
case 503 :
case 504 :
retryPolicy = defaultRetryPolicy();
break;
default :
retryPolicy = neverRetry();
break;
}
return retryPolicy;
}
private RetryPolicy neverRetry() {
return new NeverRetryPolicy();
}
private RetryPolicy defaultRetryPolicy() {
final SimpleRetryPolicy simpleRetryPolicy = new SimpleRetryPolicy();
simpleRetryPolicy.setMaxAttempts(Integer.valueOf(maxAttempts));
return simpleRetryPolicy;
}
}
我正在測試的Java類是:
@RunWith( SpringJUnit4ClassRunner.class )
@ContextConfiguration(locations = {"classpath:my_context_for_test.xml"})
public class RetryTemplateTest{
@Autowired
@Qualifier("retryTemplate_test")
RetryTemplate retryTemplate_test;
@Test
public void testRetry() throws Throwable {
Map<Class<? extends Throwable>, Boolean> r = new HashMap<>();
r.put(HttpStatusCodeException.class, true);
MockRetryCallback callback = new MockRetryCallback();
callback.setAttemptsBeforeSuccess(5);
retryTemplate_test.execute(callback);
assertEquals(5, callback.attempts);
}
private static class MockRetryCallback implements RetryCallback<Object, HttpStatusCodeException> {
private int attempts;
private int attemptsBeforeSuccess;
@SuppressWarnings("serial")
@Override
public Object doWithRetry(RetryContext status) throws HttpStatusCodeException {
this.attempts++;
if (this.attempts < this.attemptsBeforeSuccess) {
System.out.println("I'm here: "+ this.attempts);
throw new HttpStatusCodeException(HttpStatus.INTERNAL_SERVER_ERROR) {
};
}
return null;
}
public void setAttemptsBeforeSuccess(int attemptsBeforeSuccess) {
this.attemptsBeforeSuccess = attemptsBeforeSuccess;
}
}
}
我究竟做錯了什么? 我的理解是,使用回調,我正在模擬響應,並以此(可以使用自定義重試策略)處理該響應。 也
[更新]
如果我嘗試復制這個junit ,那么我會遇到同樣的異常。 最具體地說,當嘗試在此處在MockRetryCallback
類中實例化異常時,它將失敗:
private Exception exceptionToThrow = new Exception();
我能夠使它與此一起工作:
@RunWith( SpringJUnit4ClassRunner.class )
@ContextConfiguration(locations = {"classpath:test-context.xml"})
public class HttpRetryTest{
@Autowired
@Qualifier("retryTemplate_test")
RetryOperations retryTemplate_test;
@Test
public void testRetry() throws Throwable {
Map<Class<? extends Throwable>, Boolean> r = new HashMap<>();
r.put(HttpStatusCodeException.class, true);
MockRetryCallback callback = new MockRetryCallback();
MockRetryCallback.attemptsBeforeSuccess =5;
retryTemplate_test.execute(callback);
assertEquals(5, MockRetryCallback.attempts);
}
private static class MockRetryCallback implements RetryCallback<Object, HttpStatusCodeException> {
private static int attempts;
private static int attemptsBeforeSuccess;
@SuppressWarnings("serial")
@Override
public Object doWithRetry(RetryContext status) throws HttpStatusCodeException {
MockRetryCallback.attempts++;
if (MockRetryCallback.attempts <= MockRetryCallback.attemptsBeforeSuccess) {
System.out.println("I'm here: "+ MockRetryCallback.attempts);
throw new HttpStatusCodeException(HttpStatus.INTERNAL_SERVER_ERROR) {
};
}
return null;
}
}
}
為了更簡單一些,您可以查看Failsafe :
RetryPolicy<Object> retryPolicy = new RetryPolicy<>()
.handleIf((HttpStatusCodeException e) -> e.getStatusCode().getValue() == 504)
.withMaxAttempts(maxAttempts);
Failsafe.with(retryPolicy).get(() -> doSomething);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.