/*
* Copyright 2012-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.retry.annotation;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertTrue;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.retry.backoff.Sleeper;
/**
* @author Dave Syer
*
*/
public class EnableRetryWithBackoffTests {
@Test
public void vanilla() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
TestConfiguration.class);
Service service = context.getBean(Service.class);
service.service();
assertEquals("[1000, 1000]", context.getBean(PeriodSleeper.class)
.getPeriods().toString());
assertEquals(3, service.getCount());
context.close();
}
@Test
public void type() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
TestConfiguration.class);
RandomService service = context.getBean(RandomService.class);
service.service();
List<Long> periods = context.getBean(PeriodSleeper.class).getPeriods();
assertTrue("Wrong periods: " + periods, periods.get(0) > 1000);
assertEquals(3, service.getCount());
context.close();
}
@Test
public void exponential() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
TestConfiguration.class);
ExponentialService service = context.getBean(ExponentialService.class);
service.service();
assertEquals(3, service.getCount());
assertEquals("[1000, 1100]", context.getBean(PeriodSleeper.class)
.getPeriods().toString());
context.close();
}
@Test
public void randomExponential() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
TestConfiguration.class);
ExponentialRandomService service = context
.getBean(ExponentialRandomService.class);
service.service(1);
assertEquals(3, service.getCount());
List<Long> periods = context.getBean(PeriodSleeper.class).getPeriods();
assertNotEquals("[1000, 1100]", context.getBean(PeriodSleeper.class)
.getPeriods().toString());
assertTrue("Wrong periods: " + periods, periods.get(0) > 1000);
assertTrue("Wrong periods: " + periods, periods.get(1) > 1100
&& periods.get(1) < 1210);
context.close();
}
@Configuration
@EnableRetry
@EnableAspectJAutoProxy(proxyTargetClass = true)
protected static class TestConfiguration {
@Bean
public PeriodSleeper sleper() {
return new PeriodSleeper();
}
@Bean
public Service service() {
return new Service();
}
@Bean
public RandomService retryable() {
return new RandomService();
}
@Bean
public ExponentialRandomService stateful() {
return new ExponentialRandomService();
}
@Bean
public ExponentialService excludes() {
return new ExponentialService();
}
}
@SuppressWarnings("serial")
protected static class PeriodSleeper implements Sleeper {
private List<Long> periods = new ArrayList<Long>();
@Override
public void sleep(long period) throws InterruptedException {
periods.add(period);
}
private List<Long> getPeriods() {
return periods;
}
}
protected static class Service {
private int count = 0;
@Retryable(backoff = @Backoff(delay = 1000))
public void service() {
if (count++ < 2) {
throw new RuntimeException("Planned");
}
}
public int getCount() {
return count;
}
}
@Retryable(backoff = @Backoff(delay = 1000, maxDelay = 2000))
protected static class RandomService {
private int count = 0;
public void service() {
if (count++ < 2) {
throw new RuntimeException("Planned");
}
}
public int getCount() {
return count;
}
}
protected static class ExponentialService {
private int count = 0;
@Retryable(backoff = @Backoff(delay = 1000, maxDelay = 2000, multiplier = 1.1))
public void service() {
if (count++ < 2) {
throw new IllegalStateException("Planned");
}
}
public int getCount() {
return count;
}
}
protected static class ExponentialRandomService {
private int count = 0;
@Retryable(backoff = @Backoff(delay = 1000, maxDelay = 2000, multiplier = 1.1, random = true))
public void service(int value) {
if (count++ < 2) {
throw new RuntimeException("Planned");
}
}
public int getCount() {
return count;
}
}
}