package com.dbg.cloud.acheron.autoconfigure.store; import com.datastax.driver.core.Cluster; import com.datastax.driver.core.Session; import com.datastax.driver.core.exceptions.InvalidQueryException; import com.datastax.driver.core.exceptions.NoHostAvailableException; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.cassandra.core.CassandraOperations; import org.springframework.data.cassandra.core.CassandraTemplate; import java.util.concurrent.TimeUnit; @Configuration @ConditionalOnProperty(prefix = "store", value = "cassandra.enabled", havingValue = "true") @EnableConfigurationProperties(CassandraProperties.class) @Slf4j public class AcheronCassandraSetup { private final CassandraProperties cassandraProperties; private final int retryCount; private final int waitTimeBetweenRetriesInSec; public AcheronCassandraSetup(final CassandraProperties cassandraProperties) { this.cassandraProperties = cassandraProperties; this.retryCount = cassandraProperties.getInitialConnectionRetryCount() != null ? cassandraProperties.getInitialConnectionRetryCount() : 0; this.waitTimeBetweenRetriesInSec = cassandraProperties.getWaitTimeBeforeRetriesInSec() != null ? cassandraProperties.getWaitTimeBeforeRetriesInSec() : 5; } @Bean public CassandraOperations cassandraTemplate() { Session session = null; RuntimeException lastException = new IllegalStateException(); int remainingTries = 1 + retryCount; while (session == null && remainingTries > 0) { try { session = cluster().connect("acheron"); } catch (final NoHostAvailableException e) { lastException = e; log.info("Cassandra is not yet accepting connections. Retrying in {} seconds.", waitTimeBetweenRetriesInSec); } catch (final InvalidQueryException e) { lastException = e; log.info("Acheron DDL is not yet applied. Retrying in {} seconds.", waitTimeBetweenRetriesInSec); } finally { remainingTries--; if (session == null && remainingTries > 0) { try { Thread.sleep(TimeUnit.SECONDS.toMillis(waitTimeBetweenRetriesInSec)); } catch (final InterruptedException e) { // } } } } if (session == null) { throw lastException; } return new CassandraTemplate(session); } private Cluster cluster() { return Cluster.builder() .addContactPoints(cassandraProperties.getContactPoints()) .withPort(cassandraProperties.getPort()) .build(); } }