diff --git a/backend-services/feed-service/app/controllers/DailyController.scala b/backend-services/feed-service/app/controllers/DailyController.scala index 3cb1c7363987ba19a019d074708280708748c6c5..9b2dc14718484c5da888805667e19e78a7e7aab6 100644 --- a/backend-services/feed-service/app/controllers/DailyController.scala +++ b/backend-services/feed-service/app/controllers/DailyController.scala @@ -2,6 +2,7 @@ package controllers import javax.inject._ import play.api.mvc._ +import play.api.libs.json.JsValue import models.{Daily} @@ -22,7 +23,7 @@ class DailyController @Inject()(val controllerComponents: ControllerComponents) try { val result: Seq[Daily] = Daily.getAllDailiesAsync() - val jsonResult = Daily.toJson(result) + val jsonResult: JsValue = Daily.toJson(result) Ok(jsonResult) } catch { case _: TimeoutException => BadRequest("Request timed out") @@ -38,7 +39,7 @@ class DailyController @Inject()(val controllerComponents: ControllerComponents) try { val result: Seq[Daily] = Daily.getUserDailiesAsync(new ObjectId("641128f7e80bcd1ba39d04af")) - val jsonResult = Daily.toJson(result) + val jsonResult: JsValue = Daily.toJson(result) Ok(jsonResult) } catch { case _: TimeoutException => BadRequest("Request timed out") @@ -54,7 +55,7 @@ class DailyController @Inject()(val controllerComponents: ControllerComponents) try { val result: Seq[Daily] = Daily.getUserFeedAsync(new ObjectId("641128f7e80bcd1ba39d04ae")) - val jsonResult = Daily.toJson(result) + val jsonResult: JsValue = Daily.toJson(result) Ok(jsonResult) } catch { case _: TimeoutException => BadRequest("Request timed out") @@ -62,13 +63,16 @@ class DailyController @Inject()(val controllerComponents: ControllerComponents) } } + /** + * Create an Action to create a Daily. + */ def create() = Action { println("DailyController:create") try { // Dummy data - val result = Daily.createDailyAsync(new ObjectId("641128f7e80bcd1ba39d04ae"), new ObjectId("641128f7e80bcd1ba39d04ae"), "asddas") - val jsonResult = Daily.toJson(result) + val result: Daily = Daily.createDailyAsync(new ObjectId("641128f7e80bcd1ba39d04ae"), new ObjectId("641128f7e80bcd1ba39d04ae"), "asddas") + val jsonResult: JsValue = Daily.toJson(result) Ok(jsonResult) } catch { case _: TimeoutException => BadRequest("Request timed out") @@ -76,6 +80,9 @@ class DailyController @Inject()(val controllerComponents: ControllerComponents) } } + /** + * Create an Action to like a Daily. + */ def like() = Action { println("DailyController:like") diff --git a/backend-services/feed-service/app/models/Daily.scala b/backend-services/feed-service/app/models/Daily.scala index 7617f0d3bd7f760c0ff681a3453edcc8cd9ea07c..1430caccec22cbb9099754138c52dc0702e911d7 100644 --- a/backend-services/feed-service/app/models/Daily.scala +++ b/backend-services/feed-service/app/models/Daily.scala @@ -36,17 +36,17 @@ object Daily { val now: Date = Date.from(Instant.now()) val daily: Daily = Daily(None, userId, questionId, content, Seq.empty[ObjectId], now, now) val future: Future[Daily] = dailyRepo.insertDaily(daily) - Await.result(future, timeout.seconds) + Await.result[Daily](future, timeout.seconds) } def getAllDailiesAsync(timeout: Int = 4): Seq[Daily] = { val future: Future[Seq[Daily]] = dailyRepo.getAllDailies() - Await.result(future, timeout.seconds) + Await.result[Seq[Daily]](future, timeout.seconds) } def getUserDailiesAsync(userId: ObjectId, timeout: Int = 4): Seq[Daily] = { val future: Future[Seq[Daily]] = dailyRepo.getUserDailies(userId) - Await.result(future, timeout.seconds) + Await.result[Seq[Daily]](future, timeout.seconds) } def getUserFeedAsync(userId: ObjectId, timeout: Int = 4): Seq[Daily] = { @@ -56,7 +56,7 @@ object Daily { feed: Seq[Daily] <- dailyRepo.getUserDailies(friends) } yield feed - Await.result(result, timeout.seconds) + Await.result[Seq[Daily]](result, timeout.seconds) } def likeAsync(dailyId: ObjectId, userId: ObjectId, timeout: Int = 4): Unit = { @@ -65,12 +65,12 @@ object Daily { unit: Unit <- dailyRepo.like(daily, userId) } yield unit - Await.result(result, timeout.seconds) + Await.result[Unit](result, timeout.seconds) } // Convert from Daily object to JSON (serializing to JSON) def toJson(daily: Daily): JsValue = { - val usersLikedAsJsStrings = daily.usersLiked.map(id => JsString(id.toString())) + val usersLikedAsJsStrings: Seq[JsString] = daily.usersLiked.map[JsString](id => JsString(id.toString())) val dateFormat: SimpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'") val formattedCreatedAt: String = dateFormat.format(daily.createdAt) @@ -86,14 +86,14 @@ object Daily { "updatedAt" -> JsString(formattedUpdatedAt) ) - Json.toJson(JsObject(dailyJson)) + Json.toJson[JsObject](JsObject(dailyJson)) } // Convert from Daily set to JSON (serializing to JSON) def toJson(dailies: Seq[Daily]): JsValue = { - val dailiesJson = dailies.map(daily => Daily.toJson(daily)) + val dailiesJson: Seq[JsValue] = dailies.map(daily => Daily.toJson(daily)) - Json.toJson(JsArray(dailiesJson)) + Json.toJson[JsArray](JsArray(dailiesJson)) } def toString(daily: Daily): String = diff --git a/backend-services/feed-service/app/models/MongoDBClient.scala b/backend-services/feed-service/app/models/MongoDBClient.scala index dd2c719b5e99ae14086379ed27be96bca4363a6b..2edd41218a5c7f1646790ad230e63fdc6e175b90 100644 --- a/backend-services/feed-service/app/models/MongoDBClient.scala +++ b/backend-services/feed-service/app/models/MongoDBClient.scala @@ -3,6 +3,7 @@ package models import utils.ConfigHelper import org.mongodb.scala.{MongoClient, MongoDatabase, MongoCollection, Document} +import com.mongodb.client.result.{InsertOneResult, UpdateResult} import org.mongodb.scala.model.{Filters, Projections, Sorts} import org.bson.conversions.Bson import org.bson.types.ObjectId @@ -67,8 +68,8 @@ class MongoDBClient { projection: Bson = Projections.excludeId(), sort: Bson = Sorts.ascending("_id") ): Future[Seq[Document]] = { - collection.find(filter) - .projection(projection) + collection.find[Document](filter) + // .projection(projection) .sort(sort) .toFuture() } @@ -82,9 +83,9 @@ class MongoDBClient { * @throws RuntimeException if the insertion was not acknowledged by the database. */ def insertOne(collection: MongoCollection[Document], document: Document): Future[String] = { - val futureResult = collection.insertOne(document).toFuture() + val futureResult: Future[InsertOneResult] = collection.insertOne(document).toFuture() - futureResult.map(result => { + futureResult.map[String]((result: InsertOneResult) => { if (result.wasAcknowledged()) { // Grab the generated ID of the inserted document result.getInsertedId().asObjectId.getValue().toString() @@ -103,10 +104,10 @@ class MongoDBClient { * @throws RuntimeException if the update was not acknowledged by the database. */ def updateOne(collection: MongoCollection[Document], documentId: ObjectId, updates: Seq[Bson]): Future[Unit] = { - val filter = Filters.equal("_id", documentId) - val futureResult = collection.updateOne(filter, updates).toFuture() + val filter: Bson = Filters.equal[ObjectId]("_id", documentId) + val futureResult: Future[UpdateResult] = collection.updateOne(filter, updates).toFuture() - futureResult.map(result => { + futureResult.map[Unit]((result: UpdateResult) => { if (!result.wasAcknowledged()) { throw new RuntimeException("Update was not acknowledged") } diff --git a/backend-services/feed-service/app/repositories/DailyRepository.scala b/backend-services/feed-service/app/repositories/DailyRepository.scala index 69f118db233ea2c67256535b149527b5b5a1a6f8..48846acf0815abc64462872588908470214347e5 100644 --- a/backend-services/feed-service/app/repositories/DailyRepository.scala +++ b/backend-services/feed-service/app/repositories/DailyRepository.scala @@ -1,10 +1,10 @@ package repositories -import com.typesafe.config.ConfigFactory +import com.typesafe.config.{Config, ConfigFactory} import models.{Daily, MongoDBClient} -import org.mongodb.scala.{MongoCollection, Document} +import org.mongodb.scala.{MongoDatabase, MongoCollection, Document} import org.mongodb.scala.model.{Filters, Updates} import org.bson.types.ObjectId import org.bson.conversions.Bson @@ -18,10 +18,10 @@ import scala.collection.JavaConverters._ class DailyRepository extends MongoDBClient { // Loads the default configuration - private val config = ConfigFactory.load() + private val config: Config = ConfigFactory.load() - private val databaseName = config.getString("mongo.feedService.db") - private val collectionName = config.getString("mongo.dailies.collection") + private val databaseName: String = config.getString("mongo.feedService.db") + private val collectionName: String = config.getString("mongo.dailies.collection") /** * Returns a reference to a MongoDB collection within a database. @@ -31,12 +31,12 @@ class DailyRepository extends MongoDBClient { * @throws TimeoutException if the Future doesn't complete within the 3 second timeout. */ private def dailiesCollection: MongoCollection[Document] = { - val futureCollection = for { - database <- getDatabase(databaseName) - collection <- getCollection(database, collectionName) + val futureCollection: Future[MongoCollection[Document]] = for { + database: MongoDatabase <- getDatabase(databaseName) + collection: MongoCollection[Document] <- getCollection(database, collectionName) } yield collection - Await.result(futureCollection, 3.seconds) + Await.result[MongoCollection[Document]](futureCollection, 3.seconds) } /** @@ -47,7 +47,7 @@ class DailyRepository extends MongoDBClient { def getDaily(dailyId: ObjectId): Future[Daily] = { val filter = Filters.equal("_id", dailyId) val document: Future[Document] = find(dailiesCollection, filter).map(x => x(0)) - document.map(doc => DailyRepository.fromMongoDocument(doc)) + document.map[Daily](doc => DailyRepository.fromMongoDocument(doc)) } /** @@ -57,7 +57,7 @@ class DailyRepository extends MongoDBClient { */ def getAllDailies(): Future[Seq[Daily]] = { val documents: Future[Seq[Document]] = find(dailiesCollection) - documents.map(docs => DailyRepository.fromMongoDocument(docs)) + documents.map[Seq[Daily]](docs => DailyRepository.fromMongoDocument(docs)) } /** @@ -66,10 +66,10 @@ class DailyRepository extends MongoDBClient { * @return A Future containing a sequence of the user's Daily objects. */ def getUserDailies(userId: ObjectId): Future[Seq[Daily]] = { - val userFilter = Filters.equal("user_id", userId) + val userFilter: Bson = Filters.equal("user_id", userId) val documents: Future[Seq[Document]] = find(dailiesCollection, userFilter) - documents.map(docs => DailyRepository.fromMongoDocument(docs)) + documents.map[Seq[Daily]](docs => DailyRepository.fromMongoDocument(docs)) } /** @@ -79,10 +79,10 @@ class DailyRepository extends MongoDBClient { */ def getUserDailies(userIds: Seq[ObjectId]): Future[Seq[Daily]] = { // The syntax userIds: _* is used to convert the List of ObjectId instances to a variable-length argument list - val userFilter = Filters.in("user_id", userIds: _*) + val userFilter: Bson = Filters.in("user_id", userIds: _*) val documents: Future[Seq[Document]] = find(dailiesCollection, userFilter) - documents.map(docs => DailyRepository.fromMongoDocument(docs)) + documents.map[Seq[Daily]](docs => DailyRepository.fromMongoDocument(docs)) } /** @@ -92,7 +92,7 @@ class DailyRepository extends MongoDBClient { */ def insertDaily(daily: Daily): Future[Daily] = { // Don't supply an ID as Mongo will generate one for us - val document = Document( + val document: Document = Document( "user_id" -> daily.userId, "question_id" -> daily.questionId, "content" -> daily.content, @@ -101,21 +101,24 @@ class DailyRepository extends MongoDBClient { "updatedAt" -> daily.updatedAt ) - val result = insertOne(dailiesCollection, document) + val result: Future[String] = insertOne(dailiesCollection, document) // Return a Daily entity with the generated ID - result.flatMap(id => { - val updatedDaily = daily.copy(id = Some(new ObjectId(id))) + result.flatMap[Daily](id => { + val updatedDaily: Daily = daily.copy(id = Some(new ObjectId(id))) Future.successful(updatedDaily) }) } + /** + * Add a user like to the given Daily record in the database. + */ def like(daily: Daily, user: ObjectId): Future[Unit] = { val updatedUsersLiked: Seq[ObjectId] = daily.usersLiked :+ user val update: Bson = Updates.set("usersLiked", updatedUsersLiked) val updates: Seq[Bson] = Seq(update) - val dailyId = daily.id.getOrElse(throw new RuntimeException) + val dailyId: ObjectId = daily.id.getOrElse(throw new RuntimeException) updateOne(dailiesCollection, dailyId, updates) } } @@ -135,6 +138,6 @@ object DailyRepository { } def fromMongoDocument(documents: Seq[Document]): Seq[Daily] = { - documents.map(document => DailyRepository.fromMongoDocument(document)) + documents.map[Daily](document => DailyRepository.fromMongoDocument(document)) } }