How to set a bucket password with spring-data couchbase

1.4k views Asked by At

I have followed the tutorial for spring-data couchbase and have a succesfull example project with unit tests for persisting a number of custom entities with a range of views implemented to query the entities.

This works correctly in both a local dev environment and a ci environment when using the "default" bucket name and no password as the authentication.

Moving beyond the example, I want to make use of a different bucket and ultimately make use of a password.

When I create a new bucket (named "test_bucket"), and update the property injected into the CouchbaseConfig (extends AbstractCouchbaseConfiguration) to use this new bucket inplace of the "default" I get the following exception when running the unit tests.

I also tried adding a password to the creation script and adding the same password ("psswd" string in both cases) to the properties used in the CouchbaseConfig but get the same exception shown below.

So is it possible to use another bucket than "default" (and its no-authorisation required) and how do I configure a password for use on this bucket ?

I have verified that the bucket(s) and the expected views have been created correctly in couchbase from the Admin GUI.

2015-06-09 16:41:40 INFO  ClasspathLoggingApplicationListener:55 - Application failed to start with classpath: [file:/C:/tools/cmd/cygwin64/home/akirby/workspaces/repos/blackjack/persistence/target/surefire/surefirebooter7615727324811258159.jar]
2015-06-09 16:41:40 INFO  AutoConfigurationReportLoggingInitializer:107 -

Error starting ApplicationContext. To display the auto-configuration report enabled debug logging (start with --debug)

2015-06-09 16:41:40 ERROR SpringApplication:338 - Application startup failed
java.lang.NoSuchMethodError:     org.apache.commons.codec.binary.Base64.encodeBase64String([B)Ljava/lang/String;
    at com.couchbase.client.http.HttpUtil.buildAuthHeader(HttpUtil.java:55)
    at com.couchbase.client.ViewConnection.addOp(ViewConnection.java:205)
    at com.couchbase.client.CouchbaseClient.addOp(CouchbaseClient.java:803)
    at com.couchbase.client.CouchbaseClient.asyncGetView(CouchbaseClient.java:342)
    at com.couchbase.client.CouchbaseClient.getView(CouchbaseClient.java:430)
    at org.springframework.data.couchbase.core.CouchbaseTemplate$2.doInBucket(CouchbaseTemplate.java:223)
    at org.springframework.data.couchbase.core.CouchbaseTemplate$2.doInBucket(CouchbaseTemplate.java:220)
    at org.springframework.data.couchbase.core.CouchbaseTemplate.execute(CouchbaseTemplate.java:244)
    at org.springframework.data.couchbase.core.CouchbaseTemplate.queryView(CouchbaseTemplate.java:220)
    at org.springframework.data.couchbase.repository.support.SimpleCouchbaseRepository.deleteAll(SimpleCouchbaseRepository.java:168)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.executeMethodOn(RepositoryFactorySupport.java:416)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:401)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:373)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$DefaultMethodInvokingMethodInterceptor.invoke(RepositoryFactorySupport.java:486)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.data.couchbase.repository.support.ViewPostProcessor$ViewInterceptor.invoke(ViewPostProcessor.java:87)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
    at com.sun.proxy.$Proxy50.deleteAll(Unknown Source)
    at com.pubtech.cms.persistence.RepositoryService.doWork(RepositoryService.java:47)
    at com.pubtech.cms.persistence.ApplicationRepository.lambda$commandLineRunner$0(ApplicationRepository.java:83)
    at com.pubtech.cms.persistence.ApplicationRepository$$Lambda$9/594916129.run(Unknown Source)
    at org.springframework.boot.SpringApplication.runCommandLineRunners(SpringApplication.java:672)
    at org.springframework.boot.SpringApplication.afterRefresh(SpringApplication.java:690)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:321)
    at org.springframework.boot.test.SpringApplicationContextLoader.loadContext(SpringApplicationContextLoader.java:101)
    at org.springframework.test.context.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:68)
    at org.springframework.test.context.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:86)
    at org.springframework.test.context.DefaultTestContext.getApplicationContext(DefaultTestContext.java:72)
    at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:170)
    at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:110)
    at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:212)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:200)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:259)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:261)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:219)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:83)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:68)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:163)
    at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:264)
    at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:153)
    at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:124)
    at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:200)
    at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:153)
    at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:103)
2015-06-09 16:41:40 INFO  GenericWebApplicationContext:862 - Closing org.springframework.web.context.support.GenericWebApplicationContext@6302bbb1: startup date [Tue Jun 09 16:41:33 BST 2015]; root of context hierarchy
2015-06-09 16:41:40 INFO  CouchbaseConnection:87 - Shut down Couchbase client
2015-06-09 16:41:40 INFO  ViewConnection:87 - I/O reactor terminated

when using a bucket name that requires a password (bucket "t1", password "pswd") I see this authentication error in the logs, is there some format. other than plain text that the passsord should be encoded with ?

2015-06-10 10:55:58 INFO  DefaultListableBeanFactory:822 - Overriding bean definition for bean 'beanNameViewResolver': replacing [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration$WhitelabelErrorViewConfiguration; factoryMethodName=beanNameViewResolver; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/springframework/boot/autoconfigure/web/ErrorMvcAutoConfiguration$WhitelabelErrorViewConfiguration.class]] with [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration$WebMvcAutoConfigurationAdapter; factoryMethodName=beanNameViewResolver; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration$WebMvcAutoConfigurationAdapter.class]]
2015-06-10 10:55:59 INFO  Version:27 - HV000001: Hibernate Validator 5.1.3.Final
2015-06-10 10:56:00 ERROR SASLStepOperationImpl:93 - Error:  Auth failure
2015-06-10 10:56:00 WARN  BinaryMemcachedNodeImpl:90 - Discarding partially completed op: SASL steps operation
2015-06-10 10:56:00 WARN  AuthThread:90 - Authentication failed to localhost/127.0.0.1:11210, Status: {OperationStatus success=false:  cancelled}
2015-06-10 10:56:02 WARN  AuthThread:90 - Authentication failed to localhost/127.0.0.1:11210, Status: {OperationStatus success=false:  Invalid arguments}
2015-06-10 10:56:02 WARN  AuthThread:90 - Authentication failed to localhost/127.0.0.1:11210, Status: {OperationStatus success=false:  Invalid arguments}

I use the couchbase-cli to create the buckets from a script, using the same script to create the working "default" and not working "test_bucket", (properties are correctly injected using mvn filter) :

# Create Bucket
couchbase-cli bucket-create -c $COUCHBASE_HOST:$COUCHBASE_PORT -u $CB_REST_USERNAME -p $CB_REST_PASSWORD \
   --bucket=$BUCKET_NAME \
   --bucket-type=couchbase \
   --bucket-ramsize=200 \
   --bucket-replica=1 \
   --wait

CouchbaseConfig class:

..
@Configuration
@EnableCouchbaseRepositories(basePackages = {"com.persistence.db"})
@EnableAutoConfiguration
public class CouchbaseConfig extends AbstractCouchbaseConfiguration {

@Value("${couchbase.bucket:boris}")
private String bucketName;

@Value("${couchbase.bucket.password:nopwd}")
private String password;

@Value("${couchbase.host:127.0.0.1}")
private String ip;

..
1

There are 1 answers

2
Shaun Stone On

I think you got a similar issue to what i was experiencing, the issue for me was using @Value in an @Configuration class has a slight special requirement. I was using YAML for my properties file if that matters at all.

add this to your class (must be static as well)

/**
 * this is required for some reason: https://jira.spring.io/browse/SPR-11773
 * 
 * @return
 */
@Bean
public static PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer() {
    return new PropertySourcesPlaceholderConfigurer();