Skip to content

Commit

Permalink
add oracle option for json-api perf runner (#9492)
Browse files Browse the repository at this point in the history
* add oracle option to http-json-perf-binary-ee

* add oracle path to perf Main's JDBC bracket

* adapt to availableJdbcDriverNames; missing deps

* add changelog

CHANGELOG_BEGIN
- [JSON-API Perf] ``--query-store-index=postgres`` must be passed
  to select PostgreSQL query store performance testing; ``true``
  and ``yes`` are no longer supported.
  See `issue #9492 <https://github.com/digital-asset/daml/pull/9492>`__.
CHANGELOG_END
  • Loading branch information
S11001001 authored Apr 27, 2021
1 parent 8cd3658 commit 4e712a0
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 18 deletions.
11 changes: 10 additions & 1 deletion ledger-service/http-json-perf/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,13 @@ scalacopts = lf_scalacopts + [
"-P:wartremover:traverser:org.wartremover.warts.NonUnitStatements",
]

perf_runtime_deps = {
"ce": [],
"ee": [
"@maven//:com_oracle_database_jdbc_ojdbc8",
],
}

[
da_scala_library(
name = "http-json-perf-{}".format(edition),
Expand Down Expand Up @@ -45,9 +52,11 @@ scalacopts = lf_scalacopts + [
"//ledger-service/http-json-testing:{}".format(edition),
"//ledger-service/jwt",
"//libs-scala/gatling-utils",
"//libs-scala/oracle-testing",
"//libs-scala/ports",
"//libs-scala/postgresql-testing",
"//libs-scala/scala-utils",
"//runtime-components/jdbc-drivers:jdbc-drivers-{}".format(edition),
"@maven//:com_fasterxml_jackson_core_jackson_core",
"@maven//:com_fasterxml_jackson_core_jackson_databind",
"@maven//:io_gatling_gatling_app",
Expand Down Expand Up @@ -92,7 +101,7 @@ scalacopts = lf_scalacopts + [
visibility = ["//visibility:public"],
runtime_deps = [
"@maven//:ch_qos_logback_logback_classic",
],
] + perf_runtime_deps.get(edition),
deps = [
":http-json-perf-{}".format(edition),
"//language-support/scala/bindings-akka",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ import com.daml.jwt.domain.Jwt
import scalaz.{Applicative, Traverse}
import scopt.RenderingMode

import Config.QueryStoreIndex
import com.daml.http.dbbackend.ContractDao.supportedJdbcDriverNames
import com.daml.runtime.JdbcDrivers.availableJdbcDriverNames

import scala.concurrent.duration.{Duration, FiniteDuration}

private[perf] final case class Config[+S](
Expand All @@ -18,7 +22,7 @@ private[perf] final case class Config[+S](
jwt: Jwt,
reportsDir: File,
maxDuration: Option[FiniteDuration],
queryStoreIndex: Boolean,
queryStoreIndex: QueryStoreIndex,
) {
override def toString: String =
s"Config(" +
Expand All @@ -27,7 +31,7 @@ private[perf] final case class Config[+S](
s", jwt=..." + // don't print the JWT
s", reportsDir=${reportsDir: File}" +
s", maxDuration=${this.maxDuration: Option[FiniteDuration]}" +
s", queryStoreIndex=${this.queryStoreIndex: Boolean}" +
s", queryStoreIndex=${this.queryStoreIndex: QueryStoreIndex}" +
")"
}

Expand All @@ -39,15 +43,15 @@ private[perf] object Config {
jwt = Jwt(""),
reportsDir = new File(""),
maxDuration = None,
queryStoreIndex = false,
queryStoreIndex = QueryStoreIndex.No,
)

implicit val configInstance: Traverse[Config] = new Traverse[Config] {
override def traverseImpl[G[_]: Applicative, A, B](
fa: Config[A]
)(f: A => G[B]): G[Config[B]] = {
import scalaz.syntax.functor._
f(fa.scenario).map(b => Empty.copy(scenario = b))
f(fa.scenario).map(b => fa.copy(scenario = b))
}
}

Expand Down Expand Up @@ -79,10 +83,12 @@ private[perf] object Config {
.validate(validateJwt)
.text("JWT token to use when connecting to JSON API.")

opt[Boolean]("query-store-index")
opt[QueryStoreIndex]("query-store-index")
.action((x, c) => c.copy(queryStoreIndex = x))
.optional()
.text("Enables JSON API query store index. Default is false, disabled.")
.text(
s"Enables JSON API query store index ${QueryStoreIndex.allowedHelp}. Default is no, disabled."
)

opt[File]("reports-dir")
.action((x, c) => c.copy(reportsDir = x))
Expand All @@ -108,4 +114,28 @@ private[perf] object Config {
)
.toEither
}

sealed abstract class QueryStoreIndex extends Product with Serializable
object QueryStoreIndex {
case object No extends QueryStoreIndex
case object Postgres extends QueryStoreIndex
case object Oracle extends QueryStoreIndex

val names: Map[String, QueryStoreIndex] = Map("no" -> No, "postgres" -> Postgres) ++ (
if (supportedJdbcDriverNames(availableJdbcDriverNames)("oracle.jdbc.OracleDriver"))
Seq("oracle" -> Oracle)
else Seq.empty
)

private[Config] val allowedHelp = names.keys.mkString("{", ", ", "}")

implicit val scoptRead: scopt.Read[QueryStoreIndex] = scopt.Read.reads { s =>
names.getOrElse(
s.toLowerCase(java.util.Locale.ROOT),
throw new IllegalArgumentException(
s"$s is not a query store index; only $allowedHelp allowed"
),
)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,11 @@ import scalaz.std.string._
import scalaz.syntax.tag._
import scalaz.{-\/, EitherT, \/, \/-}

import Config.QueryStoreIndex

import scala.concurrent.duration.{Duration, _}
import scala.concurrent.{Await, ExecutionContext, Future, TimeoutException}
import scala.util.{Failure, Success}
import scala.util.{Failure, Success, Try}

object Main extends StrictLogging {

Expand Down Expand Up @@ -137,25 +139,70 @@ object Main extends StrictLogging {
}
}

private def withJsonApiJdbcConfig[A](jsonApiQueryStoreEnabled: Boolean)(
private def withJsonApiJdbcConfig[A](jsonApiQueryStoreEnabled: QueryStoreIndex)(
fn: Option[JdbcConfig] => Future[A]
)(implicit
ec: ExecutionContext
): Future[A] =
if (jsonApiQueryStoreEnabled) {
): Future[A] = QueryStoreBracket lookup jsonApiQueryStoreEnabled match {
case Some(b: QueryStoreBracket[s, d]) =>
import b._
for {
dbInstance <- Future.successful(new PostgresRunner())
dbConfig <- toFuture(dbInstance.start())
jsonApiDbConfig <- Future.successful(jsonApiJdbcConfig(dbConfig))
dbInstance <- Future.successful(state())
dbConfig <- toFuture(start(dbInstance))
jsonApiDbConfig <- Future.successful(config(dbInstance, dbConfig))
a <- fn(Some(jsonApiDbConfig))
_ <- Future.successful(
dbInstance.stop()
stop(dbInstance, dbConfig) // XXX ignores resulting Try
) // TODO: use something like `lf.data.TryOps.Bracket.bracket`
} yield a
} else {
fn(None)

case None => fn(None)
}

private[this] final case class QueryStoreBracket[S, D](
state: () => S,
start: S => Try[D],
config: (S, D) => JdbcConfig,
stop: (S, D) => Try[Unit],
)
private[this] object QueryStoreBracket {
type T = QueryStoreBracket[_, _]
val Postgres: T = QueryStoreBracket[PostgresRunner, PostgresDatabase](
() => new PostgresRunner(),
_.start(),
(_, d) => jsonApiJdbcConfig(d),
(r, _) => r.stop(),
)

import com.daml.testing.oracle, oracle.OracleAround
val Oracle: T = QueryStoreBracket[OracleRunner, oracle.User](
() => new OracleRunner,
_.start(),
_ jdbcConfig _,
_.stop(_),
)

private[this] final class OracleRunner extends OracleAround {
type St = oracle.User

def start() = Try {
connectToOracle()
createNewRandomUser(): St
}

def jdbcConfig(user: St) =
JdbcConfig("oracle.jdbc.OracleDriver", oracleJdbcUrl, user.name, user.pwd)

def stop(user: St) = Try(dropUser(user.name))
}

def lookup(q: QueryStoreIndex): Option[T] = q match {
case QueryStoreIndex.No => None
case QueryStoreIndex.Postgres => Some(Postgres)
case QueryStoreIndex.Oracle => Some(Oracle)
}
}

private def jsonApiJdbcConfig(c: PostgresDatabase): JdbcConfig =
JdbcConfig(
driver = "org.postgresql.Driver",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import com.daml.ports._
import java.sql._
import scala.util.{Random, Using}

private[oracle] final case class User(name: String, pwd: String)
private[daml] final case class User(name: String, pwd: String)

trait OracleAround {
@volatile
Expand Down

0 comments on commit 4e712a0

Please sign in to comment.