Skip to content

Instantly share code, notes, and snippets.

@ricardobaumann
Last active February 9, 2022 13:41
Show Gist options
  • Save ricardobaumann/4715b7fbce0ced0f4d63a3dbd8dc8010 to your computer and use it in GitHub Desktop.
Save ricardobaumann/4715b7fbce0ced0f4d63a3dbd8dc8010 to your computer and use it in GitHub Desktop.
Configure a retryable data source for spring boot services, with resilience4j
resilience4j.retry.instances.dbconn.max-attempts=3
resilience4j.retry.instances.dbconn.wait-duration=1s
plugins {
id 'org.springframework.boot' version '2.6.3'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id 'java'
}
group = 'com.ricbau'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-data-rest'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.liquibase:liquibase-core'
implementation("io.github.resilience4j:resilience4j-spring-boot2:1.7.0")
implementation("org.springframework.boot:spring-boot-starter-aop")
compileOnly 'org.projectlombok:lombok'
runtimeOnly 'org.postgresql:postgresql'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
tasks.named('test') {
useJUnitPlatform()
}
@Slf4j
@RequiredArgsConstructor
public class RetryableDataSource extends AbstractDataSource {
private final DataSource dataSource;
@Override
@Retry(name = "dbconn", fallbackMethod = "connectionFailed")
public Connection getConnection() throws SQLException {
log.info("Getting a connection no args");
return dataSource.getConnection();
}
@SneakyThrows
private Connection connectionFailed(Exception e) {
//Just to confirm the retry logic usage
log.warn("Failed to get a connection from data source after retrying");
throw e;
}
@Override
@Retry(name = "dbconn", fallbackMethod = "connectionFailed")
public Connection getConnection(String username, String password) throws SQLException {
log.info("Getting a connection for {} - {}", username, password);
return dataSource.getConnection(username, password);
}
}
@Slf4j
@Order(value = Ordered.HIGHEST_PRECEDENCE)
@Component
public class RetryableDataSourcePostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof DataSource) {
log.info("Configuring retryable data source");
return new RetryableDataSource((DataSource) bean);
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment