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

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

There is a newer version: 3.0.0
Show newest version
package im.actor.server.db

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

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

trait DbExtension extends Extension {
  val ds: JdbcDataSource
  val db: Database
}

final class DbExtensionImpl(val ds: HikariCPJdbcDataSource, val db: Database) extends Extension with FlywayInit {
  private lazy val flyway: Flyway = initFlyway(ds.ds)

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

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

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

  override def lookup = DbExtension

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

    val sqlConfig = system.settings.config.getConfig("services.postgresql")
    val queueSize = sqlConfig.getInt("queueSize")
    val ds = initDs(sqlConfig).get
    val db = initDb(ds, queueSize)

    system.registerOnTermination {
      db.close()
    }

    val ext = new DbExtensionImpl(ds, db)

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

  private def initDs(sqlConfig: Config): Try[HikariCPJdbcDataSource] = {
    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 HikariCPJdbcDataSource.forConfig(sqlConfig.withFallback(ConfigFactory.parseString(
      s"""
        |url: "jdbc:postgresql://"${host}":"${port}"/"${db}
      """.stripMargin
    )).resolve(), null, "main", getClass.getClassLoader)
  }

  private def initDb(ds: HikariCPJdbcDataSource, queueSize: Int): Database = {
    JNDI.initialContext.rebind(JndiPath, ds.ds)
    Database.forSource(ds, executor = AsyncExecutor("AsyncExecutor.actor", 20, queueSize))
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy