| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104 |
- package com.weEat.services
- import play.api.Configuration
- import org.mongodb.scala.{MongoClient,MongoDatabase,MongoCollection}
- import org.mongodb.scala.bson.codecs.Macros._
- import org.bson.{BsonReader,BsonWriter}
- import org.bson.codecs.{Codec,DecoderContext,EncoderContext}
- import org.bson.codecs.configuration.{CodecProvider,CodecRegistry}
- import org.bson.codecs.configuration.CodecRegistries.{fromRegistries,fromProviders}
- import com.weEat.models._
- import com.weEat.shared.models.{USDANode,RecipeNode,FoodNode,UnitType}
- import javax.inject.{Inject,Singleton}
- import scala.reflect.ClassTag
- import com.weEat.migrations.{Migration,Metadata}
- import scala.concurrent.ExecutionContext
- import scala.util.{Try,Success,Failure}
- import gov.usda.nal.fdc.models.Nutrient
- @Singleton
- class MongoDBService @Inject()(config: Configuration) {
- implicit val ec = scala.concurrent.ExecutionContext.global
- private val prefix = "mongo"
- val url = config.getOptional[String](s"$prefix.url").getOrElse("localhost")
- val name = config.getOptional[String](s"$prefix.name").getOrElse("recipes")
- val user = config.getOptional[String](s"$prefix.user").getOrElse("application")
- val ssl = config.getOptional[Boolean](s"$prefix.ssl").getOrElse(true)
- val port = config.getOptional[Int](s"$prefix.port").getOrElse(27017)
- val codecRegistry = fromRegistries(
- fromProviders(classOf[Metadata]),
- fromProviders(classOf[FoodNode]),
- fromProviders(classOf[User]),
- fromProviders(classOf[Authorization]),
- fromProviders(classOf[Nutrient]),
- //fromProviders(classOf[UnitType.Value]),
- fromProviders(UnitTypeEnumCodecProvider),
- MongoClient.DEFAULT_CODEC_REGISTRY
- )
- val con = {
- import org.mongodb.scala._
- import org.mongodb.scala.connection.{SslSettings,ClusterSettings}
- import scala.jdk.CollectionConverters._
- implicit val ec: ExecutionContext = ExecutionContext.global
-
- val password = Option(config.get[String](s"$prefix.password"))
- .getOrElse("").toCharArray()
- val credential = MongoCredential.createCredential(user, name, password)
- val db = MongoClient(
- MongoClientSettings.builder()
- .applyToSslSettings((builder: SslSettings.Builder) =>
- builder.enabled(ssl)
- ).applyToClusterSettings((builder: ClusterSettings.Builder) =>
- builder.hosts(List(new ServerAddress(url, port)).asJava)
- ).credential(credential)
- .build()
- ).getDatabase(name)
- .withCodecRegistry(codecRegistry)
- Migration.updateToLatest(db).map(_ => db)
- }
- def apply[T](coll: Collectable[T])(implicit ct: ClassTag[T]) =
- con.map(_.getCollection[T](coll.collectionName))
- def withCollection[T, U](coll: Collectable[U])(fn: (MongoCollection[U] => T))
- (implicit ct: ClassTag[U]) =
- apply(coll).transform({
- case Success(collection) => Success(fn(collection))
- case Failure(e) => Failure(e)
- })
- }
- object UnitTypeEnumCodecProvider extends CodecProvider {
- def isCaseObjectEnum[T](clazz: Class[T]): Boolean =
- clazz.isInstance(UnitType.MASS) ||
- clazz.isInstance(UnitType.VOLUME) ||
- clazz.isInstance(UnitType.NUMBER)
- override def get[T](clazz: Class[T], registry: CodecRegistry): Codec[T] =
- if (isCaseObjectEnum(clazz)) UnitTypeEnumCodec.asInstanceOf[Codec[T]]
- else null
- object UnitTypeEnumCodec extends Codec[UnitType.UnitType] {
- override def decode(
- reader: BsonReader,
- decoderContext: DecoderContext
- ): UnitType.UnitType = UnitType.withName(reader.readString())
- override def encode(
- writer: BsonWriter,
- value: UnitType.UnitType,
- encoderContext: EncoderContext
- ): Unit = writer.writeString(value.name)
- override def getEncoderClass: Class[UnitType.UnitType] =
- UnitType.getClass.asInstanceOf[Class[UnitType.UnitType]]
- }
- }
|