scalaspring / akka-spring-boot

Apache License 2.0
48 stars 12 forks source link

Cannot read list property from Spring #5

Open neg3ntropy opened 8 years ago

neg3ntropy commented 8 years ago

I want to set via spring properties the cassandra hosts for akka-persistence.

This is the reference.conf:

akka {
  persistence {
    journal {
        plugin = cassandra-journal
    }
  }
}

cassandra-journal {
    # this is the key I want to override:
    #contact-points = [ "host" ]
    table = events
}

It seems that there is no syntax to make a list come out of the spring property cassandra-journal.contact-points:

com.typesafe.config.ConfigException$WrongType: hardcoded value: contact-points has type STRING rather than LIST
    at com.typesafe.config.impl.SimpleConfig.findKeyOrNull(SimpleConfig.java:159) ~[config-1.3.0.jar:na]
    at com.typesafe.config.impl.SimpleConfig.findOrNull(SimpleConfig.java:170) ~[config-1.3.0.jar:na]
    at com.typesafe.config.impl.SimpleConfig.find(SimpleConfig.java:184) ~[config-1.3.0.jar:na]
    at com.typesafe.config.impl.SimpleConfig.find(SimpleConfig.java:189) ~[config-1.3.0.jar:na]
    at com.typesafe.config.impl.SimpleConfig.getList(SimpleConfig.java:252) ~[config-1.3.0.jar:na]
    at com.typesafe.config.impl.SimpleConfig.getHomogeneousUnwrappedList(SimpleConfig.java:323) ~[config-1.3.0.jar:na]
    at com.typesafe.config.impl.SimpleConfig.getStringList(SimpleConfig.java:381) ~[config-1.3.0.jar:na]
    at akka.persistence.cassandra.ConfigSessionProvider.lookupContactPoints(ConfigSessionProvider.scala:147) ~[akka-persistence-cassandra_2.11-0.14.jar:0.14]
    at akka.persistence.cassandra.ConfigSessionProvider.clusterBuilder(ConfigSessionProvider.scala:85) ~[akka-persistence-cassandra_2.11-0.14.jar:0.14]
    at akka.persistence.cassandra.ConfigSessionProvider.connect(ConfigSessionProvider.scala:42) ~[akka-persistence-cassandra_2.11-0.14.jar:0.14]
    at akka.persistence.cassandra.CassandraSession.akka$persistence$cassandra$CassandraSession$$setup$1(CassandraSession.scala:67) ~[akka-persistence-cassandra_2.11-0.14.jar:0.14]
    at akka.persistence.cassandra.CassandraSession$$anonfun$1.apply(CassandraSession.scala:91) ~[akka-persistence-cassandra_2.11-0.14.jar:0.14]
    at akka.persistence.cassandra.CassandraSession$$anonfun$1.apply(CassandraSession.scala:91) ~[akka-persistence-cassandra_2.11-0.14.jar:0.14]
    at akka.persistence.cassandra.CassandraSession.akka$persistence$cassandra$CassandraSession$$trySetup$1(CassandraSession.scala:118) ~[akka-persistence-cassandra_2.11-0.14.jar:0.14]
    at akka.persistence.cassandra.CassandraSession.retry(CassandraSession.scala:129) ~[akka-persistence-cassandra_2.11-0.14.jar:0.14]
    at akka.persistence.cassandra.CassandraSession.underlying(CassandraSession.scala:91) ~[akka-persistence-cassandra_2.11-0.14.jar:0.14]
    at akka.persistence.cassandra.CassandraSession.prepare(CassandraSession.scala:135) ~[akka-persistence-cassandra_2.11-0.14.jar:0.14]
    at akka.persistence.cassandra.journal.CassandraJournal.preparedSelectDeletedTo(CassandraJournal.scala:88) ~[akka-persistence-cassandra_2.11-0.14.jar:0.14]
    at akka.persistence.cassandra.journal.CassandraRecovery$class.asyncHighestDeletedSequenceNumber(CassandraRecovery.scala:77) ~[akka-persistence-cassandra_2.11-0.14.jar:0.14]
    at akka.persistence.cassandra.journal.CassandraJournal.asyncHighestDeletedSequenceNumber(CassandraJournal.scala:38) ~[akka-persistence-cassandra_2.11-0.14.jar:0.14]
    at akka.persistence.cassandra.journal.CassandraRecovery$class.asyncReadHighestSequenceNr(CassandraRecovery.scala:47) ~[akka-persistence-cassandra_2.11-0.14.jar:0.14]
    at akka.persistence.cassandra.journal.CassandraJournal.asyncReadHighestSequenceNr(CassandraJournal.scala:266) ~[akka-persistence-cassandra_2.11-0.14.jar:0.14]
    at akka.persistence.journal.AsyncWriteJournal$$anonfun$1$$anonfun$applyOrElse$6.apply(AsyncWriteJournal.scala:133) ~[akka-persistence_2.11-2.4.6.jar:na]
    at akka.persistence.journal.AsyncWriteJournal$$anonfun$1$$anonfun$applyOrElse$6.apply(AsyncWriteJournal.scala:133) ~[akka-persistence_2.11-2.4.6.jar:na]
    at akka.pattern.CircuitBreaker$State$class.materialize$1(CircuitBreaker.scala:298) ~[akka-actor_2.11-2.4.6.jar:na]
    at akka.pattern.CircuitBreaker$State$class.callThrough(CircuitBreaker.scala:315) ~[akka-actor_2.11-2.4.6.jar:na]
    at akka.pattern.CircuitBreaker$Closed$.callThrough(CircuitBreaker.scala:363) ~[akka-actor_2.11-2.4.6.jar:na]
    at akka.pattern.CircuitBreaker$Closed$.invoke(CircuitBreaker.scala:371) ~[akka-actor_2.11-2.4.6.jar:na]
    at akka.pattern.CircuitBreaker.withCircuitBreaker(CircuitBreaker.scala:115) ~[akka-actor_2.11-2.4.6.jar:na]
    at akka.persistence.journal.AsyncWriteJournal$$anonfun$1.applyOrElse(AsyncWriteJournal.scala:133) ~[akka-persistence_2.11-2.4.6.jar:na]
    at scala.PartialFunction$OrElse.applyOrElse(PartialFunction.scala:170) ~[scala-library-2.11.8.jar:na]
    at akka.actor.Actor$class.aroundReceive(Actor.scala:482) ~[akka-actor_2.11-2.4.6.jar:na]
    at akka.persistence.cassandra.journal.CassandraJournal.aroundReceive(CassandraJournal.scala:38) ~[akka-persistence-cassandra_2.11-0.14.jar:0.14]
    at akka.actor.ActorCell.receiveMessage(ActorCell.scala:526) [akka-actor_2.11-2.4.6.jar:na]
    at akka.actor.ActorCell.invoke(ActorCell.scala:495) [akka-actor_2.11-2.4.6.jar:na]
    at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:257) [akka-actor_2.11-2.4.6.jar:na]
    at akka.dispatch.Mailbox.run(Mailbox.scala:224) [akka-actor_2.11-2.4.6.jar:na]
    at akka.dispatch.Mailbox.exec(Mailbox.scala:234) [akka-actor_2.11-2.4.6.jar:na]
    at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260) [scala-library-2.11.8.jar:na]
    at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339) [scala-library-2.11.8.jar:na]
    at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979) [scala-library-2.11.8.jar:na]
    at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107) [scala-library-2.11.8.jar:na]

Any help is appreciated.

lancearlaus commented 8 years ago

Have you tried using the following list property syntax? For example:

cassandra-journal.contact-points[0] = host1
cassandra-journal.contact-points[1] = host2

This is supported and part of the test suite for the project. Unit test can be found here: https://github.com/scalaspring/akka-spring-boot/blob/master/src/test/scala/com/github/scalaspring/akka/config/AkkaConfigPropertySourceAdapterSpec.scala#L43

Please let me know if that doesn't work.

neg3ntropy commented 8 years ago

I had tried that:

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'akkaConfig' defined in class com.github.scalaspring.akka.config.AkkaConfigAutoConfiguration: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.typesafe.config.Config]: Factory method 'akkaConfig' threw exception; nested exception is com.typesafe.config.ConfigException$BadPath: path parameter: Invalid path 'cassandra-journal.contact-points[0]': Token not allowed in path expression: '[' (you can double-quote this token if you really want it here)
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:599) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1123) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1018) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:510) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1192) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1116) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1014) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:813) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:741) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    ... 34 common frames omitted
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.typesafe.config.Config]: Factory method 'akkaConfig' threw exception; nested exception is com.typesafe.config.ConfigException$BadPath: path parameter: Invalid path 'cassandra-journal.contact-points[0]': Token not allowed in path expression: '[' (you can double-quote this token if you really want it here)
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:189) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:588) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    ... 47 common frames omitted
Caused by: com.typesafe.config.ConfigException$BadPath: path parameter: Invalid path 'cassandra-journal.contact-points[0]': Token not allowed in path expression: '[' (you can double-quote this token if you really want it here)
    at com.typesafe.config.impl.PathParser.parsePathExpression(PathParser.java:155) ~[config-1.3.0.jar:na]
    at com.typesafe.config.impl.PathParser.parsePathExpression(PathParser.java:74) ~[config-1.3.0.jar:na]
    at com.typesafe.config.impl.PathParser.parsePath(PathParser.java:61) ~[config-1.3.0.jar:na]
    at com.typesafe.config.impl.Path.newPath(Path.java:230) ~[config-1.3.0.jar:na]
    at com.typesafe.config.impl.PropertiesParser.fromPathMap(PropertiesParser.java:79) ~[config-1.3.0.jar:na]
    at com.typesafe.config.impl.ConfigImpl.fromAnyRef(ConfigImpl.java:264) ~[config-1.3.0.jar:na]
    at com.typesafe.config.impl.ConfigImpl.fromPathMap(ConfigImpl.java:200) ~[config-1.3.0.jar:na]
    at com.typesafe.config.ConfigFactory.parseMap(ConfigFactory.java:1084) ~[config-1.3.0.jar:na]
    at com.typesafe.config.ConfigFactory.parseMap(ConfigFactory.java:1095) ~[config-1.3.0.jar:na]
    at com.github.scalaspring.akka.config.AkkaConfigAutoConfiguration.akkaConfig(AkkaConfigAutoConfiguration.java:47) ~[akka-spring-boot_2.11-0.3.1.jar:0.3.1]
    at com.github.scalaspring.akka.config.AkkaConfigAutoConfiguration$$EnhancerBySpringCGLIB$$e1c717b7.CGLIB$akkaConfig$0(<generated>) ~[akka-spring-boot_2.11-0.3.1.jar:0.3.1]
    at com.github.scalaspring.akka.config.AkkaConfigAutoConfiguration$$EnhancerBySpringCGLIB$$e1c717b7$$FastClassBySpringCGLIB$$6e24c446.invoke(<generated>) ~[akka-spring-boot_2.11-0.3.1.jar:0.3.1]
    at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228) ~[spring-core-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:355) ~[spring-context-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at com.github.scalaspring.akka.config.AkkaConfigAutoConfiguration$$EnhancerBySpringCGLIB$$e1c717b7.akkaConfig(<generated>) ~[akka-spring-boot_2.11-0.3.1.jar:0.3.1]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_91]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_91]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_91]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_91]
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:162) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    ... 48 common frames omitted
neg3ntropy commented 8 years ago

Edited: the problem remains

neg3ntropy commented 8 years ago

This is a sample config to reproduce:

reference.conf:

akka {

  loggers = ["akka.event.slf4j.Slf4jLogger"]
  logger-startup-timeout = 10s
  loglevel= DEBUG
  stdout-loglevel= ERROR    

  persistence {

    journal {
        plugin = cassandra-journal
    }

    snapshot-store {
        plugin= cassandra-snapshot-store
    }
  }
}

cassandra-journal {

# https://github.com/scalaspring/akka-spring-boot/issues/5#issuecomment-228564865
# cannot override contact point from properties
    contact-points = [ "localhost" ]
    keyspace = "ks"

    table = events
}

application.properties

cassandra-journal.contact-points[0] = localhost

Thanks for looking into it

pspiegel commented 7 years ago

Hi soulrebel We also have a cassandra-journal in our project and have faced the same problem. We finally achieved this the following way (in application.yml file, shared by spring and akka):

akka.persistence:
    journal.plugin: 'cassandra-journal'

# Cassandra Settings
cassandra-journal:
  contact-points.0: 10.1.17.1
  contact-points.1: 10.1.17.2
  contact-points.2: 10.1.17.3
  port: 9042

or in HOCON notation about this way:

akka.persistence {
   journal.plugin = cassandra-journal
}

cassandra-journal {
   contact-points.0 = 10.1.17.1
   contact-points.1 = 10.1.17.2
   contact-points.2 = 10.1.17.3
}