All Downloads are FREE. Search and download functionalities are using the official Maven repository.

im.actor.server.db.DbExtension.scala Maven / Gradle / Ivy

The newest version!
package im.actor.server.db

import akka.actor._
import akka.event.Logging
import com.github.kxbmap.configs.syntax._
import com.typesafe.config.{ Config, ConfigFactory }
import im.actor.server.JNDI
import im.actor.storage.Connector
import im.actor.storage.slick.SlickConnector
import org.flywaydb.core.Flyway
import slick.driver.PostgresDriver.api.Database
import slick.jdbc.hikaricp.HikariCPJdbcDataSource
import slick.jdbc.{ DataSourceJdbcDataSource, JdbcDataSource }

import scala.util.{ Failure, Success, Try }

final class DbExtensionImpl(val db: Database, val connector: Connector) extends Extension with FlywayInit {
  private lazy val flyway: Flyway = {
    val ds = db.source match {
      case s: HikariCPJdbcDataSource   ⇒ s.ds
      case s: DataSourceJdbcDataSource ⇒ s.ds
      case s                           ⇒ throw new IllegalArgumentException(s"Unknown DataSource: ${s.getClass.getName}")
    }
    initFlyway(ds)
  }

  def clean(): Unit = flyway.clean()

  def migrate(): Unit = flyway.migrate()
}

object DbExtension extends ExtensionId[DbExtensionImpl] with ExtensionIdProvider {
  private val JndiPath = "DefaultDatabase"

  private var _system: ActorSystem = null
  def system = _system

  override def lookup = DbExtension

  override def createExtension(system: ExtendedActorSystem): DbExtensionImpl = {
    this._system = system
    val log = Logging(system, getClass)

    val db = initDb(system.settings.config)
    val connector = new SlickConnector(db)(system.dispatcher)

    system.registerOnTermination {
      db.close()
    }

    val ext = new DbExtensionImpl(db, connector)

    Try(ext.migrate()) match {
      case Success(_) ⇒
      case Failure(e) ⇒
        log.error(e, "Migration failed")
        throw e
    }
    ext
  }

  private def initDb(appConfig: Config): Database = {
    val sqlConfig = appConfig.getConfig("services.postgresql")

    val useConfig = for {
      host ← sqlConfig.get[Try[String]]("host")
      port ← sqlConfig.get[Try[Int]]("port")
      db ← sqlConfig.get[Try[String]]("db")
      _ ← sqlConfig.get[Try[String]]("user")
      _ ← sqlConfig.get[Try[String]]("password")
    } yield sqlConfig.withFallback(ConfigFactory.parseString(
      s"""
         |url: "jdbc:postgresql://"${host}":"${port}"/"${db}
      """.stripMargin
    ))

    val db = Database.forConfig("", useConfig.get)
    JNDI.initialContext.rebind(JndiPath, db)
    db
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy