Skip to content

Commit

Permalink
Expose Oracle support in the EE trigger service (#9342)
Browse files Browse the repository at this point in the history
* Expose tho Oracle support in the EE trigger service

This PR builds on the previous PR that did all the actual work on
Oracle support and exposes it in the enterprise edition. This PR only
releases the enterprise edition via the SDK tarball. I’ll add
artifactory publishing separately.

changelog_begin
changelog_end

* Update daml-assistant/daml-sdk/validate.sh

Co-authored-by: Gary Verhaegen <gary.verhaegen@digitalasset.com>

Co-authored-by: Gary Verhaegen <gary.verhaegen@digitalasset.com>
  • Loading branch information
cocreature and garyverhaegen-da authored Apr 8, 2021
1 parent 0303017 commit e84c954
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 19 deletions.
7 changes: 7 additions & 0 deletions daml-assistant/daml-sdk/validate.sh
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,10 @@ done
for cmd in sandbox sandbox-classic; do
$JAVA -jar $SDK_EE $cmd --help | grep -q profile-dir
done

if ! ($JAVA -jar $SDK_EE trigger-service --help | grep -q oracle); then
exit 1
fi
if $JAVA -jar $SDK_CE trigger-service --help | grep -q oracle; then
exit 1
fi
24 changes: 20 additions & 4 deletions triggers/service/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,12 @@ load(
load("@build_environment//:configuration.bzl", "sdk_version")
load("@os_info//:os_info.bzl", "is_windows")

tsvc_main_scalacopts = ["-P:wartremover:traverser:org.wartremover.warts.%s" % wart for wart in [
"NonUnitStatements",
]]
tsvc_main_scalacopts = [
"-P:wartremover:traverser:org.wartremover.warts.%s" % wart
for wart in [
"NonUnitStatements",
]
]

da_scala_library(
name = "trigger-service",
Expand Down Expand Up @@ -83,9 +86,21 @@ da_scala_library(
)

da_scala_binary(
name = "trigger-service-binary",
name = "trigger-service-binary-ce",
main_class = "com.daml.lf.engine.trigger.ServiceMain",
visibility = ["//visibility:public"],
deps = [
":trigger-service",
],
)

da_scala_binary(
name = "trigger-service-binary-ee",
main_class = "com.daml.lf.engine.trigger.ServiceMain",
visibility = ["//visibility:public"],
runtime_deps = [
"@maven//:com_oracle_database_jdbc_ojdbc8",
],
deps = [
":trigger-service",
],
Expand Down Expand Up @@ -180,6 +195,7 @@ scala_test_deps = [
"@maven//:io_spray_spray_json",
"@maven//:org_scalatest_scalatest",
"@maven//:org_scalaz_scalaz_core",
"@maven//:com_github_scopt_scopt",
]

da_scala_test_suite(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,36 +51,51 @@ object JdbcConfig {
implicit val showInstance: Show[JdbcConfig] =
Show.shows(a => s"JdbcConfig(url=${a.url}, user=${a.user})")

def create(x: Map[String, String]): Either[String, JdbcConfig] =
def create(
x: Map[String, String],
supportedJdbcDriverNames: Set[String],
): Either[String, JdbcConfig] =
for {
url <- requiredField(x)("url")
user <- requiredField(x)("user")
password <- requiredField(x)("password")
driver = x.get("driver").getOrElse(defaultDriver)
_ <- Either.cond(
supportedJdbcDriverNames(driver),
(),
s"$driver unsupported. Supported drivers: ${supportedJdbcDriverNames.mkString(", ")}",
)
} yield JdbcConfig(
driver = "org.postgresql.Driver", // TODO make this configurable
driver = driver,
url = url,
user = user,
password = password,
)

private val defaultDriver: String = "org.postgresql.Driver"

private def requiredField(m: Map[String, String])(k: String): Either[String, String] =
m.get(k).filter(_.nonEmpty).toRight(s"Invalid JDBC config, must contain '$k' field")

lazy val usage: String = helpString("<JDBC connection url>", "<user>", "<password>")
lazy val usage: String =
helpString("<JDBC driver class name>", "<JDBC connection url>", "<user>", "<password>")

lazy val help: String =
def help(supportedJdbcDriverNames: Set[String]): String =
"Contains comma-separated key-value pairs. Where:\n" +
s"${indent}url -- JDBC connection URL, beginning with jdbc:postgresql,\n" +
s"${indent}user -- user name for database user with permissions to create tables,\n" +
s"${indent}password -- password of database user,\n" +
s"${indent}driver -- JDBC driver class name, supported drivers: ${supportedJdbcDriverNames
.mkString(", ")}, defaults to org.postgresql.Driver\n" +
s"${indent}Example: " + helpString(
"org.postgresql.Driver",
"jdbc:postgresql://localhost:5432/triggers",
"operator",
"password",
)

private def helpString(url: String, user: String, password: String): String =
s"""\"url=$url,user=$user,password=$password\""""
private def helpString(driver: String, url: String, user: String, password: String): String =
s"""\"driver=$driver,url=$url,user=$user,password=$password\""""

private val indent: String = List.fill(8)(" ").mkString
}
Expand All @@ -106,7 +121,8 @@ private[trigger] object ServiceConfig {
}

@SuppressWarnings(Array("org.wartremover.warts.NonUnitStatements")) // scopt builders
private val parser = new scopt.OptionParser[ServiceConfig]("trigger-service") {
private class OptionParser(supportedJdbcDriverNames: Set[String])
extends scopt.OptionParser[ServiceConfig]("trigger-service") {
head("trigger-service")

opt[String]("dar")
Expand Down Expand Up @@ -212,20 +228,27 @@ private[trigger] object ServiceConfig {

opt[Map[String, String]]("jdbc")
.action((x, c) =>
c.copy(jdbcConfig = Some(JdbcConfig.create(x).fold(e => sys.error(e), identity)))
c.copy(jdbcConfig =
Some(JdbcConfig.create(x, supportedJdbcDriverNames).fold(e => sys.error(e), identity))
)
)
.optional()
.valueName(JdbcConfig.usage)
.text("JDBC configuration parameters. If omitted the service runs without a database.")
.text(JdbcConfig.help(supportedJdbcDriverNames))
.text(
"JDBC configuration parameters. If omitted the service runs without a database. " + JdbcConfig
.help(supportedJdbcDriverNames)
)

cmd("init-db")
.action((_, c) => c.copy(init = true))
.text("Initialize database and terminate.")

help("help").text("Print this usage text")

}

def parse(args: Array[String]): Option[ServiceConfig] =
parser.parse(
def parse(args: Array[String], supportedJdbcDriverNames: Set[String]): Option[ServiceConfig] =
new OptionParser(supportedJdbcDriverNames).parse(
args,
ServiceConfig(
darPaths = Nil,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ object ServiceMain {
}

def main(args: Array[String]): Unit = {
ServiceConfig.parse(args) match {
ServiceConfig.parse(args, DbTriggerDao.supportedJdbcDriverNames) match {
case None => sys.exit(1)
case Some(config) =>
val logger = ContextualizedLogger.get(this.getClass)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,10 @@ object DbTriggerDao {
"oracle.jdbc.OracleDriver" -> ((d, xa) => new DbTriggerDaoOracle(d, xa)),
)

lazy val supportedJdbcDriverNames = supportedJdbcDrivers.keySet filter { d =>
scala.util.Try(Class forName d).isSuccess
}

def apply(c: JdbcConfig, poolSize: PoolSize = Production)(implicit
ec: ExecutionContext
): DbTriggerDao = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,26 @@ class ServiceConfigTest extends AnyWordSpec with Matchers with OptionValues {
val baseOpts = Array("--ledger-host", "localhost", "--ledger-port", "9999")

"read address" in {
parse(baseOpts).value.address should ===(defaultAddress)
parse(baseOpts ++ Seq("--address", "0.0.0.0")).value.address should ===("0.0.0.0")
parse(baseOpts, Set()).value.address should ===(defaultAddress)
parse(baseOpts ++ Seq("--address", "0.0.0.0"), Set()).value.address should ===("0.0.0.0")
}
"default to postgresql jdbc driver" in {
parse(
baseOpts ++ Seq("--jdbc", "url=url,user=user,password=password"),
Set("org.postgresql.Driver"),
).value.jdbcConfig.value.driver should ===("org.postgresql.Driver")
}
"support a custom jdbc driver" in {
parse(
baseOpts ++ Seq("--jdbc", "driver=custom,url=url,user=user,password=password"),
Set("custom"),
).value.jdbcConfig.value.driver should ===("custom")
}
"fails for unsupported jdbc driver" in {
parse(
baseOpts ++ Seq("--jdbc", "driver=custom,url=url,user=user,password=password"),
Set("notcustom"),
) should ===(None)
}
}
}

0 comments on commit e84c954

Please sign in to comment.