Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update to Play 2.5.10 & ReactiveMongo 0.12.1 #9

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 43 additions & 16 deletions app/Global.scala → app/backend/Global.scala
Original file line number Diff line number Diff line change
@@ -1,20 +1,41 @@
import javax.inject.Inject
package backend

import play.api.Play.current
import play.api.libs.concurrent.Execution.Implicits.defaultContext
import play.api.libs.iteratee.Enumerator
import javax.inject._

import scala.util.{Failure,Success}

import scala.concurrent.{Await,ExecutionContext}
import scala.concurrent.duration._

import play.api._
import play.api.libs.json.Json
import play.api.{ Logger, Application, GlobalSettings }
import play.api.{Logger, Application}
import com.google.inject.AbstractModule
import play.api.inject.{ApplicationLifecycle, Binding, Module}

import play.modules.reactivemongo.ReactiveMongoApi
import play.modules.reactivemongo.json.collection.JSONCollection
import reactivemongo.play.json.collection.JSONCollection

/**
* MongoDB module.
*/
@Singleton
final class GlobalModule(
environment: Environment, configuration: Configuration)
extends AbstractModule {

def configure() = bind(classOf[Global]).asEagerSingleton()
}

class Global @Inject() (
val reactiveMongoApi: ReactiveMongoApi) extends GlobalSettings {
appCycle: ApplicationLifecycle,
reactiveMongoApi: ReactiveMongoApi,
implicit val ec: ExecutionContext) {

def collection = reactiveMongoApi.db.collection[JSONCollection]("posts")
private def collection = reactiveMongoApi.database.map(
_.collection[JSONCollection]("posts"))

val posts = List(
private def posts = List(
Json.obj(
"text" -> "Have you heard about the Web Components revolution?",
"username" -> "Eric",
Expand Down Expand Up @@ -65,18 +86,24 @@ class Global @Inject() (
)
)

override def onStart(app: Application) {
private def onStart() {
Logger.info("Application has started")

collection.bulkInsert(posts.toStream, ordered = true).
foreach(i => Logger.info("Database was initialized"))
Await.result(
collection.flatMap(_.bulkInsert(posts.toStream, ordered = true)).andThen {
case Failure(reason) =>
Logger.error("Fails to initialize database", reason)

case _ => Logger.info("Database was initialized")
}, 10.seconds)
}

override def onStop(app: Application) {
appCycle.addStopHook { () =>
Logger.info("Application shutdown...")

collection.drop().onComplete {
case _ => Logger.info("Database collection dropped")
}
collection.flatMap(_.drop(false)).
map(_ => Logger.info("Database collection dropped"))
}

onStart()
}
16 changes: 8 additions & 8 deletions app/backend/PostRepo.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package backend

import play.api.libs.json.{JsObject, Json}
import play.modules.reactivemongo.ReactiveMongoApi
import play.modules.reactivemongo.json.collection.JSONCollection
import reactivemongo.play.json.collection.JSONCollection
import reactivemongo.api.ReadPreference
import reactivemongo.api.commands.WriteResult
import reactivemongo.bson.{BSONObjectID, BSONDocument}
Expand All @@ -23,16 +23,16 @@ class PostMongoRepo(reactiveMongoApi: ReactiveMongoApi) extends PostRepo {
// BSON-JSON conversions
import play.modules.reactivemongo.json._

protected def collection =
reactiveMongoApi.db.collection[JSONCollection]("posts")
private def collection(implicit ec: ExecutionContext) =
reactiveMongoApi.database.map(_.collection[JSONCollection]("posts"))

def find()(implicit ec: ExecutionContext): Future[List[JsObject]] =
collection.find(Json.obj()).cursor[JsObject](ReadPreference.Primary).collect[List]()
collection.flatMap(_.find(Json.obj()).
cursor[JsObject](ReadPreference.Primary).collect[List]())

def update(selector: BSONDocument, update: BSONDocument)(implicit ec: ExecutionContext): Future[WriteResult] = collection.update(selector, update)
def update(selector: BSONDocument, update: BSONDocument)(implicit ec: ExecutionContext): Future[WriteResult] = collection.flatMap(_.update(selector, update))

def remove(document: BSONDocument)(implicit ec: ExecutionContext): Future[WriteResult] = collection.remove(document)
def remove(document: BSONDocument)(implicit ec: ExecutionContext): Future[WriteResult] = collection.flatMap(_.remove(document))

def save(document: BSONDocument)(implicit ec: ExecutionContext): Future[WriteResult] =
collection.update(BSONDocument("_id" -> document.get("_id").getOrElse(BSONObjectID.generate)), document, upsert = true)
def save(document: BSONDocument)(implicit ec: ExecutionContext): Future[WriteResult] = collection.flatMap(_.update(BSONDocument("_id" -> document.get("_id").getOrElse(BSONObjectID.generate)), document, upsert = true))
}
43 changes: 21 additions & 22 deletions app/controllers/Posts.scala
Original file line number Diff line number Diff line change
Expand Up @@ -21,37 +21,36 @@ class Posts @Inject() (val reactiveMongoApi: ReactiveMongoApi)

def postRepo = new backend.PostMongoRepo(reactiveMongoApi)

def list = Action.async {implicit request =>
postRepo.find()
.map(posts => Ok(Json.toJson(posts.reverse)))
.recover {case PrimaryUnavailableException => InternalServerError("Please install MongoDB")}
val list = Action.async { implicit request =>
postRepo.find().map(posts => Ok(Json.toJson(posts.reverse)))
}

def like(id: String) = Action.async(BodyParsers.parse.json) { implicit request =>
val value = (request.body \ Favorite).as[Boolean]
postRepo.update(BSONDocument(Id -> BSONObjectID(id)), BSONDocument("$set" -> BSONDocument(Favorite -> value)))
.map(le => Ok(Json.obj("success" -> le.ok)))
}
def like(id: BSONObjectID) =
Action.async(BodyParsers.parse.json) { implicit request =>
val value = (request.body \ Favorite).as[Boolean]
postRepo.update(BSONDocument(Id -> id),
BSONDocument("$set" -> BSONDocument(Favorite -> value))).
map(le => Ok(Json.obj("success" -> le.ok)))
}

def update(id: String) = Action.async(BodyParsers.parse.json) { implicit request =>
val value = (request.body \ Text).as[String]
postRepo.update(BSONDocument(Id -> BSONObjectID(id)), BSONDocument("$set" -> BSONDocument(Text -> value)))
.map(le => Ok(Json.obj("success" -> le.ok)))
}
def update(id: BSONObjectID) =
Action.async(BodyParsers.parse.json) { implicit request =>
val value = (request.body \ Text).as[String]
postRepo.update(BSONDocument(Id -> id),
BSONDocument("$set" -> BSONDocument(Text -> value))).
map(le => Ok(Json.obj("success" -> le.ok)))
}

def delete(id: String) = Action.async {
postRepo.remove(BSONDocument(Id -> BSONObjectID(id)))
.map(le => RedirectAfterPost(le, routes.Posts.list()))
def delete(id: BSONObjectID) = Action.async {
postRepo.remove(BSONDocument(Id -> id)).
map(_ => Redirect(routes.Posts.list()))
}

private def RedirectAfterPost(result: WriteResult, call: Call): Result =
if (result.inError) InternalServerError(result.toString)
else Redirect(call)

def add = Action.async(BodyParsers.parse.json) { implicit request =>
val add = Action.async(BodyParsers.parse.json) { implicit request =>
val username = (request.body \ Username).as[String]
val text = (request.body \ Text).as[String]
val avatar = (request.body \ Avatar).as[String]

postRepo.save(BSONDocument(
Text -> text,
Username -> username,
Expand Down
16 changes: 9 additions & 7 deletions build.sbt
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
name := """PlayReactiveMongoPolymer"""
import play.sbt.routes.RoutesKeys

name := "PlayReactiveMongoPolymer"

version := "1.0-SNAPSHOT"

scalaVersion := "2.11.7"
scalaVersion := "2.11.8"

routesGenerator := InjectedRoutesGenerator

libraryDependencies ++= Seq(
"org.reactivemongo" %% "play2-reactivemongo" % "0.11.7.play24",
"org.specs2" %% "specs2-core" % "3.6.5" % "test",
"org.specs2" %% "specs2-junit" % "3.6.5" % "test",
"org.specs2" %% "specs2-mock" % "3.6.5" % "test"
)
"org.reactivemongo" %% "play2-reactivemongo" % "0.12.1"
) ++ Seq("core", "junit", "mock").map(m =>
"org.specs2" %% s"specs2-$m" % "3.6.5" % Test)

lazy val root = (project in file(".")).enablePlugins(PlayScala)

JsEngineKeys.engineType := JsEngineKeys.EngineType.Node

RoutesKeys.routesImport += "play.modules.reactivemongo.PathBindables._"
8 changes: 2 additions & 6 deletions conf/application.conf
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,6 @@ application.secret="1f5UEufe^l6iVYii8Lm7g:H4[C<9uaPbsqKwtHE/t`NWF@XRv=cC]KmYe^8j
# ~~~~~
application.langs="en"

# Global object class
# ~~~~~
# Define the Global object class for this application.
# Default to Global in the root package.
# application.global=Global

# Router
# ~~~~~
# Define the Router object to use for this application.
Expand Down Expand Up @@ -49,4 +43,6 @@ application.langs="en"

play.modules.enabled += "play.modules.reactivemongo.ReactiveMongoModule"

play.modules.enabled += "backend.GlobalModule"

mongodb.uri = "mongodb://localhost:27017/posts"
1 change: 0 additions & 1 deletion conf/play.plugins

This file was deleted.

6 changes: 3 additions & 3 deletions conf/routes
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
GET / controllers.Assets.at(path="/public", file="app/index.html")

GET /api/posts controllers.Posts.list
PATCH /api/post/:id/like controllers.Posts.like(id: String)
PATCH /api/post/:id controllers.Posts.update(id: String)
PATCH /api/post/:id/like controllers.Posts.like(id: reactivemongo.bson.BSONObjectID)
PATCH /api/post/:id controllers.Posts.update(id: reactivemongo.bson.BSONObjectID)
POST /api/post controllers.Posts.add
DELETE /api/post/:id controllers.Posts.delete(id : String)
DELETE /api/post/:id controllers.Posts.delete(id: reactivemongo.bson.BSONObjectID)

GET /*file controllers.Assets.at(path="/public", file)
2 changes: 1 addition & 1 deletion project/build.properties
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#Activator-generated Properties
#Tue Mar 03 13:10:16 CET 2015
template.uuid=88679796-ef1c-40cd-82c2-d3114cfa2881
sbt.version=0.13.9
sbt.version=0.13.11
2 changes: 1 addition & 1 deletion project/plugins.sbt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
resolvers += "Typesafe repository" at "https://repo.typesafe.com/typesafe/releases/"

// The Play plugin
addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.4.3")
addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.5.10")
addSbtPlugin("com.github.dwickern" % "sbt-bower" % "1.0.3")
7 changes: 4 additions & 3 deletions test/controllers/PostsSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ import play.api.mvc._
import play.api.test.Helpers._
import play.api.test._
import play.modules.reactivemongo.ReactiveMongoApi
import reactivemongo.play.json._ // JSON/BSON
import reactivemongo.api.commands.LastError
import reactivemongo.bson.BSONDocument
import reactivemongo.bson.{BSONDocument,BSONObjectID}

import scala.concurrent.{ExecutionContext, Future}
import scala.concurrent.ExecutionContext.Implicits.global
Expand All @@ -20,8 +21,8 @@ object PostsSpec extends org.specs2.mutable.Specification with Results with Mock
val mockPostRepo = mock[PostMongoRepo]
val reactiveMongoRepo = mock[ReactiveMongoApi]

val FirstPostId = "5559e224cdecd3b535e8b681"
val SecondPostId = "5559e224cdecd3b535e8b682"
val FirstPostId = BSONObjectID.parse("5559e224cdecd3b535e8b681").get
val SecondPostId = BSONObjectID.parse("5559e224cdecd3b535e8b682").get

val wojciechPost = Json.obj(
Id -> FirstPostId,
Expand Down