Assumptions:
MongoDB is running at localhost:27017
This project is modeled after https://github.com/sap1ens/akka-microservice . Please refer to it if there is not enough information below to help. If it gets too confusing, I can add code from other files if necessary.
Questions based on RegistrationsService.scala
Why is it trying to connect to MongoDB and insert the document on startup before any PostRegistrationMessage is sent to RegistrationsService actor?
Why is it failing?
How can I convert registrationJsValue into MongoDBObject and insert it into collection?
Relevant info in build.sbt
scalaVersion := "2.10.4"
val akkaVersion = "2.3.8"
val sprayVersion = "1.3.1"
// Main dependencies
libraryDependencies ++= Seq(
"com.typesafe.akka" %% "akka-actor" % akkaVersion,
"com.typesafe.akka" %% "akka-slf4j" % akkaVersion,
"io.spray" % "spray-can" % sprayVersion,
"io.spray" % "spray-routing" % sprayVersion,
"io.spray" % "spray-client" % sprayVersion,
"io.spray" %% "spray-json" % sprayVersion,
"com.typesafe" % "config" % "1.2.1",
"ch.qos.logback" % "logback-classic" % "1.1.2",
"org.mongodb" %% "casbah" % "2.7.4"
)
RegistrationService.scala (like ExampleService.scala in git repo)
package service
import akka.actor.{Props, ActorLogging, Actor}
import spray.json._
import com.mongodb.util.JSON
import com.mongodb.casbah.Imports._
import model.Registration
import model.RegistrationProtocol._
object RegistrationsService {
case class PostRegistrationMessage(registration: Registration)
def props(property: String) = Props(classOf[RegistrationsService], property)
}
class RegistrationsService(property: String) extends Actor with ActorLogging {
import RegistrationsService._
def receive = {
case PostRegistrationMessage(registration) => {
val registrationJsValue = registration.toJson
val dbObject = JSON.parse(registrationJsValue.toString()).asInstanceOf[DBObject]
val mongoClientURI = MongoClientURI("mongodb://localhost:27017/")
val mongoClient = MongoClient(mongoClientURI)
val someDB = mongoClient("somedb")
val registrationsColl = someDB("registratoins")
log.info(s"Got access to registratoins collection")
registrationsColl.insert(MongoDBObject("hello" -> "world"))
log.info(s"Inserted a doc to registratoins collection")
mongoClient.close()
log.info(s"Closed client connection to mongo")
sender() ! registrationJsValue
}
}
}
sbt run
14:01:10.655 [microservice-system-akka.actor.default-dispatcher-3] INFO c.e.a.s.RegistrationsService - Got access to registratoins collection
14:01:11.383 [microservice-system-akka.actor.default-dispatcher-3] DEBUG spray.can.server.HttpListener - Binding to localhost/127.0.0.1:8878
14:01:11.475 [microservice-system-akka.actor.default-dispatcher-3] DEBUG akka.io.TcpListener - Successfully bound to /127.0.0.1:8878
14:01:11.480 [microservice-system-akka.actor.default-dispatcher-6] INFO spray.can.server.HttpListener - Bound to localhost/127.0.0.1:8878
14:01:20.704 [microservice-system-akka.actor.default-dispatcher-5] ERROR akka.actor.OneForOneStrategy - Timed out after 10000 ms while waiting for a server that matches AnyServerSelector{}. Client view of cluster state is {type=Unknown, servers=[{address=localhost:27017, type=Unknown, state=Connecting, exception={java.lang.NullPointerException}}]
com.mongodb.MongoTimeoutException: Timed out after 10000 ms while waiting for a server that matches AnyServerSelector{}. Client view of cluster state is {type=Unknown, servers=[{address=localhost:27017, type=Unknown, state=Connecting, exception={java.lang.NullPointerException}}]
at com.mongodb.BaseCluster.getServer(BaseCluster.java:82) ~[mongo-java-driver-2.12.4.jar:na]
at com.mongodb.DBTCPConnector.getServer(DBTCPConnector.java:654) ~[mongo-java-driver-2.12.4.jar:na]
at com.mongodb.DBTCPConnector.access$300(DBTCPConnector.java:39) ~[mongo-java-driver-2.12.4.jar:na]
at com.mongodb.DBTCPConnector$MyPort.getConnection(DBTCPConnector.java:503) ~[mongo-java-driver-2.12.4.jar:na]
at com.mongodb.DBTCPConnector$MyPort.get(DBTCPConnector.java:451) ~[mongo-java-driver-2.12.4.jar:na]
at com.mongodb.DBTCPConnector.getPrimaryPort(DBTCPConnector.java:409) ~[mongo-java-driver-2.12.4.jar:na]
at com.mongodb.DBCollectionImpl.insert(DBCollectionImpl.java:182) ~[mongo-java-driver-2.12.4.jar:na]
at com.mongodb.DBCollectionImpl.insert(DBCollectionImpl.java:165) ~[mongo-java-driver-2.12.4.jar:na]
at com.mongodb.DBCollection.insert(DBCollection.java:93) ~[mongo-java-driver-2.12.4.jar:na]
at com.mongodb.casbah.MongoCollectionBase$class.insert(MongoCollection.scala:621) ~[casbah-core_2.10-2.7.4.jar:2.7.4]
at com.mongodb.casbah.MongoCollection.insert(MongoCollection.scala:1109) ~[casbah-core_2.10-2.7.4.jar:2.7.4]
at service.RegistrationsService$$anonfun$receive$1.applyOrElse(RegistrationsService.scala:47) ~[classes/:na]
at akka.actor.Actor$class.aroundReceive(Actor.scala:465) ~[akka-actor_2.10-2.3.8.jar:na]
at service.RegistrationsService.aroundReceive(RegistrationsService.scala:20) ~[classes/:na]
at akka.actor.ActorCell.receiveMessage(ActorCell.scala:516) [akka-actor_2.10-2.3.8.jar:na]
at akka.actor.ActorCell.invoke(ActorCell.scala:487) [akka-actor_2.10-2.3.8.jar:na]
at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:254) [akka-actor_2.10-2.3.8.jar:na]
at akka.dispatch.Mailbox.run(Mailbox.scala:221) [akka-actor_2.10-2.3.8.jar:na]
at akka.dispatch.Mailbox.exec(Mailbox.scala:231) [akka-actor_2.10-2.3.8.jar:na]
at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260) [scala-library.jar:na]
at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339) [scala-library.jar:na]
at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979) [scala-library.jar:na]
at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107) [scala-library.jar:na]
^C14:01:42.231 [microservice-system-akka.actor.default-dispatcher-11] INFO akka.actor.LocalActorRef - Message [akka.actor.Terminated] from Actor[akka://microservice-system/user/$a#1754981697] to Actor[akka://microservice-system/user/IO-HTTP/listener-0#-602059531] was not delivered. [1] dead letters encountered. This logging can be turned off or adjusted with configuration settings 'akka.log-dead-letters' and 'akka.log-dead-letters-during-shutdown'.
14:01:42.236 [microservice-system-akka.actor.default-dispatcher-11] DEBUG akka.event.EventStream - shutting down: StandardOutLogger started
Not sure what you mean by the following.
Why is it trying to connect to MongoDB and insert the document on startup before any PostRegistrationMessage is sent to RegistrationsService actor?
In the example code (for RegistrationsService
) you have shown the only connection that is made is inside the Actor's receive method. Unless you (or some other piece of code is sending this message, the actor will not try to connect to Mongo.
On a side note, what are you creating a Mongo connection inside the Actor's receive
method ? You should avoid any heavy weight operation inside the receive
method. You can create a Mongo connection outside the Actor and then inject it in the Actor's constructor to be used in the Receive method.
Have you written a standalone program/test that connects to your MongoDB using the casbah driver? It should work independently of your actor code and will help your isolate any issues (if there is one) with the driver and connection code.
PS: This may not the be the answer to your question but I didn't want to write it in the comments part because of space and formatting limitations.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.