Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to connect to two different buckets of couchbase in spring boot

I am trying to connect to two different buckets in couchbase using spring boot. But in a single spring boot application the database config only takes a single bucket name.

Is it possible to connect to more than one couchbase bucket in spring-boot?

like image 929
piyush Avatar asked Apr 28 '16 15:04

piyush


2 Answers

So it seems you want to use Spring Data Couchbase from within a Spring Boot application, and have (at least) two different repositories backed by two different Bucket?

You'll have to customize your Spring Data configuration programmatically (as opposed to letting Spring Boot do all the heavy lifting), but that's possible.

  • Spring Boot creates a CouchbaseConfigurer through which it creates default Cluster and Bucket (as tuned in the properties file).
  • If you have a CouchbaseRepository on your classpath, it'll also attempt to configure Spring Data by instantiating a SpringBootCouchbaseDataConfiguration class.
  • You can customize that by extending the SpringBootCouchbaseDataConfiguration above in your project, marking it as @Configuration

Once you're ready to customize the Spring Data configuration programmatically, what you need is to create a second Bucket bean, a second CouchbaseTemplate that uses that bucket, and then instruct Spring Data Couchbase on which template to use with which Repository.

To that end, there is a configureRepositoryOperationsMapping(...) method. You can use the parameter of this method as a builder to:

  • link a specific Repository interface to a CouchbaseTemplate: map
  • say that any repo with a specific entity type should use a given template: mapEntity
  • even redefine the default template to use (initially the one created by Spring Boot): setDefault.

This second part is explained in the Spring Data Couchbase documentation.

like image 142
Simon Baslé Avatar answered Nov 02 '22 04:11

Simon Baslé


Probably what you are trying to say is that Spring boot provides pre-defined properties that you can modify, such as: couchbase.cluster.bucket that takes single value and you want to connect to two or more buckets.

In case you will not find a better solution, I can point you to a slightly different approach, and that is to setup your own couchbase connection manager that you can inject anywhere you need.

Here is the example of such @Service that will provider you with two connections to different buckets.

You can modify to suite your needs, it is very small.

import java.util.ArrayList;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.couchbase.client.java.Bucket;
import com.couchbase.client.java.Cluster;
import com.couchbase.client.java.CouchbaseCluster;
import com.couchbase.client.java.env.CouchbaseEnvironment;
import com.couchbase.client.java.env.DefaultCouchbaseEnvironment;

@Service
public class CouchbaseConnectionManager {
    private static final int TIMEOUT = 100000;

    @Value("#{configProp['couchbase.nodes']}")
    private List<String> nodes = new ArrayList<String>();

    @Value("#{configProp['couchbase.binary.bucketname']}")
    private String binaryBucketName;

    @Value("#{configProp['couchbase.nonbinary.bucketname']}")
    private String nonbinaryBucketName;

    @Value("#{configProp['couchbase.password']}")
    private String password;

    private Bucket binaryBucket;

    private Bucket nonbinaryBucket;

    private Cluster cluster;

    private static final Logger log = Logger.getLogger(CouchbaseConnectionManager.class);

    @PostConstruct
    public void createSession() {

        if (nodes != null && nodes.size() != 0) {
            try {
                CouchbaseEnvironment env = DefaultCouchbaseEnvironment.builder().connectTimeout(TIMEOUT).build();

                cluster = CouchbaseCluster.create(env, nodes);

                binaryBucket = cluster.openBucket(binaryBucketName, password);
                nonbinaryBucket = cluster.openBucket(nonbinaryBucketName, password);
                log.info(GOT_A_CONNECTION_TO_COUCHBASE_BUCKETS + binaryBucket + " " + nonbinaryBucket);
            } catch (Exception e) {
                log.warn(UNABLE_TO_GET_CONNECTION_TO_COUCHBASE_BUCKETS);
            }
        } else {
            log.warn(COUCH_NOT_CONFIGURED);
        }
    }

    @PreDestroy
    public void preDestroy() {
        if (cluster != null) {
            cluster.disconnect();
            log.info(SUCCESSFULLY_DISCONNECTED_FROM_COUCHBASE);
        }
    }

    public Bucket getBinaryBucket() {
        return binaryBucket;
    }

    public Bucket getNonbinaryBucket() {
        return nonbinaryBucket;
    }

    private static final String SUCCESSFULLY_DISCONNECTED_FROM_COUCHBASE = "Successfully disconnected from couchbase";
    private static final String GOT_A_CONNECTION_TO_COUCHBASE_BUCKETS = "Got a connection to couchbase buckets: ";
    private static final String COUCH_NOT_CONFIGURED = "COUCH not configured!!";
    private static final String UNABLE_TO_GET_CONNECTION_TO_COUCHBASE_BUCKETS = "Unable to get connection to couchbase buckets";
}
like image 42
Jenya G Avatar answered Nov 02 '22 04:11

Jenya G