Spring Boot2 ,Connecting to multiple bucket thread safety and reconnectivity of cluster

Hi All,
I am trying to connect to multiple buckets using couchbase repositories in spring boot with spring data.
I am using below classes to achieve it.

  • CouchBaseClusterProvider=> A singleton class which returns the Cluster object after authentication

Does this class work if couchbase server restarted without restarting the spring boot server?Will the Cluster automatically reconnects?

  • GeneralConfigurer class implements CouchbaseConfigurer and it opens the default bucket(configurationBucketName) and stores messageBucket in cache .

On couchbase server restart will the connection prevail?

  • GeneralBucketConfig class does @configuration and @EnableCouchbaseRepositories and create additional template messageConfigTemplate other thanthedefaulttemplate.

Please go through the code and advice me on reconnectivity after couchbase restarts?
Does caching of buckets permitted and advice to do?

Thanks
Isuru

public class CouchbaseClusterProvider {

private Cluster cluster;

private static volatile CouchbaseClusterProvider INSTANCE;

private CouchbaseClusterProvider(List<String> host, String bucketRootUserName, String password) {
	 cluster = CouchbaseCluster.create(host);
	cluster.authenticate(bucketRootUserName, password);
}

public static CouchbaseClusterProvider getInstance(List<String> host, String bucketRootUserName, String password) {
	if (INSTANCE == null) {
		synchronized (CouchbaseClusterProvider.class) {

			if (INSTANCE == null) {
				INSTANCE = new CouchbaseClusterProvider(host, bucketRootUserName, password);
			}
		}
	}
	return INSTANCE;
}

public Cluster getCluster() {
	return cluster;
}

}

@Component
public class GeneralConfigurer implements CouchbaseConfigurer {
@Value("#{environment.getProperty(‘connect_couchbase_rootPassword’)}")
private String bucketRootPassword;

// Implement RBAC in Couchbase6
@Value("#{environment.getProperty('connect_couchbase_rootUser')}")
private String bucketRootUserName;

@Value("#{environment.getProperty('connect_couchbase_server')}")
private String hosts;

@Value("#{environment.getProperty('connect_couchbase_configuration_bucketName')}")
protected String configurationBucketName;
private Map<String, Bucket> buckets = new ConcurrentHashMap<>();


@Value("#{environment.getProperty('connect_couchbase_message_bucketName')}")
protected String messageBucketName;

private  List<String> getBootstrapHosts() {
	return Arrays.asList(hosts.split(","));
}

@Override
public CouchbaseEnvironment couchbaseEnvironment() throws Exception {
	 return DefaultCouchbaseEnvironment.builder()
		        .connectTimeout(60000)
		        .kvTimeout(60000)
		        .queryTimeout(60000)
		        .viewTimeout(60000)
		        .build();
}

@Override
public Cluster couchbaseCluster() throws Exception {
	// TODO Auto-generated method stub
	return  CouchbaseClusterProvider.getInstance(getBootstrapHosts(),
			bucketRootUserName, bucketRootPassword).getCluster();
}

@Override
public ClusterInfo couchbaseClusterInfo() throws Exception {
	// TODO Auto-generated method stub
	return couchbaseCluster().clusterManager().info();
}

@Override
public synchronized Bucket couchbaseClient() throws Exception {
	// TODO Auto-generated method stub
	return getBucketFromCache(configurationBucketName);
}

public synchronized Bucket messageBucket() throws Exception {		
	return getBucketFromCache(messageBucketName);		
}

private Bucket getBucketFromCache(String bucketName) throws Exception{

	if(!buckets.containsKey(bucketName)) {
        Bucket bucket = couchbaseCluster().openBucket(bucketName);
        buckets.put(bucketName, bucket);
    }
    return buckets.get(bucketName);
}

@Configuration
@EnableCouchbaseRepositories
public class GeneralBucketConfig extends AbstractCouchbaseDataConfiguration {
@Autowired
GeneralConfigurer generalConfigurer;

public CouchbaseTemplate messageConfigTemplate() throws Exception {
	CouchbaseTemplate template = new CouchbaseTemplate(
			couchbaseConfigurer().couchbaseClusterInfo(), generalConfigurer.messageBucket(),
			mappingCouchbaseConverter(), translationService());
	template.setDefaultConsistency(getDefaultConsistency());
	return template;
}

@Override
  public void configureRepositoryOperationsMapping(RepositoryOperationsMapping baseMapping) {
    try {
		baseMapping
		  .mapEntity(Api.class, couchbaseTemplate())
		.mapEntity(Connector.class, couchbaseTemplate())
		.mapEntity(ConnectorParameter.class, couchbaseTemplate())			
		.mapEntity(Subscriber.class, couchbaseTemplate()).map(RouteRepository.class, couchbaseTemplate())
		.mapEntity(MessageTest.class, messageConfigTemplate()).map(MessageBucketRepository.class, messageConfigTemplate())
		;
		
		
	} catch (Exception e) {
		// TODO Auto-generated catch block
		throw new RuntimeException("Mapping error occured");
	} 
  }

@Override
protected CouchbaseConfigurer couchbaseConfigurer() {
	// TODO Auto-generated method stub
	return generalConfigurer;
}	

}

Hi @iisuru,

  • CouchBaseClusterProvider=> A singleton class which returns the Cluster object after authentication

RBAC should be available with SDC lovelace releases (3.1+)

  • GeneralConfigurer class implements CouchbaseConfigurer and it opens the default bucket(configurationBucketName) and stores messageBucket in cache .

Bucket instances are already cached in the client, not necessary for an external cached

On couchbase server restart will the connection prevail?
Yes, the client would try to reconnect automatically.

Hi Subashini,
Thanks for the reply.
Rgds,
Isuru