Giter VIP home page Giter VIP logo

lagom's Introduction

Gitter Join the contributors chat at https://gitter.im/lagom/contributors CI / Build and tests Open Source Helpers

Deprecated - Lagom - July 1 2023

This project will only recieve security patches until July 1, 2024, at that point the project will no longer receive any additional patches.

If you are an existing customer of Lightbend and we have not yet contacted you, please reach out to Support.

We recommend migrating any existing work to:

  • Akka for deeply customized projects with complex infrastructure needs. Akka now contains the vast majority of Lagom features.
  • Kalix for a managed scalable environment with an abstraction above the Akka framework layer to allow you to focus only on business logic.

Lagom - The Reactive Microservices Framework

Lagom is a Swedish word meaning just right, sufficient. Microservices are about creating services that are just the right size, that is, they have just the right level of functionality and isolation to be able to adequately implement a scalable and resilient system.

Lagom focuses on ensuring that your application realizes the full potential of the Reactive Manifesto while delivering a high productivity development environment, and seamless production deployment experience.

Learn More

License

Copyright (C) Lightbend Inc. (https://www.lightbend.com).

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this project except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

lagom's People

Contributors

2m avatar aldenml avatar ayushprashar avatar benmccann avatar beritou avatar dotta avatar dwijnand avatar ennru avatar erip avatar gmethvin avatar guizmaii avatar huntc avatar ignasi35 avatar ihostage avatar johanandren avatar jroper avatar jrudolph avatar kunals201 avatar marcospereira avatar markusjura avatar mergify[bot] avatar munandermaan avatar octonato avatar pallavisingh1992 avatar patriknw avatar raboof avatar rstento avatar scala-steward avatar timmoore avatar yg-apaza avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

lagom's Issues

Include comprehensive debug information in the error reporter when running in dev mode

Are you looking for help?

This is an issue tracker, used to manage and track the development of Lagom. It is not a support system and so it is not a place to ask questions or get help. If you're not sure if you have found a bug, the best place to start is with either the users mailing list or Stack Overflow. If you have a feature request, the contributors channel is a better forum than an issue tracker to discuss it.

Lagom Version (2.5.x / etc)

n/a

API (Scala / Java / Neither / Both)

n/a

Operating System (Ubuntu 15.10 / MacOS 10.10 / Windows 10)

Use uname -a if on Linux.

n/a

JDK (Oracle 1.8.0_72, OpenJDK 1.8.x, Azul Zing)

Paste the output from java -version at the command line.

n/a

Library Dependencies

If this is an issue that involves integration with another system, include the exact version and OS of the other system, including any intermediate drivers or APIs i.e. if you connect to a PostgreSQL database, include both the version / OS of PostgreSQL and the JDBC driver version used to connect to the database.

n/a

Expected Behavior

Please describe the expected behavior of the issue, starting from the first action.

  1. An exception is thrown when processing a service request
  2. An error response is generated
  3. For security reasons when running in Prod it should not disclose data which may contain sensitive or compromising information. But when running in Dev mode, emitting proper and thorough error information will improve the debugging lead time and create general happiness and prosperity in the solar system and elsewhere.

Actual Behavior

Please provide a description of what actually happens, working from the same starting point.

Be descriptive: "it doesn't work" does not describe what the behavior actually is -- instead, say "the page renders a 500 error code with no body content." Copy and paste logs, and include any URLs.

  1. An exception is thrown when processing a service request
  2. An error response is generated
  3. Which doesn't contain any interesting information, for security reasons.

Reproducible Test Case

Please provide a PR with a failing test.

throw null;

If the issue is more complex or requires configuration, please provide a link to a project on Github that reproduces the issue.

CPUs at 100% when running `runAll` on sample projects

Expected Behavior

CPUs usage should be to a minimum when idle.

Actual Behavior

From the gitter channel:

Trying out the basic hello world example, as well as chirper, I do notice however that running the app with "activator runAll" uses 100% of a cpu core (on OS X at least). Anyone else notice that?

I could reproduce it, and it seems to be that activator is partly to blame for using 100% on all CPUs, since if I'm running sbt runAll less CPUs are spinning (but I still get 4 out of 8 CPUs at 100%). I did a quick investigation, and I think the embedded Cassandra server is to blame for most of the remaining waste of CPUs cycles.

Reproducible Test Case

  • Run activator runAll and notice how all CPUs are busy at 100%. Compare with sbt runAll where less CPUs cycles seem to be wasted (and the waste seems to be due the next item). This seems an activator template issue.
  • Run sbt lagomCassandraStart on the chirper activator template and notice how many CPUs (in my case (4 out of 8) are extremely busy, doing nothing :-)

Dev mode is broken

Dev mode no longer reloads on master, because the dependency classpath contains all the project classes directories. When I stick a println on the dependency classpath (which should not contain any project classes directories, only jar files), I get the following:

/home/jroper/src/activator-lagom-java-chirper/chirp-impl/target/scala-2.11/classes
/home/jroper/src/activator-lagom-java-chirper/chirp-api/target/scala-2.11/classes
/home/jroper/src/activator-lagom-java-chirper/api-common/target/scala-2.11/classes
/home/jroper/src/activator-lagom-java-chirper/server-common/target/scala-2.11/classes
/home/jroper/.ivy2/cache/org.scala-lang/scala-library/jars/scala-library-2.11.7.jar
/home/jroper/.ivy2/local/com.lightbend.lagom/lagom-javadsl-api_2.11/1.0.0-private-1/jars/lagom-javadsl-api_2.11.jar
...

We should modify the scripted tests to check that the application is actually updated, to prevent regressions like this in future.

Support for SQL persistence module

Per the documentation:

We will not provide support for a wide range of other data stores, but if there is enough demand we might support some other, such as a SQL database.

This issue is for tracking demand for a SQL persistence module, +1 if this is something you would like.

`run` on root project should be an alias to `runAll`

Expected Behavior

Typing the usual run command on the root project of a Lagom build should be an alias to runAll, if the root project has not enabled the LagomJava sbt plugin.

Actual Behavior

Typing run on the lagom seed project (i.e., lagom-java) currently fails with the following exception:

"java.lang.RuntimeException: No main class detected.
    at scala.sys.package$.error(package.scala:27)"

This should not happen, as it hinders the getting started experience.

Reproducible Test Case

$ activator new my-first-system lagom-java
$ cd my-first-system
$ activator run

Update cache not working in dev mode

On master, the update cache is not working.

To illustrate, run chirper with Lagom 1.0.0-M1, using runAll. Then stop it. Then run runAll again. On the second run, every server should just start, without doing any resolving.

However, if using master, every project needs to be resolved every time you run runAll. Somehow the update cache isn't working.

Further more, it appears to be updating every project twice in parallel - this could explain why the update cache isn't working, the parallel runs are probably invalidating each other:

[info] Updating {file:/home/jroper/src/activator-lagom-java-chirper/}front-end...
[info] Resolving org.scala-lang#scala-library;2.11.7 ...
[info] Updating {file:/home/jroper/src/activator-lagom-java-chirper/}front-end...
[info] Resolving jline#jline;2.12.1 ...

This makes starting chirper very slow every time, not just the first time.

NPE when port conflict

I discovered this when running scripted sbt-plugin/run-service-locator and having the helloworld sample running at the same time. Probably a port conflict so it could not bind to the port (probably the fixed service locator port).

I guess this can happen if you accidentally start two Lagom shells also.

[info] java.lang.NullPointerException
[info]  at com.lightbend.lagom.discovery.ServiceLocatorServer.address(ServiceLocatorServer.scala:56)
[info]  at com.lightbend.lagom.discovery.ServiceLocatorServer.start(ServiceLocatorServer.scala:28)
[info]  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[info]  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
[info]  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[info]  at java.lang.reflect.Method.invoke(Method.java:497)
[info]  at com.lightbend.lagom.sbt.LagomPlugin$ServiceLocator$.start(LagomPlugin.scala:446)
[info]  at com.lightbend.lagom.sbt.LagomPlugin$AppLauncher$$anonfun$start$1.apply(LagomPlugin.scala:391)
[info]  at com.lightbend.lagom.sbt.LagomPlugin$AppLauncher$$anonfun$start$1.apply(LagomPlugin.scala:389)
[info]  at com.lightbend.lagom.sbt.LagomPlugin$AppLauncher.withContextClassloader(LagomPlugin.scala:410)
[info]  at com.lightbend.lagom.sbt.LagomPlugin$AppLauncher.start(LagomPlugin.scala:389)
[info]  at com.lightbend.lagom.sbt.LagomPlugin$$anonfun$com$lightbend$lagom$sbt$LagomPlugin$$startEmbeddedProjectService$1$$anonfun$apply$28.apply(LagomPlugin.scala:316)
[info]  at com.lightbend.lagom.sbt.LagomPlugin$$anonfun$com$lightbend$lagom$sbt$LagomPlugin$$startEmbeddedProjectService$1$$anonfun$apply$28.apply(LagomPlugin.scala:313)

Add first class support for the process manager pattern in Lagom

As agreed on the lagom-framework Google group, I'm opening an issue (feature request) for adding first class support for the DDD style process manager pattern in Lagom. My feeling is that such an extension would provide the missing piece of the puzzle for rapidly building DDD inspired systems using Lagom.

expire circuit breakers

Circuit breakers that are not used for some time (e.g. 5 minutes) should be cleaned up. There is also a method in the metrics SPI that should be called when they are removed.

Using runAll with the basic hello world consumes a lot of CPU on all cores.

Running on a Mac (OSX 10.11.4, 2.2 GHz Intel Core i7) with java version:
java version "1.8.0_65"
Java(TM) SE Runtime Environment (build 1.8.0_65-b17)
Java HotSpot(TM) 64-Bit Server VM (build 25.65-b01, mixed mode)

I'm seeing high CPU usage for the java process running Lagom stuff.

I'm just running the hello world, ala "activator new my-first-system lagom-java", then "cd my-first-system && sbt runAll".

Top shows:

PID COMMAND %CPU TIME #TH #WQ #PORT MEM PURG CMPRS PGRP PPID STATE BOOSTS
16094 java 246.5 11:57.44 84/2 0 206 637M+ 0B 0B 15993 16031 running *0[2]

where you can see that java process is using 246.5% CPU.

Stopping the system with CTRL-D returns things to normal.

Re-connecting to cassandra DB is not working

It feels that a Lagom service is not "always" able to re-connect to the cassandra DB. This can happen if the Lagom service is started before the cassandra DB. Tested the behaviour in a ConductR context. More info how to reproduce can be found below.

I am currently not sure if this is a general Lagom issue or if maybe the chirper example has things wrongly implemented. Interesting to note is that during my test the chirp-impl service couldn't connect to cassandra. The friend-impl service on the other hand could successfully re-connect to cassandra. Both services have been started before the cassandra bundle. More info can be found below in the Logs section.

How to reproduce
Tested the behaviour with chirper on ConductR 1.1.3:

cd activator-lagom-java-chirper
sbt
sandbox run 1.1.3 --feature logging
bundle:dist
conduct load <chirp-impl-bundle>
conduct load <activity-stream-impl-bundle>
conduct load <friend-impl-bundle>
project front-end
configuration:dist
conduct load <front-end-impl-bundle> <front-end-impl-configuration>
project /
cassandra-configuration:dist
conduct load cassandra <cassandra-configuration>
conduct run --no-wait activity
conduct run --no-wait friend
conduct run --no-wait chirp
conduct run front
conduct run cassandra

It is important to start the cassandra bundle at last.

When using chirper in the browser, it is possible to sign up a user. But it is not possible to post chirps.

Use then conduct logs <bundle> to display the logging for a bundle.

Logs

chirp-impl

The following stack trace shows that the chirp service periodically tries to re-connect to the cassandra DB, usually 5 times before logging an error. At 13:11:39 you can see that it tries it the fourth time. Afterwards no error is thrown. Maybe the re-connecting algorithm is broken here?

> conduct logs -n 100 chirp
TIME      HOST          LOG
13:11:36  860d8dbb3847  [warn] c.l.l.i.p.c.ServiceLocatorSessionProvider - Could not find Cassandra contact points, due to: No contact points for [cas_native]
[warn] c.l.l.i.p.c.ServiceLocatorSessionProvider - Could not find Cassandra contact points, due to: No contact points for [cas_native]
[warn] c.l.l.i.p.c.ServiceLocatorSessionProvider - Could not find Cassandra contact points, due to: No contact points for [cas_native]
[warn] c.l.l.i.p.c.ServiceLocatorSessionProvider - Could not find Cassandra contact points, due to: No contact points for [cas_native]
13:11:36  860d8dbb3847  [error] s.c.c.i.ChirpServiceImpl - Failed to create chirp table, due to: No contact points for [cas_native]
com.lightbend.lagom.internal.persistence.cassandra.NoContactPointsException: No contact points for [cas_native]
13:11:37  860d8dbb3847  [warn] c.l.l.i.p.c.ServiceLocatorSessionProvider - Could not find Cassandra contact points, due to: No contact points for [cas_native]
13:11:38  860d8dbb3847  [warn] c.l.l.i.p.c.ServiceLocatorSessionProvider - Could not find Cassandra contact points, due to: No contact points for [cas_native]
13:11:39  860d8dbb3847  [warn] c.l.l.i.p.c.ServiceLocatorSessionProvider - Could not find Cassandra contact points, due to: No contact points for [cas_native]
13:11:39  860d8dbb3847  [warn] a.p.c.j.CassandraJournal - Failed to connect to Cassandra and initialize. It will be retried on demand. Caused by: No contact points for [cas_native]
13:15:38  860d8dbb3847  [error] chirpservice - Exception in PathCallId{pathPattern='/api/chirps/live'}
java.util.concurrent.ExecutionException: com.datastax.driver.core.exceptions.InvalidQueryException: unconfigured table chirp
    at com.google.common.util.concurrent.AbstractFuture.getDoneValue(AbstractFuture.java:476) ~[com.google.guava.guava-19.0.jar:na]
    at com.google.common.util.concurrent.AbstractFuture.get(AbstractFuture.java:435) ~[com.google.guava.guava-19.0.jar:na]
    at com.google.common.util.concurrent.AbstractFuture$TrustedFuture.get(AbstractFuture.java:79) ~[com.google.guava.guava-19.0.jar:na]
    at com.lightbend.lagom.internal.persistence.cassandra.CassandraSessionImpl$ListenableFutureConverter$$anon$1$$anonfun$run$1.apply(CassandraSessionImpl.scala:62) ~[com.lightbend.lagom.lagom-javadsl-persistence_2.11-1.0.0-SNAPSHOT.jar:1.0.0-SNAPSHOT]
    at scala.util.Try$.apply(Try.scala:192) ~[org.scala-lang.scala-library-2.11.7.jar:na]
    at com.lightbend.lagom.internal.persistence.cassandra.CassandraSessionImpl$ListenableFutureConverter$$anon$1.run(CassandraSessionImpl.scala:62) ~[com.lightbend.lagom.lagom-javadsl-persistence_2.11-1.0.0-SNAPSHOT.jar:1.0.0-SNAPSHOT]
    at akka.dispatch.TaskInvocation.run(AbstractDispatcher.scala:39) ~[com.typesafe.akka.akka-actor_2.11-2.4.2.jar:na]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) ~[na:1.8.0_66-internal]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) ~[na:1.8.0_66-internal]
    at java.lang.Thread.run(Thread.java:745) ~[na:1.8.0_66-internal]
Caused by: com.datastax.driver.core.exceptions.InvalidQueryException: unconfigured table chirp
    at com.datastax.driver.core.Responses$Error.asException(Responses.java:136) ~[com.datastax.cassandra.cassandra-driver-core-3.0.0.jar:na]
    at com.datastax.driver.core.SessionManager$4.apply(SessionManager.java:220) ~[com.datastax.cassandra.cassandra-driver-core-3.0.0.jar:na]
    at com.datastax.driver.core.SessionManager$4.apply(SessionManager.java:196) ~[com.datastax.cassandra.cassandra-driver-core-3.0.0.jar:na]
    at com.google.common.util.concurrent.Futures$AsyncChainingFuture.doTransform(Futures.java:1442) ~[com.google.guava.guava-19.0.jar:na]
    at com.google.common.util.concurrent.Futures$AsyncChainingFuture.doTransform(Futures.java:1433) ~[com.google.guava.guava-19.0.jar:na]
    at com.google.common.util.concurrent.Futures$AbstractChainingFuture.run(Futures.java:1408) ~[com.google.guava.guava-19.0.jar:na]
    at com.google.common.util.concurrent.MoreExecutors$DirectExecutor.execute(MoreExecutors.java:456) ~[com.google.guava.guava-19.0.jar:na]
    at com.google.common.util.concurrent.AbstractFuture.executeListener(AbstractFuture.java:817) ~[com.google.guava.guava-19.0.jar:na]
    at com.google.common.util.concurrent.AbstractFuture.complete(AbstractFuture.java:753) ~[com.google.guava.guava-19.0.jar:na]
    at com.google.common.util.concurrent.AbstractFuture.set(AbstractFuture.java:613) ~[com.google.guava.guava-19.0.jar:na]

activity-impl

Stacktrace for completion..

> conduct logs -n 100 activity
TIME      HOST          LOG
13:15:38  860d8dbb3847  [error] activityservice - Exception in PathCallId{pathPattern='/api/activity/:userId/live'}
com.lightbend.lagom.javadsl.api.transport.TransportException:
    at com.lightbend.lagom.javadsl.api.transport.TransportException.fromCodeAndMessage(TransportException.java:49) ~[com.lightbend.lagom.lagom-javadsl-api_2.11-1.0.0-SNAPSHOT.jar:1.0.0-SNAPSHOT]
    at com.lightbend.lagom.javadsl.jackson.JacksonExceptionSerializer.deserialize(JacksonExceptionSerializer.java:83) ~[com.lightbend.lagom.lagom-javadsl-jackson_2.11-1.0.0-SNAPSHOT.jar:1.0.0-SNAPSHOT]
    at com.lightbend.lagom.internal.client.WebSocketSupervisor.channelRead(WebSocketClient.scala:243) ~[com.lightbend.lagom.lagom-javadsl-client_2.11-1.0.0-SNAPSHOT.jar:1.0.0-SNAPSHOT]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:307) ~[io.netty.netty-transport-4.0.34.Final.jar:4.0.34.Final]
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:293) ~[io.netty.netty-transport-4.0.34.Final.jar:4.0.34.Final]
    at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:276) ~[io.netty.netty-codec-4.0.34.Final.jar:4.0.34.Final]
    at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:263) ~[io.netty.netty-codec-4.0.34.Final.jar:4.0.34.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:307) ~[io.netty.netty-transport-4.0.34.Final.jar:4.0.34.Final]
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:293) ~[io.netty.netty-transport-4.0.34.Final.jar:4.0.34.Final]
    at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:840) ~[io.netty.netty-transport-4.0.34.Final.jar:4.0.34.Final]

friend-impl

Here it seems that the cassandra re-connection was successful. In fact, I was able to sign up new users which I believe is only possible if the DB is available and a connection has been established.

> conduct logs -n 100 friend
TIME      HOST          LOG
13:11:27  860d8dbb3847  [warn] c.l.l.i.p.c.ServiceLocatorSessionProvider - Could not find Cassandra contact points, due to: No contact points for [cas_native]
13:11:27  860d8dbb3847  [warn] c.l.l.i.p.c.ServiceLocatorSessionProvider - Could not find Cassandra contact points, due to: No contact points for [cas_native]
13:11:27  860d8dbb3847  [warn] c.l.l.i.p.c.ServiceLocatorSessionProvider - Could not find Cassandra contact points, due to: No contact points for [cas_native]
[warn] c.l.l.i.p.c.ServiceLocatorSessionProvider - Could not find Cassandra contact points, due to: No contact points for [cas_native]
13:11:27  860d8dbb3847  [error] a.a.OneForOneStrategy - com.lightbend.lagom.internal.persistence.cassandra.NoContactPointsException: No contact points for [cas_native]
java.util.concurrent.CompletionException: com.lightbend.lagom.internal.persistence.cassandra.NoContactPointsException: No contact points for [cas_native]
    at java.util.concurrent.CompletableFuture.encodeThrowable(CompletableFuture.java:292) ~[na:1.8.0_66-internal]
    at java.util.concurrent.CompletableFuture.completeThrowable(CompletableFuture.java:308) ~[na:1.8.0_66-internal]
    at java.util.concurrent.CompletableFuture.uniCompose(CompletableFuture.java:943) ~[na:1.8.0_66-internal]
    at java.util.concurrent.CompletableFuture$UniCompose.tryFire(CompletableFuture.java:926) ~[na:1.8.0_66-internal]
    at java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:474) ~[na:1.8.0_66-internal]
    at java.util.concurrent.CompletableFuture.completeExceptionally(CompletableFuture.java:1977) ~[na:1.8.0_66-internal]
    at scala.concurrent.java8.FuturesConvertersImpl$CF.apply(FutureConvertersImpl.scala:21) ~[org.scala-lang.modules.scala-java8-compat_2.11-0.7.0.jar:na]
    at scala.concurrent.java8.FuturesConvertersImpl$CF.apply(FutureConvertersImpl.scala:18) ~[org.scala-lang.modules.scala-java8-compat_2.11-0.7.0.jar:na]
    at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:32) ~[org.scala-lang.scala-library-2.11.7.jar:na]
    at scala.concurrent.BatchingExecutor$Batch$$anonfun$run$1.processBatch$1(BatchingExecutor.scala:63) ~[org.scala-lang.scala-library-2.11.7.jar:na]
Caused by: com.lightbend.lagom.internal.persistence.cassandra.NoContactPointsException: No contact points for [cas_native]
13:11:27  860d8dbb3847  [warn] c.l.l.i.p.c.ServiceLocatorSessionProvider - Could not find Cassandra contact points, due to: No contact points for [cas_native]
...
...
...
13:12:13  860d8dbb3847  [warn] a.c.s.ShardRegion - Trying to register to coordinator at [Some(ActorSelection[Anchor(akka://friend-impl-1/), Path(/system/sharding/FriendEntityCoordinator/singleton/coordinator)])], but no acknowledgement. Total [3] buffered messages.
13:12:15  860d8dbb3847  [warn] a.c.s.ShardRegion - Trying to register to coordinator at [Some(ActorSelection[Anchor(akka://friend-impl-1/), Path(/system/sharding/FriendEntityCoordinator/singleton/coordinator)])], but no acknowledgement. Total [4] buffered messages.
13:12:15  860d8dbb3847  [warn] a.c.s.ShardRegion - Retry request for shard [16] homes from coordinator at [Actor[akka://friend-impl-1/system/sharding/FriendEntityCoordinator/singleton/coordinator#1449747217]]. [4] buffered messages.
13:12:15  860d8dbb3847  [error] friendservice - Exception in RestCallId{method=POST, pathPattern='/api/users'}
com.lightbend.lagom.javadsl.persistence.PersistentEntity$InvalidCommandException: User qq is already created
13:13:23  860d8dbb3847  [error] friendservice - Exception in RestCallId{method=POST, pathPattern='/api/users'}
com.lightbend.lagom.javadsl.persistence.PersistentEntity$InvalidCommandException: User qq is already created
13:13:35  860d8dbb3847  [error] friendservice - Exception in RestCallId{method=POST, pathPattern='/api/users'}
com.lightbend.lagom.javadsl.persistence.PersistentEntity$InvalidCommandException: User qq is already created
13:13:36  860d8dbb3847  [error] friendservice - Exception in RestCallId{method=POST, pathPattern='/api/users'}
com.lightbend.lagom.javadsl.persistence.PersistentEntity$InvalidCommandException: User qq is already created
13:13:37  860d8dbb3847  [error] friendservice - Exception in RestCallId{method=POST, pathPattern='/api/users'}
com.lightbend.lagom.javadsl.persistence.PersistentEntity$InvalidCommandException: User qq is already created
13:13:37  860d8dbb3847  [error] friendservice - Exception in RestCallId{method=POST, pathPattern='/api/users'}
com.lightbend.lagom.javadsl.persistence.PersistentEntity$InvalidCommandException: User qq is already created
13:13:38  860d8dbb3847  [error] friendservice - Exception in RestCallId{method=POST, pathPattern='/api/users'}
com.lightbend.lagom.javadsl.persistence.PersistentEntity$InvalidCommandException: User qq is already created
13:13:50  860d8dbb3847  [error] friendservice - Exception in RestCallId{method=POST, pathPattern='/api/users'}
com.lightbend.lagom.javadsl.persistence.PersistentEntity$InvalidCommandException: User qq is already created

Make circuit breakers a service locator concern

Currently, the circuit breaker is added by the Lagom service client. This means the service (or service call) can be protected by a circuit breaker, however it doesn't allow intelligent routing based on circuit breaker status.

It would make sense for a service locator to return URIs based on knowledge of whether the calls to those URIs are failing or not, and the easiest way to do this would be for the service locator to create a circuit breaker per node. When the circuit breaker is open, the service locator simply wouldn't return that node anymore.

To implement this though currently would mean adding double circuit breakers to each service call, since Lagom already adds one itself, which doesn't make sense.

So, instead we should move the responsibility of adding circuit breakers to the service locator. The service locator already provides a method that takes a callback to execute with the URI and return a future, which allows it to inject the right circuit breaker.

So this task requires the following:

  • Remove the circuit breaker injection from the Lagom service client.
  • Add the circuit breaker injection to the dev mode and ConductR service locator implementations.
  • Add the service call meta data to the service locator lookup method - so that the service locator can use the circuit breaker configuration for it.
  • Modify the circuit breaker configuration so that it can be specified to be none (ie no circuit breaker at all), per node, or per service. Currently it's just a String ID, I suggest we have an object that has an ID and an enum specifying the mode.
  • Ensure that the full circuit breaker configuration is resolved on the ServiceCall by the ServiceReader - currently the default ID is applied in the Lagom service client, but it should be applied by the ServiceReader so that when the ServiceCall is passed to the ServiceLocator, the full info is there.

At least once read side support

We should high level APIs for at least once read side event processing support. Currently, you have to manually implement the offset storage and reading yourself. The framework could implement this for you. The framework could also provide built in partition/sharding support for the read side.

Kubernetes support

It would be great if Lagom also supported Kubernetes as a target production platform.

This would require the following things:

  • Kubernetes based ServiceLocator implementation
  • Pick up configuration for Akka clustering, service location and database location from Kubernetes
  • sbt-native-packager based packaging to produce artifacts that can be deployed by Kubernetes
  • Documentation

To be clear, this is not going to be implemented by Lightbend, but we are creating this issue to indicate that we would be happy to accept such contributions from the community. We recommend, at least initially, implementing it in a separate repo, which could later be pulled into the Lagom GitHub organization if that makes sense.

Better error message when application.conf is missing

The following exception is thrown when starting a Lagom service project that has no application.conf:

> runAll
[info] p.c.s.NettyServer - Listening for HTTP on /0:0:0:0:0:0:0:0:28118
Configuration error: Configuration error[application: application.conf: java.io.IOException: resource not found on classpath: application.conf, application.json: java.io.IOException: resource not found on classpath: application.json, application.properties: java.io.IOException: resource not found on classpath: application.properties]
    at play.api.Configuration$.configError(Configuration.scala:154)
    at play.api.Configuration$.load(Configuration.scala:101)
    at play.api.Configuration$.load(Configuration.scala:109)
    at play.api.ApplicationLoader$.createContext(ApplicationLoader.scala:91)
    at play.core.server.LagomReloadableDevServerStart$$anonfun$mainDev$1$$anon$2$$anonfun$get$1$$anonfun$apply$1$$anonfun$2$$anonfun$3.apply(LagomReloadableDevServerStart.scala:149)
    at play.core.server.LagomReloadableDevServerStart$$anonfun$mainDev$1$$anon$2$$anonfun$get$1$$anonfun$apply$1$$anonfun$2$$anonfun$3.apply(LagomReloadableDevServerStart.scala:148)
    at play.utils.Threads$.withContextClassLoader(Threads.scala:21)
    at play.core.server.LagomReloadableDevServerStart$$anonfun$mainDev$1$$anon$2$$anonfun$get$1$$anonfun$apply$1$$anonfun$2.apply(LagomReloadableDevServerStart.scala:148)
    at play.core.server.LagomReloadableDevServerStart$$anonfun$mainDev$1$$anon$2$$anonfun$get$1$$anonfun$apply$1$$anonfun$2.apply(LagomReloadableDevServerStart.scala:124)
    at scala.Option.map(Option.scala:146)
    at play.core.server.LagomReloadableDevServerStart$$anonfun$mainDev$1$$anon$2$$anonfun$get$1$$anonfun$apply$1.apply(LagomReloadableDevServerStart.scala:124)
    at play.core.server.LagomReloadableDevServerStart$$anonfun$mainDev$1$$anon$2$$anonfun$get$1$$anonfun$apply$1.apply(LagomReloadableDevServerStart.scala:122)
    at scala.util.Success.flatMap(Try.scala:231)
    at play.core.server.LagomReloadableDevServerStart$$anonfun$mainDev$1$$anon$2$$anonfun$get$1.apply(LagomReloadableDevServerStart.scala:122)
    at play.core.server.LagomReloadableDevServerStart$$anonfun$mainDev$1$$anon$2$$anonfun$get$1.apply(LagomReloadableDevServerStart.scala:114)
    at scala.concurrent.impl.Future$PromiseCompletingRunnable.liftedTree1$1(Future.scala:24)
    at scala.concurrent.impl.Future$PromiseCompletingRunnable.run(Future.scala:24)
    at java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1402)
    at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
    at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
    at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
    at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)
Caused by: com.typesafe.config.ConfigException$IO: application: application.conf: java.io.IOException: resource not found on classpath: application.conf, application.json: java.io.IOException: resource not found on classpath: application.json, application.properties: java.io.IOException: resource not found on classpath: application.properties
    at com.typesafe.config.impl.SimpleIncluder.fromBasename(SimpleIncluder.java:236)
    at com.typesafe.config.impl.ConfigImpl.parseResourcesAnySyntax(ConfigImpl.java:132)
    at com.typesafe.config.ConfigFactory.parseResourcesAnySyntax(ConfigFactory.java:1024)
    at com.typesafe.config.ConfigFactory.parseApplicationConfig(ConfigFactory.java:238)
    at com.typesafe.config.ConfigFactory.defaultApplication(ConfigFactory.java:519)
    at play.api.Configuration$$anonfun$3.apply(Configuration.scala:73)
    at play.api.Configuration$$anonfun$3.apply(Configuration.scala:69)
    at scala.Option.getOrElse(Option.scala:121)
    at play.api.Configuration$.load(Configuration.scala:69)
    ... 20 more
Caused by: com.typesafe.config.ConfigException$IO: application.conf: java.io.IOException: resource not found on classpath: application.conf
    at com.typesafe.config.impl.Parseable.parseValue(Parseable.java:188)
    at com.typesafe.config.impl.Parseable.parseValue(Parseable.java:174)
    at com.typesafe.config.impl.Parseable.parse(Parseable.java:152)
    at com.typesafe.config.impl.SimpleIncluder.fromBasename(SimpleIncluder.java:185)
    ... 28 more
Caused by: java.io.IOException: resource not found on classpath: application.conf
    at com.typesafe.config.impl.Parseable$ParseableResources.rawParseValue(Parseable.java:735)
    at com.typesafe.config.impl.Parseable$ParseableResources.rawParseValue(Parseable.java:710)
    at com.typesafe.config.impl.Parseable.parseValue(Parseable.java:180)
    ... 31 more

application.conf is usually needed to enable the Module class that binds the service interface to its implementation, e.g.,

# application.conf
play.modules.enabled += sample.chirper.activity.impl.ActivityStreamModule

In theory, one actually doesn't need to enable the Module if the Play convention is used (i.e., if a Module class is placed in the root package). But, since we don't document this solution, it may be better to simply require to always have an application.conf in the classpath.

sbt reload when Cassandra is running results in exception

When manually starting Cassandra, if a sbt reload is performed we should stop Cassandra, or otherwise we will loose the reference to the process running it.

We should add some hooks into the sbt lifecycle to clean up on reload. We also need to be very careful to ensure all stop hooks are removed on reload, as stop hooks are a hotspot for classloader leaks.

Here is how to reproduce the problem:

> lagomCassandraStart
Starting embedded Cassandra server.......
Cassandra server running @ 127.0.0.1:4000
[success] Total time: 4 s, completed Feb 5, 2016 8:56:20 AM
> reload
...
> lagomCassandraStart
> 2016-02-05 08:56:34,464 ERROR org.apache.cassandra.service.CassandraDaemon - Error starting local jmx server: 
java.rmi.server.ExportException: Port already in use: 4099; nested exception is: 
    java.net.BindException: Address already in use
    at sun.rmi.transport.tcp.TCPTransport.listen(TCPTransport.java:341) ~[na:1.8.0_60]
    at sun.rmi.transport.tcp.TCPTransport.exportObject(TCPTransport.java:249) ~[na:1.8.0_60]
    at sun.rmi.transport.tcp.TCPEndpoint.exportObject(TCPEndpoint.java:411) ~[na:1.8.0_60]
    at sun.rmi.transport.LiveRef.exportObject(LiveRef.java:147) ~[na:1.8.0_60]
    at sun.rmi.server.UnicastServerRef.exportObject(UnicastServerRef.java:208) ~[na:1.8.0_60]
    at sun.rmi.registry.RegistryImpl.setup(RegistryImpl.java:152) ~[na:1.8.0_60]
    at sun.rmi.registry.RegistryImpl.<init>(RegistryImpl.java:112) ~[na:1.8.0_60]
    at java.rmi.registry.LocateRegistry.createRegistry(LocateRegistry.java:239) ~[na:1.8.0_60]
    at org.apache.cassandra.service.CassandraDaemon.maybeInitJmx(CassandraDaemon.java:120) [cassandra-all-3.0.2.jar:3.0.2]
    at org.apache.cassandra.service.CassandraDaemon.setup(CassandraDaemon.java:188) [cassandra-all-3.0.2.jar:3.0.2]
    at org.apache.cassandra.service.CassandraDaemon.activate(CassandraDaemon.java:549) [cassandra-all-3.0.2.jar:3.0.2]
    at akka.persistence.cassandra.testkit.CassandraLauncher$.start(CassandraLauncher.scala:103) [akka-persistence-cassandra_2.11-0.8.jar:0.8]
    at akka.persistence.cassandra.testkit.CassandraLauncher$.main(CassandraLauncher.scala:46) [akka-persistence-cassandra_2.11-0.8.jar:0.8]
    at akka.persistence.cassandra.testkit.CassandraLauncher.main(CassandraLauncher.scala) [akka-persistence-cassandra_2.11-0.8.jar:0.8]
Caused by: java.net.BindException: Address already in use
    at java.net.PlainSocketImpl.socketBind(Native Method) ~[na:1.8.0_60]
    at java.net.AbstractPlainSocketImpl.bind(AbstractPlainSocketImpl.java:387) ~[na:1.8.0_60]
    at java.net.ServerSocket.bind(ServerSocket.java:375) ~[na:1.8.0_60]
    at java.net.ServerSocket.<init>(ServerSocket.java:237) ~[na:1.8.0_60]
    at javax.net.DefaultServerSocketFactory.createServerSocket(ServerSocketFactory.java:231) ~[na:1.8.0_60]
    at org.apache.cassandra.utils.RMIServerSocketFactoryImpl.createServerSocket(RMIServerSocketFactoryImpl.java:13) ~[cassandra-all-3.0.2.jar:3.0.2]
    at sun.rmi.transport.tcp.TCPEndpoint.newServerSocket(TCPEndpoint.java:666) ~[na:1.8.0_60]
    at sun.rmi.transport.tcp.TCPTransport.listen(TCPTransport.java:330) ~[na:1.8.0_60]
    ... 13 common frames omitted
Exception (java.lang.IllegalStateException) encountered during startup: Failed to bind port 4000 on 127.0.0.1.
2016-02-05 08:56:35,170 ERROR org.apache.cassandra.service.CassandraDaemon - Exception encountered during startup
java.lang.IllegalStateException: Failed to bind port 4000 on 127.0.0.1.
    at org.apache.cassandra.transport.Server.start(Server.java:166) ~[cassandra-all-3.0.2.jar:3.0.2]
    at java.util.Collections$SingletonSet.forEach(Collections.java:4767) ~[na:1.8.0_60]
    at org.apache.cassandra.service.NativeTransportService.start(NativeTransportService.java:128) ~[cassandra-all-3.0.2.jar:3.0.2]
    at org.apache.cassandra.service.CassandraDaemon.startNativeTransport(CassandraDaemon.java:597) ~[cassandra-all-3.0.2.jar:3.0.2]
    at org.apache.cassandra.service.CassandraDaemon.start(CassandraDaemon.java:459) ~[cassandra-all-3.0.2.jar:3.0.2]
    at org.apache.cassandra.service.CassandraDaemon.activate(CassandraDaemon.java:564) ~[cassandra-all-3.0.2.jar:3.0.2]
    at akka.persistence.cassandra.testkit.CassandraLauncher$.start(CassandraLauncher.scala:103) [akka-persistence-cassandra_2.11-0.8.jar:0.8]
    at akka.persistence.cassandra.testkit.CassandraLauncher$.main(CassandraLauncher.scala:46) [akka-persistence-cassandra_2.11-0.8.jar:0.8]
    at akka.persistence.cassandra.testkit.CassandraLauncher.main(CassandraLauncher.scala) [akka-persistence-cassandra_2.11-0.8.jar:0.8]
java.lang.IllegalStateException: Failed to bind port 4000 on 127.0.0.1.
    at org.apache.cassandra.transport.Server.start(Server.java:166)
    at java.util.Collections$SingletonSet.forEach(Collections.java:4767)
    at org.apache.cassandra.service.NativeTransportService.start(NativeTransportService.java:128)
    at org.apache.cassandra.service.CassandraDaemon.startNativeTransport(CassandraDaemon.java:597)
    at org.apache.cassandra.service.CassandraDaemon.start(CassandraDaemon.java:459)
    at org.apache.cassandra.service.CassandraDaemon.activate(CassandraDaemon.java:564)
    at akka.persistence.cassandra.testkit.CassandraLauncher$.start(CassandraLauncher.scala:103)
    at akka.persistence.cassandra.testkit.CassandraLauncher$.main(CassandraLauncher.scala:46)
    at akka.persistence.cassandra.testkit.CassandraLauncher.main(CassandraLauncher.scala)
2016-02-05 08:56:35,171 ERROR org.apache.cassandra.service.CassandraDaemon - Exception in thread Thread[main,5,main]
java.lang.RuntimeException: Exception encountered during startup
    at org.apache.cassandra.service.CassandraDaemon.exitOrFail(CassandraDaemon.java:686) ~[cassandra-all-3.0.2.jar:3.0.2]
    at org.apache.cassandra.service.CassandraDaemon.activate(CassandraDaemon.java:579) ~[cassandra-all-3.0.2.jar:3.0.2]
    at akka.persistence.cassandra.testkit.CassandraLauncher$.start(CassandraLauncher.scala:103) ~[akka-persistence-cassandra_2.11-0.8.jar:0.8]
    at akka.persistence.cassandra.testkit.CassandraLauncher$.main(CassandraLauncher.scala:46) ~[akka-persistence-cassandra_2.11-0.8.jar:0.8]
    at akka.persistence.cassandra.testkit.CassandraLauncher.main(CassandraLauncher.scala) ~[akka-persistence-cassandra_2.11-0.8.jar:0.8]
Caused by: java.lang.IllegalStateException: Failed to bind port 4000 on 127.0.0.1.
    at org.apache.cassandra.transport.Server.start(Server.java:166) ~[cassandra-all-3.0.2.jar:3.0.2]
    at java.util.Collections$SingletonSet.forEach(Collections.java:4767) ~[na:1.8.0_60]
    at org.apache.cassandra.service.NativeTransportService.start(NativeTransportService.java:128) ~[cassandra-all-3.0.2.jar:3.0.2]
    at org.apache.cassandra.service.CassandraDaemon.startNativeTransport(CassandraDaemon.java:597) ~[cassandra-all-3.0.2.jar:3.0.2]
    at org.apache.cassandra.service.CassandraDaemon.start(CassandraDaemon.java:459) ~[cassandra-all-3.0.2.jar:3.0.2]
    at org.apache.cassandra.service.CassandraDaemon.activate(CassandraDaemon.java:564) ~[cassandra-all-3.0.2.jar:3.0.2]
    ... 3 common frames omitted

Cassandra trying to delete non-existing file when executing a ServiceTest via IDE

I'm not sure if this issue is applicable to all IDEs but it appears to be the case with IntelliJ.
When running a single ServiceTest via IntelliJ itself, it seems like it is always trying to cleanup some non-existing Cassandra related directory.

The test works just fine when executing it via Activator/sbt.

I can easily reproduce the issue by cloning the Chirper template and trying to execute the ChirpServiceTest either by right click > Running the whole class or a single test. This results in the following Exception being raised:

java.lang.AssertionError: attempted to delete non-existing file ServiceTest_160510221228981
    at org.apache.cassandra.io.util.FileUtils.deleteWithConfirm(FileUtils.java:127)
    at org.apache.cassandra.io.util.FileUtils.deleteWithConfirm(FileUtils.java:154)
    at org.apache.cassandra.io.util.FileUtils.deleteRecursive(FileUtils.java:441)
    at akka.persistence.cassandra.testkit.CassandraLauncher$.start(CassandraLauncher.scala:91)
    at com.lightbend.lagom.javadsl.testkit.ServiceTest$.startServer(ServiceTest.scala:198)
    at com.lightbend.lagom.javadsl.testkit.ServiceTest.startServer(ServiceTest.scala)
    at sample.chirper.chirp.impl.ChirpServiceTest.setUp(ChirpServiceTest.java:30)

I believe I also had this issue when Lagom was just released but I managed to get around it by fiddling around, deleting target- and .idea-folders and reimporting the project but this time I can't seem to get it resolved.

Using Java 1.8.0_74 and IntelliJ Ultimate 2016.1.2.

Pass in Circuit Breaker information alongside the service name in the ServiceLocator

It is important for a ServiceLocator to be able to take advantage of the information in the Circuit Breaker, if a service is considered down (CB:open), how many retries, etc. in order to make intelligent choices in terms of the service instance it returns. We should add a meta-data parameter to the ServiceLocator:locate method with all information needed.

can not connect to local cassandra db

first, i start my local cassandra db, I add sbt config to build.sbt according to the wiki, using the conductR load the subprojects

How to reproduce

Tested the behaviour with chirper on ConductR 1.1.3:

cd activator-lagom-java-chirper
sbt
sandbox run 1.1.3 --feature logging
bundle:dist
conduct load <chirp-impl-bundle>
conduct load <activity-stream-impl-bundle>
conduct load <friend-impl-bundle>
project front-end
configuration:dist
conduct load <front-end-impl-bundle> <front-end-impl-configuration>

conduct run activity
conduct run friend
conduct run chirp
conduct run front
sbt config added
lagomCassandraEnabled in ThisBuild := false
lagomCassandraPort in ThisBuild := 9042
logs

chirp-impl

18:10:27  87be4cb0700d  [error] s.c.c.i.ChirpServiceImpl - Failed to create chirp table, due to: No contact points for [cas_native]
com.lightbend.lagom.internal.persistence.cassandra.NoContactPointsException: No contact points for [cas_native]
18:10:28  87be4cb0700d  [warn] c.l.l.i.p.c.ServiceLocatorSessionProvider - Could not find Cassandra contact points, due to: No contact points for [cas_native]
18:10:29  87be4cb0700d  [warn] c.l.l.i.p.c.ServiceLocatorSessionProvider - Could not find Cassandra contact points, due to: No contact points for [cas_native]
18:10:30  87be4cb0700d  [warn] a.p.c.j.CassandraJournal - Failed to connect to Cassandra and initialize. It will be retried on demand. Caused by: No contact points for [cas_native]
18:29:38  87be4cb0700d  [warn] c.l.l.i.p.c.ServiceLocatorSessionProvider - Could not find Cassandra contact points, due to: No contact points for [cas_native]
18:29:41  87be4cb0700d  [warn] a.p.c.j.CassandraJournal - Failed to connect to Cassandra and initialize. It will be retried on demand. Caused by: No contact points for [cas_native]
18:38:43  87be4cb0700d  [warn] c.l.l.i.p.c.ServiceLocatorSessionProvider - Could not find Cassandra contact points, due to: No contact points for [cas_native]
18:38:44  87be4cb0700d  [warn] c.l.l.i.p.c.ServiceLocatorSessionProvider - Could not find Cassandra contact points, due to: No contact points for [cas_native]
18:38:45  87be4cb0700d  [warn] c.l.l.i.p.c.ServiceLocatorSessionProvider - Could not find Cassandra contact points, due to: No contact points for [cas_native]
18:38:45  87be4cb0700d  [warn] a.p.c.j.CassandraJournal - Failed to connect to Cassandra and initialize. It will be retried on demand. Caused by: No contact points for [cas_native]

frend-impl

18:45:38  87be4cb0700d  [warn] a.c.s.ShardRegion - Trying to register to coordinator at [Some(ActorSelection[Anchor(akka://friend-impl-1/), Path(/system/sharding/FriendEntityCoordinator/singleton/coordinator)])], but no acknowledgement. Total [6] buffered messages.
18:45:40  87be4cb0700d  [warn] a.c.s.ShardRegion - Trying to register to coordinator at [Some(ActorSelection[Anchor(akka://friend-impl-1/), Path(/system/sharding/FriendEntityCoordinator/singleton/coordinator)])], but no acknowledgement. Total [6] buffered messages.
18:45:42  87be4cb0700d  [warn] a.c.s.ShardRegion - Trying to register to coordinator at [Some(ActorSelection[Anchor(akka://friend-impl-1/), Path(/system/sharding/FriendEntityCoordinator/singleton/coordinator)])], but no acknowledgement. Total [6] buffered messages.
18:45:44  87be4cb0700d  [warn] a.c.s.ShardRegion - Trying to register to coordinator at [Some(ActorSelection[Anchor(akka://friend-impl-1/), Path(/system/sharding/FriendEntityCoordinator/singleton/coordinator)])], but no acknowledgement. Total [6] buffered messages.
18:45:46  87be4cb0700d  [warn] a.c.s.ShardRegion - Trying to register to coordinator at [Some(ActorSelection[Anchor(akka://friend-impl-1/), Path(/system/sharding/FriendEntityCoordinator/singleton/coordinator)])], but no acknowledgement. Total [6] buffered messages.
18:45:48  87be4cb0700d  [warn] a.c.s.ShardRegion - Trying to register to coordinator at [Some(ActorSelection[Anchor(akka://friend-impl-1/), Path(/system/sharding/FriendEntityCoordinator/singleton/coordinator)])], but no acknowledgement. Total [6] buffered messages.
18:45:50  87be4cb0700d  [warn] a.c.s.ShardRegion - Trying to register to coordinator at [Some(ActorSelection[Anchor(akka://friend-impl-1/), Path(/system/sharding/FriendEntityCoordinator/singleton/coordinator)])], but no acknowledgement. Total [6] buffered messages.
18:45:52  87be4cb0700d  [warn] a.c.s.ShardRegion - Trying to register to coordinator at [Some(ActorSelection[Anchor(akka://friend-impl-1/), Path(/system/sharding/FriendEntityCoordinator/singleton/coordinator)])], but no acknowledgement. Total [6] buffered messages.
18:45:54  87be4cb0700d  [warn] a.c.s.ShardRegion - Trying to register to coordinator at [Some(ActorSelection[Anchor(akka://friend-impl-1/), Path(/system/sharding/FriendEntityCoordinator/singleton/coordinator)])], but no acknowledgement. Total [6] buffered messages.
18:45:56  87be4cb0700d  [warn] a.c.s.ShardRegion - Trying to register to coordinator at [Some(ActorSelection[Anchor(akka://friend-impl-1/), Path(/system/sharding/FriendEntityCoordinator/singleton/coordinator)])], but no acknowledgement. Total [6] buffered messages.

front-end
nothing

activity-stream-impl
nothing

Code formatting in the Getting Started documentation

This is in relation to Lagom Getting Started page, particularly the code snippet under Understanding services projects section - http://www.lagomframework.com/documentation/1.0.x/GettingStarted.html#Understanding-services-projects

The code snippet in question is this:

    // Look up the hello world entity for the given ID.
    PersistentEntityRef<HelloCommand> ref = persistentEntityRegistry.refFor(HelloWorld.class, id);

If viewed using the browser the code snippet is truncated at PersistentEntityRef<HelloCommand> ref = persistentEntityRegistry.refFor(HelloWorld.class, - one must scroll to the right to view the code in its entirety.

Because there's no scrollbar, I didn't know there more text to scroll until @dotta told me. We should change the formatting so the whole code is visible without scrolling.

ConfigChecker warnings when running with RP

[warn] a.d.ConfigChecker - Typesafe recommendation: Don't use jvm-exit-on-fatal-error=off. It's safer to shutdown the JVM in case of a fatal error, such as OutOfMemoryError. Related config properties: [akka.jvm-exit-on-fatal-error = off]. Corresponding default values: [akka.jvm-exit-on-fatal-error = on]. You may disable this check by adding [jvm-exit-on-fatal-error] to configuration string list akka.diagnostics.checker.disabled-checks. Please use http://support.typesafe.com/ if you need more advice around this warning.
[warn] a.d.ConfigChecker - Typesafe recommendation: You have configured [14] different custom dispatchers. Do you really need that many dispatchers. Separating into CPU bound tasks and blocking (IO) tasks are often enough. Related config properties: [remote.backoff-remote-dispatcher, play.akka.blockingIoDispatcher, stream.default-blocking-io-dispatcher, actor.default-dispatcher, cassandra-journal.default-dispatcher, persistence.dispatchers.default-stream-dispatcher, diagnostics.recorder.dispatcher, cassandra-snapshot-store.default-dispatcher, cassandra-query-journal.default-dispatcher, io.pinned-dispatcher, lagom.persistence.dispatcher, remote.default-remote-dispatcher, persistence.dispatchers.default-replay-dispatcher, persistence.dispatchers.default-plugin-dispatcher]. You may disable this check by adding [dispatcher-count] to configuration string list akka.diagnostics.checker.disabled-checks. Please use http://support.typesafe.com/ if you need more advice around this warning.
[warn] a.d.ConfigChecker - Typesafe recommendation: akka.actor.default-dispatcher.fork-join-executor.task-peeking-mode is an advanced configuration setting. Make sure that you fully understand the implications of changing the default value. You can confirm that you know the meaning of this configuration setting by adding [akka.actor.default-dispatcher.fork-join-executor.task-peeking-mode] to configuration string list akka.diagnostics.checker.confirmed-power-user-settings. Related config properties: [akka.actor.default-dispatcher.fork-join-executor.task-peeking-mode = LIFO]. Corresponding default values: [akka.actor.default-dispatcher.fork-join-executor.task-peeking-mode = FIFO]. You may disable this check by adding [power-user-settings] to configuration string list akka.diagnostics.checker.disabled-checks. Please use http://support.typesafe.com/ if you need more advice around this warning.
[warn] a.d.ConfigChecker - Typesafe recommendation: akka.remote.netty.udp.hostname is an advanced configuration setting. Make sure that you fully understand the implications of changing the default value. You can confirm that you know the meaning of this configuration setting by adding [akka.remote.netty.udp.hostname] to configuration string list akka.diagnostics.checker.confirmed-power-user-settings. Related config properties: [akka.remote.netty.udp.hostname = 127.0.0.1]. Corresponding default values: [akka.remote.netty.udp.hostname = ]. You may disable this check by adding [power-user-settings] to configuration string list akka.diagnostics.checker.disabled-checks. Please use http://support.typesafe.com/ if you need more advice around this warning.
[warn] a.d.ConfigChecker - Typesafe recommendation: akka.remote.netty.udp.port is an advanced configuration setting. Make sure that you fully understand the implications of changing the default value. You can confirm that you know the meaning of this configuration setting by adding [akka.remote.netty.udp.port] to configuration string list akka.diagnostics.checker.confirmed-power-user-settings. Related config properties: [akka.remote.netty.udp.port = 0]. Corresponding default values: [akka.remote.netty.udp.port = 2552]. You may disable this check by adding [power-user-settings] to configuration string list akka.diagnostics.checker.disabled-checks. Please use http://support.typesafe.com/ if you need more advice around this warning.

This is because we use OSS version of Play. If we want to fix it before we have an RP that includes Play 2.5.0 we have to add things to Lagom's reference-overrides

Support for service integration tests

Support for writing integration tests that involve several interacting services. The idea is that we can launch the services in a similar way as the dev-mode runAll and thereafter run the test that interact with the services using their service clients.

I have explored this and the following code works. The missing pieces is the sbt support for starting the services and tests.

package com.lightbend.lagom.javadsl.testkit

import java.util.function.{ Function => JFunction }

import scala.annotation.varargs
import scala.concurrent.duration._
import scala.concurrent.duration.FiniteDuration
import scala.util.Try

import akka.actor.ActorSystem
import akka.japi.function.Effect
import akka.japi.function.Procedure
import akka.stream.Materializer
import com.google.inject.AbstractModule
import com.lightbend.lagom.internal.cluster.JoinClusterModule
import com.lightbend.lagom.javadsl.api.Service
import com.lightbend.lagom.javadsl.api.ServiceInfo
import com.lightbend.lagom.javadsl.client.ServiceClientGuiceSupport
import com.lightbend.lagom.javadsl.persistence.PersistenceModule
import com.lightbend.lagom.javadsl.pubsub.PubSubModule
import com.lightbend.lagom.javadsl.server.ServiceGuiceSupport
import play.Application
import play.api.Mode
import play.api.Play
import play.api.inject.BindingKey
import play.api.inject.guice.GuiceApplicationBuilder
import play.api.inject.guice.GuiceableModule
import play.inject.Injector
import play.inject.guice.{ GuiceApplicationBuilder => JGuiceApplicationBuilder }

object ServiceIntegrationTest {

  @varargs
  @SafeVarargs
  class TestModule(services: Class[_ <: Service]*) extends AbstractModule with ServiceClientGuiceSupport {
    override def configure(): Unit = {
      services.foreach(bindClient(_))
    }
  }

  @varargs
  @SafeVarargs
  def testModule(services: Class[_ <: Service]*): TestModule =
    new TestModule(services: _*)

  class TestClient(val app: Application) {

    def client[S <: Service](serviceClass: Class[S]): S =
      app.injector().instanceOf(serviceClass)

    def materializer: Materializer = injector.instanceOf(classOf[Materializer])

    def system: ActorSystem = injector.instanceOf(classOf[ActorSystem])

    def injector: Injector = app.injector()

    def stop(): Unit = {
      Try(Play.stop(app.getWrappedApplication))
    }
  }

  def withClient(
    configureBuilder: JFunction[JGuiceApplicationBuilder, JGuiceApplicationBuilder],
    block:            Procedure[TestClient]
  ): Unit = {
    // using Procedure instead of Consumer to support throwing Exception
    val testClient = startClient(configureBuilder)
    try {
      block(testClient)
    } finally {
      testClient.stop()
    }
  }

  def startClient(configureBuilder: JFunction[JGuiceApplicationBuilder, JGuiceApplicationBuilder]): TestClient = {
    val builder =
      new GuiceApplicationBuilder(loadModules = (env, conf) => {
        GuiceableModule.loadModules(env, conf).filterNot(
          _.guiced(env, conf).exists(_.isInstanceOf[ServiceGuiceSupport])
        )
      })
        .in(Mode.Dev)
        .bindings(bind(classOf[ServiceInfo]).to(new ServiceInfo("test")))
        .disable(classOf[PersistenceModule], classOf[PubSubModule], classOf[JoinClusterModule])
        .configure(
          "lagom.service-locator.enabled" -> true,
          "lagom.service-locator.url" -> "http://localhost:8000",
          "akka.actor.provider" -> "akka.actor.LocalActorRefProvider"
        )

    val app = configureBuilder(JGuiceApplicationBuilder.fromScalaBuilder(builder)).build()
    new TestClient(app)
  }

  def eventually(max: FiniteDuration, block: Effect): Unit =
    eventually(max, 100.millis, block)

  def eventually(max: FiniteDuration, interval: FiniteDuration, block: Effect): Unit =
    ServiceTest.eventually(max, interval, block)

  def bind[T](clazz: Class[T]): BindingKey[T] =
    play.inject.Bindings.bind(clazz)

}

and here is example of such a test:

public class ActivityStreamServiceTest {

  @Test
  public void testInvoke() throws Exception {
    withClient(b -> b.bindings(testModule(ActivityStreamService.class, FriendService.class)), testClient -> {
      ActivityStreamService activityStream = testClient.client(ActivityStreamService.class);
      FriendService friend = testClient.client(FriendService.class);

      User usr1 = User.builder().userId("usr1").name("User 1").build();
      friend.createUser().invoke().toCompletableFuture().get(10, TimeUnit.SECONDS);

      CompletionStage<Source<Chirp, ?>> feed = activityStream.getLiveActivityStream().invoke("usr1",
          NotUsed.getInstance());
      Source<Chirp, ?> source = feed.toCompletableFuture().get(3, TimeUnit.SECONDS);
      System.out.println("# got " + source); // FIXME
    });

  }

}

note that the API should be aligned with the API of the ServiceTest

Smooth shutdown when an exception occurs during service initialization

This is a development environment issue that occurs when an exception is thrown when the service is created (but not yet started). For instance, if one forgets to enable the Module class (in the application.conf) that binds a service interface to its implementation. Another occurrence of the same problem is when the port assigned to the service is already in use. The issue is particularly annoying when using the runAll task, as the service that is not being started is likely the one a user is working on.

Add Maven as alternative build tools

I have followed http://blog.eisele.net/2016/04/your-first-lagom-service-getting-started-with-java-microservices.html and tried Lagom. But encountered the worst experience of SBT.

I am using the latest Java 8, Activitor 1.3.10.

The activiator eclipse command uses over 30 hrs to resolve the dependencies. Yes, 30 hours. It it terrible.

  1. I have added -Dsbt.override.build.repos=true to the command line.

  2. Changed the repos in .sbt/repositories.

    [repositories]
    local
    maven-local
    nexus-maven-proxy: http://120.26.102.83:8081/nexus/content/groups/public
    nexus-ivy-proxy: http://120.26.102.83:8081/nexus/content/groups/public, [organization]/[module]/(scala_[scalaVersion]/)(sbt_[sbtVersion]/)[revision]/[type]s/artifact.[ext]
    typesafe-releases: https://dl.bintray.com/typesafe/ivy-releases/
    typesafe-ivy-releases: https://dl.bintray.com/typesafe/ivy-releases/, [organization]/[module]/(scala_[scalaVersion]/)(sbt_[sbtVersion]/)[revision]/[type]s/artifact.[ext]

  3. And the console log failure indicates it does not work at all. After Local, it always calls Maven public, then my local nexus repositories.

    [warn] [FAILED ] org.seleniumhq.selenium#selenium-java;2.48.2!selenium-java.jar(src): (0ms)
    [warn] ==== local: tried
    [warn] E:\Users\hantsy.ivy2\local\org.seleniumhq.selenium\selenium-java\2.48.2\srcs\selenium-java-sources.jar
    [warn] ==== public: tried
    [warn] https://repo1.maven.org/maven2/org/seleniumhq/selenium/selenium-java/2.48.2/selenium-java-2.48.2-sources.jar
    [warn] ==== Maven2 Local: tried
    [warn] file:/E:/Users/hantsy/.m2/repository/org/seleniumhq/selenium/selenium-java/2.48.2/selenium-java-2.48.2-sources.jar
    [warn] ==== nexus-maven-proxy: tried
    [warn] http://120.26.102.83:8081/nexus/content/groups/public/org/seleniumhq/selenium/selenium-java/2.48.2/selenium-java-2.48.2-sources.jar
    [warn] ==== nexus-ivy-proxy: tried
    [warn] http://120.26.102.83:8081/nexus/content/groups/public/org.seleniumhq.selenium/selenium-java/2.48.2/srcs/selenium-java-sources.jar
    [warn] ==== typesafe-releases: tried
    [warn] https://dl.bintray.com/typesafe/ivy-releases/org/seleniumhq/selenium/selenium-java/2.48.2/selenium-java-2.48.2-sources.jar
    [warn] ==== typesafe-ivy-releases: tried
    [warn] https://dl.bintray.com/typesafe/ivy-releases/org.seleniumhq.selenium/selenium-java/2.48.2/srcs/selenium-java-sources.jar
    [warn] ==== bintray-typesafe-maven-releases: tried
    [warn] https://dl.bintray.com/typesafe/maven-releases/org/seleniumhq/selenium/selenium-java/2.48.2/selenium-java-2.48.2-sources.jar
    [warn] ==== bintray-typesafe-maven-releases: tried
    [warn] https://dl.bintray.com/typesafe/maven-releases/org/seleniumhq/selenium/selenium-java/2.48.2/selenium-java-2.48.2-sources.jar

Please provide Maven alternatives for all templates instead of the SBT and ivy.

default logback conf not used by ServiceTest

When running tests with ServiceTest the default logback configuration provided by lagom-logback is not used. I think play.logger.configurator property is not honored when launching Play in these tests.

Lagom Lagom assigned port to service - Network architecture and filtering pains

Hi all.

The default port range [20000, 30000] is part of IANA user port range [1024-49151].
According to IANA http://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xhtml, User Ports are assigned by IANA using the "IETF Review" process, the "IESG Approval" process, or the "Expert Review" process, as per [RFC6335].
This range can be in conflict by the secure network filtering convention in certain cases.

My proposal is to choose the "Dynamic and/or Private" range [49152-65535] by default in futur realese of Lagom and also Play! and Akka.

Regards!

Could not find Cassandra contact points, due to: ServiceLocator is not bound

Problem

When adding the lagomJavadslPersistence module the api project (instead of the implementation project), the following error is reported upon executing runAll:

> runAll
[info] Starting embedded Cassandra server
.......
[info] Cassandra server running at 127.0.0.1:4000
[info] Service locator is running at http://localhost:8000
[info] Service gateway is running at http://localhost:9000
[info] Updating {file:/Users/mirco/Projects/oos/lagom-demo/}user-api...
[info] Resolving jline#jline;2.12.1 ...
[info] Done updating.
[info] Updating {file:/Users/mirco/Projects/oos/lagom-demo/}user-impl...
[info] Resolving com.fasterxml.jackson.core#jackson-databind;2.7.2 ...
[info] Done updating.
[info] application - Signalled start to ConductR
[info] application - Signalled start to ConductR
[info] Service user-impl listening for HTTP on 0:0:0:0:0:0:0:0:28255
[info] Service image-impl listening for HTTP on 0:0:0:0:0:0:0:0:25118
[info] (Services started, use Ctrl+D to stop and go back to the console...)
[warn] c.l.l.i.p.c.ServiceLocatorSessionProvider - Could not find Cassandra contact points, due to: ServiceLocator is not bound
[warn] c.l.l.i.p.c.ServiceLocatorSessionProvider - Could not find Cassandra contact points, due to: ServiceLocator is not bound
[warn] c.l.l.i.p.c.ServiceLocatorSessionProvider - Could not find Cassandra contact points, due to: ServiceLocator is not bound
[warn] c.l.l.i.p.c.ServiceLocatorSessionProvider - Could not find Cassandra contact points, due to: ServiceLocator is not bound
[warn] c.l.l.i.p.c.ServiceLocatorSessionProvider - Could not find Cassandra contact points, due to: ServiceLocator is not bound
[warn] c.l.l.i.p.c.ServiceLocatorSessionProvider - Could not find Cassandra contact points, due to: ServiceLocator is not bound
[warn] a.p.c.j.CassandraJournal - Failed to connect to Cassandra and initialize. It will be retried on demand. Caused by: ServiceLocator is not bound
[warn] c.l.l.i.p.c.ServiceLocatorSessionProvider - Could not find Cassandra contact points, due to: ServiceLocator is not bound
[warn] a.p.c.s.CassandraSnapshotStore - Failed to connect to Cassandra and initialize. It will be retried on demand. Caused by: ServiceLocator is not bound
[warn] c.l.l.i.p.c.ServiceLocatorSessionProvider - Could not find Cassandra contact points, due to: ServiceLocator is not bound
[warn] a.p.c.j.CassandraJournal - Failed to connect to Cassandra and initialize. It will be retried on demand. Caused by: ServiceLocator is not bound
[error] a.c.s.PersistentShardCoordinator - Persistence failure when replaying events for persistenceId [/sharding/UserEntityCoordinator]. Last known sequence number [0]
java.lang.IllegalStateException: ServiceLocator is not bound
    at com.lightbend.lagom.internal.persistence.cassandra.ServiceLocatorSessionProvider.com$lightbend$lagom$internal$persistence$cassandra$ServiceLocatorSessionProvider$$tryAgain$1(ServiceLocatorSessionProvider.scala:52) ~[lagom-javadsl-persistence_2.11-1.0.0-M2.jar:1.0.0-M2]

Workaround

Declare the lagomJavadslPersistence dependency on the implementation project, instead of the api.

Useful info for fixing the issue

Look at ServiceLocatorSessionProvider and CassandraModule. The latter class in injected by the lagom sbt plugin if the lagomJavadslPersistence dependency is detected, as you can see here.

Support for DynamoDB persistence module

Similar to #63, this issue is for tracking demand for a DynamoDB persistence module, +1 if this is something you would like.

Supporting DynamoDB will allow easier deployments to AWS since it will not be necessary to manage a Cassandra cluster.

Ensure javadocs don't output the date

The Lagom javadocs are built by running sbt unidoc. The output javadocs however contain a date/timestamp, which means when the docs are rebuilt by our nightlies, every page of the javadocs is touched. See lagom/lagom.github.io@66b4dec for an example. This isn't the end of the world, but isn't ideal. The unidoc configuration should be updated to disable timestamps when javadoc is run.

Investigate OSX file watching

When I use Lagom dev mode on Linux, if I make a change to, for example, a configuration file, reloads are instant, when I switch windows after making a change, I see it's already reloaded.

When I use Lagom dev mode on OSX, if I make the same change, it seems to take several seconds before that change is detected and the application is reloaded, sometimes as long as 10 seconds.

This is suspicious, and seems to me like maybe the JDK file WatchService is being used on OSX. It shouldn't be - it's implemented using polling on OSX, so in Play we detect the platform and use jnotify instead. But maybe this isn't working the way it's supposed to work for some reason in Lagom.

Make the documentation searchable

We need to make the documentation searchable. It is currently extremely tedious to find specific topics. I essentially have to rely or Google, or go through every page and search in the html file.

com.google.inject.CreationException after enabling ConductR

@datto
I am following the instructions to take my code into production like environment. I enabled the ConductR plugins and added teh override for play as documented.

I am starting the application using:

activator runAll

On startup, I get the following exception:

om.google.inject.CreationException: Unable to create injector, see the following errors:

1) A binding to com.lightbend.lagom.javadsl.api.ServiceLocator was already configured at com.typesafe.conductr.bundlelib.lagom.ServiceLocatorModule.bindings(ServiceLocatorModule.scala:16):
Binding(interface com.lightbend.lagom.javadsl.api.ServiceLocator to ConstructionTarget(class com.typesafe.conductr.bundlelib.lagom.ConductRServiceLocator) in interface javax.inject.Singleton) (via modules: com.google.inject.util.Modules$OverrideModule -> play.api.inject.guice.GuiceableModuleConversions$$anon$1).
  at com.lightbend.lagom.internal.registry.ServiceRegistryModule.configure(ServiceRegistryModule.scala:31) (via modules: com.google.inject.util.Modules$OverrideModule -> com.lightbend.lagom.internal.registry.ServiceRegistryModule)

1 error
    at com.google.inject.internal.Errors.throwCreationExceptionIfErrorsExist(Errors.java:466)
    at com.google.inject.internal.InternalInjectorCreator.initializeStatically(InternalInjectorCreator.java:155)
    at com.google.inject.internal.InternalInjectorCreator.build(InternalInjectorCreator.java:107)
    at com.google.inject.Guice.createInjector(Guice.java:96)
    at com.google.inject.Guice.createInjector(Guice.java:84)
    at play.api.inject.guice.GuiceBuilder.injector(GuiceInjectorBuilder.scala:181)
    at play.api.inject.guice.GuiceApplicationBuilder.build(GuiceApplicationBuilder.scala:123)
    at play.api.inject.guice.GuiceApplicationLoader.load(GuiceApplicationLoader.scala:21)
    at com.typesafe.conductr.bundlelib.lagom.ConductRApplicationLoader.load(ConductRApplicationLoader.scala:22)
    at play.core.server.LagomReloadableDevServerStart$$anonfun$mainDev$1$$anon$2$$anonfun$get$1$$anonfun$apply$1$$anonfun$2$$anonfun$3.apply(LagomReloadableDevServerStart.scala:151)
    at play.core.server.LagomReloadableDevServerStart$$anonfun$mainDev$1$$anon$2$$anonfun$get$1$$anonfun$apply$1$$anonfun$2$$anonfun$3.apply(LagomReloadableDevServerStart.scala:148)
    at play.utils.Threads$.withContextClassLoader(Threads.scala:21)
    at play.core.server.LagomReloadableDevServerStart$$anonfun$mainDev$1$$anon$2$$anonfun$get$1$$anonfun$apply$1$$anonfun$2.apply(LagomReloadableDevServerStart.scala:148)
    at play.core.server.LagomReloadableDevServerStart$$anonfun$mainDev$1$$anon$2$$anonfun$get$1$$anonfun$apply$1$$anonfun$2.apply(LagomReloadableDevServerStart.scala:124)
    at scala.Option.map(Option.scala:146)
    at play.core.server.LagomReloadableDevServerStart$$anonfun$mainDev$1$$anon$2$$anonfun$get$1$$anonfun$apply$1.apply(LagomReloadableDevServerStart.scala:124)
    at play.core.server.LagomReloadableDevServerStart$$anonfun$mainDev$1$$anon$2$$anonfun$get$1$$anonfun$apply$1.apply(LagomReloadableDevServerStart.scala:122)
    at scala.util.Success.flatMap(Try.scala:231)
    at play.core.server.LagomReloadableDevServerStart$$anonfun$mainDev$1$$anon$2$$anonfun$get$1.apply(LagomReloadableDevServerStart.scala:122)
    at play.core.server.LagomReloadableDevServerStart$$anonfun$mainDev$1$$anon$2$$anonfun$get$1.apply(LagomReloadableDevServerStart.scala:114)
    at scala.concurrent.impl.Future$PromiseCompletingRunnable.liftedTree1$1(Future.scala:24)
    at scala.concurrent.impl.Future$PromiseCompletingRunnable.run(Future.scala:24)
    at java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1402)
    at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
    at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
    at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
    at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)

Stacktrace caused by project observer-asp-impl (filesystem path to project is /Users/gaswamin/starbucks/Analytics/bits/lagom-asp/observer-asp-impl).
Hint: Maybe you have forgot to enable your service Module class via `play.modules.enabled`? (check in your project's application.conf)

Your suggested workaround does not fix the problem

play.modules.disabled += com.lightbend.lagom.internal.registry.ServiceRegistryModule

Here is my plugins.sbt

// The lagom build plugin
addSbtPlugin("com.lightbend.lagom" % "lagom-sbt-plugin" % "1.0.0-M1")

// The lagom deployment plugin
addSbtPlugin("com.typesafe.sbt" % "sbt-lagom-bundle" % "1.0.0")

// The lagom developer sandbox plugin
addSbtPlugin("com.typesafe.conductr" % "sbt-conductr-sandbox" % "1.3.0")

// Play 2.5.0 is not part of RP yet
rpOverrides := rpOverrides.value.filterNot(_.organization == "com.typesafe.play")

And here is my build.sbt

def project(id: String) = Project(id, base = file(id))
    .settings(javacOptions in compile ++= Seq("-encoding", "UTF-8", "-source", "1.8", "-target", "1.8", "-Xlint:unchecked", "-Xlint:deprecation"))
    .settings(jacksonParameterNamesJavacSettings: _*) // applying it to every project even if not strictly needed.
    // Play 2.5.0 is not part of RP yet
    .settings(rpOverrides := rpOverrides.value.filterNot(_.organization == "com.typesafe.play"))

// See https://github.com/FasterXML/jackson-module-parameter-names
lazy val jacksonParameterNamesJavacSettings = Seq(
  javacOptions in compile += "-parameters"
)

My application.conf has these first 3 lines followed by custom application configuration.

play.modules.enabled += com.starbucks.analytics.observer.impl.ObserverModule
play.modules.enabled += com.starbucks.analytics.observations.ObservationModule
play.modules.disabled += com.lightbend.lagom.internal.registry.ServiceRegistryModule

logback-test.xml is not used

I find it confusing that logback-test.xml is not used.

Can be reproduced in service-integration-tests by renaming lagom-service-integration-tests/src/test/resources/logback.xml to /lagom-service-integration-tests/src/test/resources/logback-test.xml

No service locator when integrating with ConductR

Given the new install command for sbt-conductr, I can successfully load and run the Chirper system. However a couple of services (chirp and friend) complain that they cannot locate Cassandra contact points. Further back in the logs of friend I can see the following message:

java.util.concurrent.CompletionException: java.lang.IllegalStateException: ServiceLocator is not bound
    at java.util.concurrent.CompletableFuture.encodeThrowable(CompletableFuture.java:292) ~[na:1.8.0_66-internal]
    at java.util.concurrent.CompletableFuture.completeThrowable(CompletableFuture.java:308) ~[na:1.8.0_66-internal]
    at java.util.concurrent.CompletableFuture.uniCompose(CompletableFuture.java:943) ~[na:1.8.0_66-internal]
    at java.util.concurrent.CompletableFuture$UniCompose.tryFire(CompletableFuture.java:926) ~[na:1.8.0_66-internal]
    at java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:474) ~[na:1.8.0_66-internal]
    at java.util.concurrent.CompletableFuture.completeExceptionally(CompletableFuture.java:1977) ~[na:1.8.0_66-internal]
    at scala.concurrent.java8.FuturesConvertersImpl$CF.apply(FutureConvertersImpl.scala:21) ~[org.scala-lang.modules.scala-java8-compat_2.11-0.7.0.jar:na]
    at scala.concurrent.java8.FuturesConvertersImpl$CF.apply(FutureConvertersImpl.scala:18) ~[org.scala-lang.modules.scala-java8-compat_2.11-0.7.0.jar:na]
    at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:32) ~[org.scala-lang.scala-library-2.11.7.jar:na]
    at scala.concurrent.BatchingExecutor$Batch$$anonfun$run$1.processBatch$1(BatchingExecutor.scala:63) ~[org.scala-lang.scala-library-2.11.7.jar:na]
Caused by: java.lang.IllegalStateException: ServiceLocator is not bound
    at com.lightbend.lagom.internal.persistence.cassandra.ServiceLocatorSessionProvider.com$lightbend$lagom$internal$persistence$cassandra$ServiceLocatorSessionProvider$$tryAgain$1(ServiceLocatorSessionProvider.scala:52) ~[com.lightbend.lagom.lagom-javadsl-persistence_2.11-1.0.0-M2.jar:1.0.0-M2]
    at com.lightbend.lagom.internal.persistence.cassandra.ServiceLocatorSessionProvider$$anonfun$com$lightbend$lagom$internal$persistence$cassandra$ServiceLocatorSessionProvider$$tryAgain$1$1.apply$mcV$sp(ServiceLocatorSessionProvider.scala:58) ~[com.lightbend.lagom.lagom-javadsl-persistence_2.11-1.0.0-M2.jar:1.0.0-M2]
    at akka.actor.Scheduler$$anon$4.run(Scheduler.scala:122) ~[com.typesafe.akka.akka-actor_2.11-2.4.4.jar:na]
    ... 4 common frames omitted

This could be something in relation to conductr-bundle-lib requiring an upgrade to M2 - it is presently on M1.

Scaffolding of new services "activator new frond-end lagom-frontend-java"

I was searching for a quick way to add a new service module to an existing example.
Copy and pasting isn't exactly what I was looking for. Maybe there can be an easy template/scaffolding mechanism to support a command like this:

activator new frond-end lagom-frontend-java

which adds the required module definition to the build.sbt, required plugins and creates the directory structure?

Scheduled calls

I think it would be useful to be able to schedule service calls in a safe and easy way. Something like:

public interface CallScheduler {

  /**
   * Schedules call to be invoked once with a delay, i.e. a time period that has
   * to pass before the message is sent.
   */
  <Id, Request, Response> Pair<Cancellable, CompletionStage<Response>> scheduleOnce(
      FiniteDuration delay,
      ServiceCall<Id, Request, Response> call, Id id, Request request);

  /**
   * Schedules call to be invoked repeatedly with an initial delay and
   * frequency.
   */
  <Id, Request, Response> Pair<Cancellable, CompletionStage<Source<Response, NotUsed>>> schedulePeriodically(
      FiniteDuration initialDelay, FiniteDuration interval,
      ServiceCall<Id, Request, Response> call, Id id, Request request);

}

Not sure we need the Cancellable, those are mostly used for periodic tasks, and then we could perhaps piggyback on the possibility to cancel the Source, or have the Cancellable as materialized value?

API for provisioning persistent stream subscriptions

We could provide an API for provisioning persistent stream subscriptions between services. By persistent, I mean if a disconnect occurs, it reconnects (with exponential backoff).

The purpose of this is to provide point to point at least once message delivery between two clustered services.

At a minimum we could support running as a cluster singleton, but we could also let Lagom handle partitioning, so that we can subscribe to partitioned streams - this would need to be paired with nice partitioning support in the persistent entities event stream (probably isn't any hard then simply tagging events by partition, sharding by event id over the number of partitions). To implement this, we could simply allow the client side to shard partitions across the cluster - it would need to ask the service how many partitions there are to do so.

Additionally, we could also provide some helpers that would manage recording and loading offsets in Cassandra for implementing at least one delivery - this doesn't have to be part of the persistent stream API, but could be a helper component that helps in implementing the code that sets up the stream.

Immutables library cumbersome to use with IntelliJ

While the steps described at http://www.lagomframework.com/documentation/1.0.x/ImmutablesInIDEs.html#IntelliJ_IDEA do work to successfully set up the Immutables library and have the classes generated the caveat about setting the the Production and Test sources directory isn't completely correct. According to the documentation you are supposed to have the classes generated under target but this directory is excluded by default under the Project Structure of the project in IntelliJ causing you to be unable to reference the generated classes in your code.

You would therefor need to place the sources elsewhere and mark that directory as generated sources. This step is necessary each time the project is imported in IntelliJ.

Original conversation on Gitter:

yannickdeturck Mar 15 21:23
Is the Immutables library supposed to be usable when using IntelliJ? I followed the steps described at http://www.lagomframework.com/documentation/1.0.x/ImmutablesInIDEs.html#IntelliJ_IDEA but the generated classes end up in an ignored folder (target/scala-2.11/src_managed/main) as mentioned by James (https://youtrack.jetbrains.com/issue/SCL-8543#comment=27-1285955) and thus cannot be referenced in the code

jroper 02:12
@yannickdeturck we originally were going to have all the samples use immutables and push it strongly as the way of doing things, but the problems with intellij led us to not do that
yes, it's usable, but it's a real pain, you have to configure the intellij annotation processor to put the annotations somewhere that isn't in the target directory, make sure you add that to your .gitignore, and then manually mark that directory as a generated source directory in intellij. and just for laughs, every time you reimport the project into intellij, that config will be lost, so you'll have to do it all again

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.