Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expose Oracle support in the EE trigger service #9342

Merged
merged 2 commits into from
Apr 8, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
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
  • Loading branch information
cocreature committed Apr 7, 2021
commit 4519d667364edf8a64fb4589937bc8094a2cc15c
5 changes: 5 additions & 0 deletions daml-assistant/daml-sdk/validate.sh
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,8 @@ done
for cmd in sandbox sandbox-classic; do
$JAVA -jar $SDK_EE $cmd --help | grep -q profile-dir
done

$JAVA -jar $SDK_EE trigger-service --help | grep -q oracle
cocreature marked this conversation as resolved.
Show resolved Hide resolved
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)
}
}
}