Skip to content

Commit

Permalink
Merge branch 'develop' into ID-804-new-tos-config-endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
Ghost-in-a-Jar authored Oct 30, 2023
2 parents e4d05b1 + 68d1a53 commit ccfe95b
Show file tree
Hide file tree
Showing 6 changed files with 39 additions and 8 deletions.
13 changes: 12 additions & 1 deletion src/main/resources/sam.conf
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ db {
poolMaxSize = 8
poolConnectionTimeoutMillis = 5000
driver = "org.postgresql.Driver"
url = ${?POSTGRES_READ_URL}
url = ${?POSTGRES_WRITE_URL}
user = ${?POSTGRES_USERNAME}
password = ${?POSTGRES_PASSWORD}
}
Expand Down Expand Up @@ -162,6 +162,17 @@ db {
user = ${?POSTGRES_USERNAME}
password = ${?POSTGRES_PASSWORD}
}

sam_read_replica {
poolName = "sam_read_replica"
poolInitialSize = 8
poolMaxSize = 8
poolConnectionTimeoutMillis = 5000
driver = "org.postgresql.Driver"
url = ${?POSTGRES_READ_URL}
user = ${?POSTGRES_USERNAME}
password = ${?POSTGRES_PASSWORD}
}
}

admin {
Expand Down
10 changes: 7 additions & 3 deletions src/main/scala/org/broadinstitute/dsde/workbench/sam/Boot.scala
Original file line number Diff line number Diff line change
Expand Up @@ -109,14 +109,16 @@ object Boot extends IOApp with LazyLogging {
(foregroundDirectoryDAO, foregroundAccessPolicyDAO, postgresDistributedLockDAO, azureManagedResourceGroupDAO, lastQuotaErrorDAO) <- createDAOs(
appConfig,
appConfig.samDatabaseConfig.samWrite,
appConfig.samDatabaseConfig.samRead
appConfig.samDatabaseConfig.samRead,
appConfig.samDatabaseConfig.samReadReplica
)

// This special set of objects are for operations that happen in the background, i.e. not in the immediate service
// of an api call (foreground). They are meant to partition resources so that background processes can't crowd our api calls.
(backgroundDirectoryDAO, backgroundAccessPolicyDAO, _, _, _) <- createDAOs(
appConfig,
appConfig.samDatabaseConfig.samBackground,
appConfig.samDatabaseConfig.samBackground,
appConfig.samDatabaseConfig.samBackground
)

Expand Down Expand Up @@ -201,14 +203,16 @@ object Boot extends IOApp with LazyLogging {
private def createDAOs(
appConfig: AppConfig,
writeDbConfig: DatabaseConfig,
readDbConfig: DatabaseConfig
readDbConfig: DatabaseConfig,
readReplicaDbConfig: DatabaseConfig
): cats.effect.Resource[IO, (PostgresDirectoryDAO, AccessPolicyDAO, PostgresDistributedLockDAO[IO], AzureManagedResourceGroupDAO, LastQuotaErrorDAO)] =
for {
writeDbRef <- DbReference.resource(appConfig.liquibaseConfig, writeDbConfig)
readDbRef <- DbReference.resource(appConfig.liquibaseConfig.copy(initWithLiquibase = false), readDbConfig)
readReplicaDbRef <- DbReference.resource(appConfig.liquibaseConfig.copy(initWithLiquibase = false), readReplicaDbConfig)

directoryDAO = new PostgresDirectoryDAO(writeDbRef, readDbRef)
accessPolicyDAO = new PostgresAccessPolicyDAO(writeDbRef, readDbRef)
accessPolicyDAO = new PostgresAccessPolicyDAO(writeDbRef, readDbRef, Some(readReplicaDbRef))
postgresDistributedLockDAO = new PostgresDistributedLockDAO[IO](writeDbRef, readDbRef, appConfig.distributedLockConfig)
azureManagedResourceGroupDAO = new PostgresAzureManagedResourceGroupDAO(writeDbRef, readDbRef)
lastQuotaErrorDAO = new PostgresLastQuotaErrorDAO(writeDbRef, readDbRef)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,12 @@ object AppConfig {
}

implicit val samDatabaseConfigReader: ValueReader[SamDatabaseConfig] = ValueReader.relative { config =>
SamDatabaseConfig(config.as[DatabaseConfig]("sam_read"), config.as[DatabaseConfig]("sam_write"), config.as[DatabaseConfig]("sam_background"))
SamDatabaseConfig(
config.as[DatabaseConfig]("sam_read"),
config.as[DatabaseConfig]("sam_write"),
config.as[DatabaseConfig]("sam_background"),
config.as[DatabaseConfig]("sam_read_replica")
)
}

final case class AdminConfig(superAdminsGroup: WorkbenchEmail, allowedEmailDomains: Set[String], serviceAccountAdmins: Set[WorkbenchEmail])
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package org.broadinstitute.dsde.workbench.sam.config

final case class SamDatabaseConfig(samRead: DatabaseConfig, samWrite: DatabaseConfig, samBackground: DatabaseConfig)
final case class SamDatabaseConfig(samRead: DatabaseConfig, samWrite: DatabaseConfig, samBackground: DatabaseConfig, samReadReplica: DatabaseConfig)

final case class DatabaseConfig(
dbName: Symbol,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,11 @@ import scala.collection.concurrent.TrieMap
import scala.util.{Failure, Try}
import cats.effect.Temporal

class PostgresAccessPolicyDAO(protected val writeDbRef: DbReference, protected val readDbRef: DbReference)(implicit timer: Temporal[IO])
class PostgresAccessPolicyDAO(
protected val writeDbRef: DbReference,
protected val readDbRef: DbReference,
protected override val readReplicaDbRef: Option[DbReference] = None
)(implicit timer: Temporal[IO])
extends AccessPolicyDAO
with DatabaseSupport
with PostgresGroupDAO
Expand Down Expand Up @@ -1353,7 +1357,7 @@ class PostgresAccessPolicyDAO(protected val writeDbRef: DbReference, protected v
userId: WorkbenchUserId,
samRequestContext: SamRequestContext
): IO[Iterable[ResourceIdWithRolesAndActions]] =
readOnlyTransaction("listUserResourcesWithRolesAndActions", samRequestContext) { implicit session =>
readOnlyTransactionReadReplica("listUserResourcesWithRolesAndActions", samRequestContext) { implicit session =>
class ListUserResourcesQuery extends UserResourcesQuery(resourceTypeName, None, userId) {
val policyRole = EffectivePolicyRoleTable.syntax("policyRole")
val resourceRole = ResourceRoleTable.syntax("resourceRole")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,19 @@ import cats.effect.Temporal
trait DatabaseSupport {
protected val writeDbRef: DbReference
protected val readDbRef: DbReference
protected val readReplicaDbRef: Option[DbReference] = None

protected def readOnlyTransaction[A](dbQueryName: String, samRequestContext: SamRequestContext)(databaseFunction: DBSession => A): IO[A] = {
val databaseIO = IO(readDbRef.readOnly(databaseFunction))
readDbRef.runDatabaseIO(dbQueryName, samRequestContext, databaseIO)
}

protected def readOnlyTransactionReadReplica[A](dbQueryName: String, samRequestContext: SamRequestContext)(databaseFunction: DBSession => A): IO[A] = {
val dbRef = readReplicaDbRef.getOrElse(readDbRef)
val databaseIO = IO(dbRef.readOnly(databaseFunction))
readDbRef.runDatabaseIO(dbQueryName, samRequestContext, databaseIO)
}

/** Run a database transaction with isolation level set to serializable. See https://www.postgresql.org/docs/9.6/transaction-iso.html. Use this when you need
* to be sure there are no concurrent changes that affect the outcome of databaseFunction. When a transaction fails due to a serialization failure it may be
* retried.
Expand Down

0 comments on commit ccfe95b

Please sign in to comment.