Expose Oracle support in the EE trigger service (#9342)

* 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>
This commit is contained in:
Moritz Kiefer 2021-04-08 14:50:47 +02:00 committed by GitHub
parent 0303017343
commit e84c954973
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 87 additions and 19 deletions

View File

@ -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

View File

@ -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",
@ -83,7 +86,7 @@ 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 = [
@ -91,6 +94,18 @@ da_scala_binary(
],
)
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",
],
)
da_scala_library(
name = "trigger-service-tests",
srcs = glob(["src/test/scala/com/digitalasset/daml/lf/engine/trigger/*.scala"]),
@ -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(

View File

@ -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
}
@ -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")
@ -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,

View File

@ -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)

View File

@ -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 = {

View File

@ -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)
}
}
}