diff --git a/backend-services/feed-service/app/models/MongoDBClient.scala b/backend-services/feed-service/app/models/MongoDBClient.scala new file mode 100644 index 0000000000000000000000000000000000000000..b7af45a7e15431daa011b86bbed4ad506d6bcc53 --- /dev/null +++ b/backend-services/feed-service/app/models/MongoDBClient.scala @@ -0,0 +1,92 @@ +package models + +import org.mongodb.scala.{MongoClient, MongoDatabase, MongoCollection, Document, FindObservable, Observer, Observable} +import org.mongodb.scala.model.{Filters, Projections, Sorts} +import org.bson.conversions.Bson + +import scala.concurrent.ExecutionContext.Implicits.global +import scala.concurrent.Future +import scala.util.{Success, Failure, Try} + + +/** + * A MongoDB client for connecting to and interacting with a MongoDB database. + * + * @constructor Creates a new instance of the MongoDBClient class. + */ +class MongoDBClient { + // Connects to a MongoDB Client when class is constructed + private var client: MongoClient = this.connect() + + /** + * Connects to a MongoDB database using the default MongoDB connection string. + * + * @return A MongoClient instance. + */ + def connect(): MongoClient = { + MongoClient("mongodb://localhost:27017/") + } + + /** + * Gets a reference to a MongoDB database. + * + * @param database The name of the database to retrieve. + * @return A Future containing a MongoDatabase instance. + */ + def getDatabase(database: String): Future[MongoDatabase] = Future { + client.getDatabase(database) + } + + /** + * Gets a reference to a MongoDB collection within a database. + * + * @param database The MongoDatabase instance containing the desired collection. + * @param collection The name of the collection to retrieve. + * @return A Future containing a MongoCollection instance. + */ + def getCollection(database: MongoDatabase, collection: String): Future[MongoCollection[Document]] = Future { + database.getCollection(collection) + } + + /** + * Finds documents in a MongoDB collection. + * + * @param collection The MongoCollection instance to search. + * @param filter A Bson filter to apply to the search. + * @param projection A Bson projection to apply to the search. + * @param sort A Bson sort to apply to the search. + * @return A Future containing a sequence of matching documents as Documents. + */ + def find( + collection: MongoCollection[Document], + filter: Bson = Filters.empty(), + projection: Bson = Projections.excludeId(), + sort: Bson = Sorts.ascending("_id") + ): Future[Seq[Document]] = { + collection.find(filter) + .projection(projection) + .sort(sort) + .toFuture() + } + + /** + * Inserts a document into a MongoDB collection. + * + * @param collection The MongoCollection instance to insert into. + * @param document The document to insert. + * @return A Future containing the ID of the inserted document. + * @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() + + futureResult.map(result => { + if (result.wasAcknowledged()) { + // Grab the generated ID of the inserted document + result.getInsertedId().asObjectId.getValue().toString() + } else { + throw new RuntimeException("Insertion was not acknowledged") + } + }) + } +} diff --git a/backend-services/feed-service/build.sbt b/backend-services/feed-service/build.sbt index ed85231113e7f816b91841357b43d65944776d63..2367eff2107702816e934914796c14e48cbabbb7 100644 --- a/backend-services/feed-service/build.sbt +++ b/backend-services/feed-service/build.sbt @@ -15,3 +15,4 @@ libraryDependencies += "org.scalatestplus.play" %% "scalatestplus-play" % "5.0.0 // Adds additional packages into conf/routes // play.sbt.routes.RoutesKeys.routesImport += "com.daily.binders._" +libraryDependencies += "org.mongodb.scala" %% "mongo-scala-driver" % "4.3.0"