mirror of
https://github.com/digital-asset/daml.git
synced 2024-09-20 01:07:18 +03:00
Port //triggers/... to Scala 2.13 (#8781)
changelog_begin changelog_end
This commit is contained in:
parent
d4e0d8b8be
commit
40e1a39f2c
@ -182,6 +182,7 @@ jobs:
|
||||
//ledger-api/... \
|
||||
//ledger/... \
|
||||
//ledger-service/... \
|
||||
//triggers/... \
|
||||
-//ledger-service/http-json/... \
|
||||
-//ledger-service/http-json-perf/... \
|
||||
-//ledger-service/http-json-testing/... \
|
||||
@ -199,6 +200,7 @@ jobs:
|
||||
//ledger/... \
|
||||
//ledger-service/... \
|
||||
//daml-script/dump/... \
|
||||
//triggers/... \
|
||||
-//libs-scala/gatling-utils/... \
|
||||
-//language-support/scala/examples/... \
|
||||
-//language-support/scala/codegen-sample-app/... \
|
||||
|
@ -14,6 +14,13 @@ tsvc_main_scalacopts = ["-P:wartremover:traverser:org.wartremover.warts.%s" % wa
|
||||
da_scala_library(
|
||||
name = "trigger-runner-lib",
|
||||
srcs = glob(["src/main/scala/**/*.scala"]),
|
||||
scala_deps = [
|
||||
"@maven//:com_github_scopt_scopt",
|
||||
"@maven//:com_typesafe_akka_akka_stream",
|
||||
"@maven//:org_scala_lang_modules_scala_collection_compat",
|
||||
"@maven//:org_scalaz_scalaz_core",
|
||||
"@maven//:org_typelevel_paiges_core",
|
||||
],
|
||||
scalacopts = tsvc_main_scalacopts,
|
||||
tags = ["maven_coordinates=com.daml:trigger-runner:__VERSION__"],
|
||||
visibility = ["//visibility:public"],
|
||||
@ -34,11 +41,6 @@ da_scala_library(
|
||||
"//libs-scala/auth-utils",
|
||||
"//libs-scala/contextualized-logging",
|
||||
"//libs-scala/scala-utils",
|
||||
"@maven//:com_github_scopt_scopt_2_12",
|
||||
"@maven//:com_typesafe_akka_akka_stream_2_12",
|
||||
"@maven//:org_scala_lang_modules_scala_collection_compat_2_12",
|
||||
"@maven//:org_scalaz_scalaz_core_2_12",
|
||||
"@maven//:org_typelevel_paiges_core_2_12",
|
||||
],
|
||||
)
|
||||
|
||||
|
@ -310,37 +310,55 @@ object Converter {
|
||||
}
|
||||
|
||||
private def toFiniteDuration(value: SValue): Either[String, FiniteDuration] =
|
||||
value expect ("RelTime", { case SRecord(_, _, JavaList(SInt64(microseconds))) =>
|
||||
FiniteDuration(microseconds, MICROSECONDS)
|
||||
})
|
||||
value.expect(
|
||||
"RelTime",
|
||||
{ case SRecord(_, _, JavaList(SInt64(microseconds))) =>
|
||||
FiniteDuration(microseconds, MICROSECONDS)
|
||||
},
|
||||
)
|
||||
|
||||
private def toIdentifier(v: SValue): Either[String, Identifier] =
|
||||
v expect ("STypeRep", { case STypeRep(TTyCon(id)) =>
|
||||
id
|
||||
})
|
||||
v.expect(
|
||||
"STypeRep",
|
||||
{ case STypeRep(TTyCon(id)) =>
|
||||
id
|
||||
},
|
||||
)
|
||||
|
||||
private def toTemplateTypeRep(v: SValue): Either[String, Identifier] =
|
||||
v expectE ("TemplateTypeRep", { case SRecord(_, _, JavaList(id)) =>
|
||||
toIdentifier(id)
|
||||
})
|
||||
v.expectE(
|
||||
"TemplateTypeRep",
|
||||
{ case SRecord(_, _, JavaList(id)) =>
|
||||
toIdentifier(id)
|
||||
},
|
||||
)
|
||||
|
||||
private def toRegisteredTemplate(v: SValue): Either[String, Identifier] =
|
||||
v expectE ("RegisteredTemplate", { case SRecord(_, _, JavaList(sttr)) =>
|
||||
toTemplateTypeRep(sttr)
|
||||
})
|
||||
v.expectE(
|
||||
"RegisteredTemplate",
|
||||
{ case SRecord(_, _, JavaList(sttr)) =>
|
||||
toTemplateTypeRep(sttr)
|
||||
},
|
||||
)
|
||||
|
||||
private def toRegisteredTemplates(v: SValue): Either[String, Seq[Identifier]] =
|
||||
v expectE ("list of RegisteredTemplate", { case SList(tpls) =>
|
||||
tpls.traverse(toRegisteredTemplate).map(_.toImmArray.toSeq)
|
||||
})
|
||||
v.expectE(
|
||||
"list of RegisteredTemplate",
|
||||
{ case SList(tpls) =>
|
||||
tpls.traverse(toRegisteredTemplate).map(_.toImmArray.toSeq)
|
||||
},
|
||||
)
|
||||
|
||||
private def toAnyContractId(v: SValue): Either[String, AnyContractId] =
|
||||
v expectE ("AnyContractId", { case SRecord(_, _, JavaList(stid, scid)) =>
|
||||
for {
|
||||
templateId <- toTemplateTypeRep(stid)
|
||||
contractId <- toContractId(scid)
|
||||
} yield AnyContractId(templateId, contractId)
|
||||
})
|
||||
v.expectE(
|
||||
"AnyContractId",
|
||||
{ case SRecord(_, _, JavaList(stid, scid)) =>
|
||||
for {
|
||||
templateId <- toTemplateTypeRep(stid)
|
||||
contractId <- toContractId(scid)
|
||||
} yield AnyContractId(templateId, contractId)
|
||||
},
|
||||
)
|
||||
|
||||
private[this] def toAnyTemplate(v: SValue): Either[String, AnyTemplate] = {
|
||||
v match {
|
||||
@ -361,35 +379,45 @@ object Converter {
|
||||
}
|
||||
|
||||
private def toAnyContractKey(v: SValue): Either[String, AnyContractKey] =
|
||||
v expect ("AnyContractKey", { case SRecord(_, _, JavaList(SAny(_, v), _)) =>
|
||||
AnyContractKey(v)
|
||||
})
|
||||
v.expect(
|
||||
"AnyContractKey",
|
||||
{ case SRecord(_, _, JavaList(SAny(_, v), _)) =>
|
||||
AnyContractKey(v)
|
||||
},
|
||||
)
|
||||
|
||||
private[this] def toCreate(v: SValue): Either[String, CreateCommand] =
|
||||
v expectE ("CreateCommand", { case SRecord(_, _, JavaList(sTpl)) =>
|
||||
for {
|
||||
anyTmpl <- toAnyTemplate(sTpl)
|
||||
templateArg <- toLedgerRecord(anyTmpl.arg)
|
||||
} yield CreateCommand(Some(toApiIdentifier(anyTmpl.ty)), Some(templateArg))
|
||||
})
|
||||
v.expectE(
|
||||
"CreateCommand",
|
||||
{ case SRecord(_, _, JavaList(sTpl)) =>
|
||||
for {
|
||||
anyTmpl <- toAnyTemplate(sTpl)
|
||||
templateArg <- toLedgerRecord(anyTmpl.arg)
|
||||
} yield CreateCommand(Some(toApiIdentifier(anyTmpl.ty)), Some(templateArg))
|
||||
},
|
||||
)
|
||||
|
||||
private[this] def toExercise(v: SValue): Either[String, ExerciseCommand] =
|
||||
v expectE ("ExerciseCommand", { case SRecord(_, _, JavaList(sAnyContractId, sChoiceVal)) =>
|
||||
for {
|
||||
anyContractId <- toAnyContractId(sAnyContractId)
|
||||
anyChoice <- toAnyChoice(sChoiceVal)
|
||||
choiceArg <- toLedgerValue(anyChoice.arg)
|
||||
} yield ExerciseCommand(
|
||||
Some(toApiIdentifier(anyContractId.templateId)),
|
||||
anyContractId.contractId.coid,
|
||||
anyChoice.name,
|
||||
Some(choiceArg),
|
||||
)
|
||||
})
|
||||
v.expectE(
|
||||
"ExerciseCommand",
|
||||
{ case SRecord(_, _, JavaList(sAnyContractId, sChoiceVal)) =>
|
||||
for {
|
||||
anyContractId <- toAnyContractId(sAnyContractId)
|
||||
anyChoice <- toAnyChoice(sChoiceVal)
|
||||
choiceArg <- toLedgerValue(anyChoice.arg)
|
||||
} yield ExerciseCommand(
|
||||
Some(toApiIdentifier(anyContractId.templateId)),
|
||||
anyContractId.contractId.coid,
|
||||
anyChoice.name,
|
||||
Some(choiceArg),
|
||||
)
|
||||
},
|
||||
)
|
||||
|
||||
private[this] def toExerciseByKey(v: SValue): Either[String, ExerciseByKeyCommand] =
|
||||
v expectE ("ExerciseByKeyCommand", {
|
||||
case SRecord(_, _, JavaList(stplId, skeyVal, sChoiceVal)) =>
|
||||
v.expectE(
|
||||
"ExerciseByKeyCommand",
|
||||
{ case SRecord(_, _, JavaList(stplId, skeyVal, sChoiceVal)) =>
|
||||
for {
|
||||
tplId <- toTemplateTypeRep(stplId)
|
||||
keyVal <- toAnyContractKey(skeyVal)
|
||||
@ -402,22 +430,26 @@ object Converter {
|
||||
anyChoice.name,
|
||||
Some(choiceArg),
|
||||
)
|
||||
})
|
||||
},
|
||||
)
|
||||
|
||||
private[this] def toCreateAndExercise(v: SValue): Either[String, CreateAndExerciseCommand] =
|
||||
v expectE ("CreateAndExerciseCommand", { case SRecord(_, _, JavaList(sTpl, sChoiceVal)) =>
|
||||
for {
|
||||
anyTmpl <- toAnyTemplate(sTpl)
|
||||
templateArg <- toLedgerRecord(anyTmpl.arg)
|
||||
anyChoice <- toAnyChoice(sChoiceVal)
|
||||
choiceArg <- toLedgerValue(anyChoice.arg)
|
||||
} yield CreateAndExerciseCommand(
|
||||
Some(toApiIdentifier(anyTmpl.ty)),
|
||||
Some(templateArg),
|
||||
anyChoice.name,
|
||||
Some(choiceArg),
|
||||
)
|
||||
})
|
||||
v.expectE(
|
||||
"CreateAndExerciseCommand",
|
||||
{ case SRecord(_, _, JavaList(sTpl, sChoiceVal)) =>
|
||||
for {
|
||||
anyTmpl <- toAnyTemplate(sTpl)
|
||||
templateArg <- toLedgerRecord(anyTmpl.arg)
|
||||
anyChoice <- toAnyChoice(sChoiceVal)
|
||||
choiceArg <- toLedgerValue(anyChoice.arg)
|
||||
} yield CreateAndExerciseCommand(
|
||||
Some(toApiIdentifier(anyTmpl.ty)),
|
||||
Some(templateArg),
|
||||
anyChoice.name,
|
||||
Some(choiceArg),
|
||||
)
|
||||
},
|
||||
)
|
||||
|
||||
private def toCommand(v: SValue): Either[String, Command] = {
|
||||
v match {
|
||||
@ -443,9 +475,12 @@ object Converter {
|
||||
|
||||
private def toCommands(v: SValue): Either[String, Seq[Command]] =
|
||||
for {
|
||||
cmdValues <- v expect ("[Command]", { case SList(cmdValues) =>
|
||||
cmdValues
|
||||
})
|
||||
cmdValues <- v.expect(
|
||||
"[Command]",
|
||||
{ case SList(cmdValues) =>
|
||||
cmdValues
|
||||
},
|
||||
)
|
||||
commands <- cmdValues.traverse(toCommand)
|
||||
} yield commands.toImmArray.toSeq
|
||||
|
||||
|
@ -21,8 +21,6 @@ import scalaz.syntax.tag._
|
||||
import scalaz.syntax.std.boolean._
|
||||
import scalaz.syntax.std.option._
|
||||
|
||||
import scala.language.higherKinds
|
||||
|
||||
import scala.annotation.tailrec
|
||||
import scala.concurrent.{ExecutionContext, Future}
|
||||
import scala.concurrent.duration.FiniteDuration
|
||||
@ -653,12 +651,16 @@ object Runner extends StrictLogging {
|
||||
def trial(tries: Int, value: A): Future[B] =
|
||||
if (tries <= 1) notRetryable(value)
|
||||
else
|
||||
retryable(value).flatMap(_ cata (Future.successful, {
|
||||
Future {
|
||||
try Thread.sleep(backoff(initialTries - tries + 1).toMillis)
|
||||
catch { case _: InterruptedException => }
|
||||
}.flatMap(_ => trial(tries - 1, value))
|
||||
}))
|
||||
retryable(value).flatMap(
|
||||
_.cata(
|
||||
Future.successful, {
|
||||
Future {
|
||||
try Thread.sleep(backoff(initialTries - tries + 1).toMillis)
|
||||
catch { case _: InterruptedException => }
|
||||
}.flatMap(_ => trial(tries - 1, value))
|
||||
},
|
||||
)
|
||||
)
|
||||
Flow[A].mapAsync(parallelism)(trial(initialTries, _))
|
||||
}
|
||||
|
||||
@ -668,7 +670,7 @@ object Runner extends StrictLogging {
|
||||
val ov = m get k
|
||||
f(ov) map {
|
||||
(ov, _) match {
|
||||
case (_, Some(v)) => m updated (k, v)
|
||||
case (_, Some(v)) => m.updated(k, v)
|
||||
case (None, None) => m
|
||||
case (Some(_), None) => m - k
|
||||
}
|
||||
@ -704,7 +706,10 @@ object Runner extends StrictLogging {
|
||||
party: String,
|
||||
)(implicit materializer: Materializer, executionContext: ExecutionContext): Future[SValue] = {
|
||||
val darMap = dar.all.toMap
|
||||
val compiledPackages = PureCompiledPackages(darMap).right.get
|
||||
val compiledPackages = PureCompiledPackages(darMap) match {
|
||||
case Left(err) => throw new RuntimeException(s"Failed to compile packages: $err")
|
||||
case Right(pkgs) => pkgs
|
||||
}
|
||||
val trigger = Trigger.fromIdentifier(compiledPackages, triggerId) match {
|
||||
case Left(err) => throw new RuntimeException(s"Invalid trigger: $err")
|
||||
case Right(trigger) => trigger
|
||||
|
@ -16,7 +16,6 @@ import scala.annotation.tailrec
|
||||
import com.daml.scalautil.Statement.discard
|
||||
|
||||
import scala.collection.compat._
|
||||
import scala.collection.generic.CanBuildFrom
|
||||
import scala.collection.immutable.{IndexedSeq, Iterable, LinearSeq}
|
||||
|
||||
/** A variant of [[scalaz.CorecursiveList]] that emits a final state
|
||||
@ -42,7 +41,7 @@ private[trigger] sealed abstract class UnfoldState[+T, +A] {
|
||||
private[trigger] final def iterator(): Iterator[T \/ A] =
|
||||
new Iterator[T \/ A] {
|
||||
var last = some(step(init))
|
||||
override def hasNext() = last.isDefined
|
||||
override def hasNext = last.isDefined
|
||||
override def next() = last match {
|
||||
case Some(\/-((a, s))) =>
|
||||
last = Some(step(s))
|
||||
@ -55,8 +54,8 @@ private[trigger] sealed abstract class UnfoldState[+T, +A] {
|
||||
}
|
||||
}
|
||||
|
||||
final def runTo[FA](implicit cbf: CanBuildFrom[Nothing, A, FA]): (FA, T) = {
|
||||
val b = cbf()
|
||||
final def runTo[FA](implicit factory: Factory[A, FA]): (FA, T) = {
|
||||
val b = factory.newBuilder
|
||||
val t = foreach(a => discard(b += a))
|
||||
(b.result(), t)
|
||||
}
|
||||
@ -76,7 +75,7 @@ private[trigger] object UnfoldState {
|
||||
|
||||
implicit def `US bifunctor instance`: Bifunctor[UnfoldState] = new Bifunctor[UnfoldState] {
|
||||
override def bimap[A, B, C, D](fab: UnfoldState[A, B])(f: A => C, g: B => D) =
|
||||
UnfoldState(fab.init)(fab.step andThen (_ bimap (f, (_ leftMap g))))
|
||||
UnfoldState(fab.init)(fab.step andThen (_.bimap(f, (_ leftMap g))))
|
||||
}
|
||||
|
||||
def fromLinearSeq[A](list: LinearSeq[A]): UnfoldState[Unit, A] =
|
||||
@ -175,12 +174,15 @@ private[trigger] object UnfoldState {
|
||||
|
||||
private[this] def statefulMapConcatFun[T, A, B](f: FoldL[T, A, B]): T \/ A => Iterable[T \/ B] = {
|
||||
var mcFun: A => Iterable[T \/ B] = null
|
||||
_ fold (zeroT => {
|
||||
mcFun = mkMapConcatFun(zeroT, f)
|
||||
Iterable.empty
|
||||
}, { a =>
|
||||
mcFun(a)
|
||||
})
|
||||
_.fold(
|
||||
zeroT => {
|
||||
mcFun = mkMapConcatFun(zeroT, f)
|
||||
Iterable.empty
|
||||
},
|
||||
{ a =>
|
||||
mcFun(a)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
private[this] def mkMapConcatFun[T, A, B](zero: T, f: FoldL[T, A, B]): A => Iterable[T \/ B] = {
|
||||
@ -196,7 +198,7 @@ private[trigger] object UnfoldState {
|
||||
override def iterator = new Iterator[T \/ B] {
|
||||
private[this] var last: Option[T \/ (B, bs.S)] = {
|
||||
val fst = step(bs.init)
|
||||
fst fold (newT => t = newT, _ => ())
|
||||
fst.fold(newT => t = newT, _ => ())
|
||||
Some(fst)
|
||||
}
|
||||
|
||||
@ -204,7 +206,7 @@ private[trigger] object UnfoldState {
|
||||
// of what the client sees. We could improve laziness by making it
|
||||
// "even", but it would be a little trickier, as `hasNext` would have
|
||||
// a forcing side-effect
|
||||
override def hasNext() = last.isDefined
|
||||
override def hasNext = last.isDefined
|
||||
|
||||
override def next() =
|
||||
last match {
|
||||
@ -212,7 +214,7 @@ private[trigger] object UnfoldState {
|
||||
val next = step(s)
|
||||
// The assumption here is that statefulMapConcat's implementation
|
||||
// will always read iterator to end before invoking on the next A
|
||||
next fold (newT => t = newT, _ => ())
|
||||
next.fold(newT => t = newT, _ => ())
|
||||
last = Some(next)
|
||||
\/-(b)
|
||||
case Some(et @ -\/(_)) =>
|
||||
|
@ -19,6 +19,32 @@ da_scala_library(
|
||||
name = "trigger-service",
|
||||
srcs = glob(["src/main/scala/**/*.scala"]),
|
||||
resources = glob(["src/main/resources/**/*"]),
|
||||
scala_deps = [
|
||||
"@maven//:com_chuusai_shapeless",
|
||||
"@maven//:com_github_scopt_scopt",
|
||||
"@maven//:com_lihaoyi_sourcecode",
|
||||
"@maven//:com_typesafe_akka_akka_actor",
|
||||
"@maven//:com_typesafe_akka_akka_actor_typed",
|
||||
"@maven//:com_typesafe_akka_akka_http",
|
||||
"@maven//:com_typesafe_akka_akka_http_core",
|
||||
"@maven//:com_typesafe_akka_akka_http_spray_json",
|
||||
"@maven//:com_typesafe_akka_akka_parsing",
|
||||
"@maven//:com_typesafe_akka_akka_stream",
|
||||
"@maven//:com_typesafe_scala_logging_scala_logging",
|
||||
"@maven//:io_spray_spray_json",
|
||||
"@maven//:org_scalaz_scalaz_core",
|
||||
"@maven//:org_tpolecat_doobie_core",
|
||||
"@maven//:org_tpolecat_doobie_free",
|
||||
"@maven//:org_tpolecat_doobie_postgres",
|
||||
"@maven//:org_typelevel_cats_core",
|
||||
"@maven//:org_typelevel_cats_effect",
|
||||
"@maven//:org_typelevel_cats_free",
|
||||
"@maven//:org_typelevel_cats_kernel",
|
||||
],
|
||||
scala_runtime_deps = [
|
||||
"@maven//:com_typesafe_akka_akka_slf4j",
|
||||
"@maven//:org_tpolecat_doobie_postgres",
|
||||
],
|
||||
scalacopts = tsvc_main_scalacopts,
|
||||
# Uncomment this if/when the target is published to maven.
|
||||
# tags = ["maven_coordinates=com.daml:trigger-service:__VERSION__"],
|
||||
@ -26,9 +52,7 @@ da_scala_library(
|
||||
runtime_deps = [
|
||||
"@maven//:ch_qos_logback_logback_classic",
|
||||
"@maven//:ch_qos_logback_logback_core",
|
||||
"@maven//:com_typesafe_akka_akka_slf4j_2_12",
|
||||
"@maven//:org_postgresql_postgresql",
|
||||
"@maven//:org_tpolecat_doobie_postgres_2_12",
|
||||
],
|
||||
deps = [
|
||||
"//daml-lf/archive:daml_lf_archive_reader",
|
||||
@ -51,29 +75,10 @@ da_scala_library(
|
||||
"//libs-scala/scala-utils",
|
||||
"//triggers/runner:trigger-runner-lib",
|
||||
"//triggers/service/auth:middleware-api",
|
||||
"@maven//:com_chuusai_shapeless_2_12",
|
||||
"@maven//:com_github_scopt_scopt_2_12",
|
||||
"@maven//:com_lihaoyi_sourcecode_2_12",
|
||||
"@maven//:com_typesafe_akka_akka_actor_2_12",
|
||||
"@maven//:com_typesafe_akka_akka_actor_typed_2_12",
|
||||
"@maven//:com_typesafe_akka_akka_http_2_12",
|
||||
"@maven//:com_typesafe_akka_akka_http_core_2_12",
|
||||
"@maven//:com_typesafe_akka_akka_http_spray_json_2_12",
|
||||
"@maven//:com_typesafe_akka_akka_parsing_2_12",
|
||||
"@maven//:com_typesafe_akka_akka_stream_2_12",
|
||||
"@maven//:com_typesafe_scala_logging_scala_logging_2_12",
|
||||
"@maven//:com_typesafe_config",
|
||||
"@maven//:com_zaxxer_HikariCP",
|
||||
"@maven//:io_spray_spray_json_2_12",
|
||||
"@maven//:org_flywaydb_flyway_core",
|
||||
"@maven//:org_scalaz_scalaz_core_2_12",
|
||||
"@maven//:org_slf4j_slf4j_api",
|
||||
"@maven//:org_tpolecat_doobie_core_2_12",
|
||||
"@maven//:org_tpolecat_doobie_free_2_12",
|
||||
"@maven//:org_tpolecat_doobie_postgres_2_12",
|
||||
"@maven//:org_typelevel_cats_core_2_12",
|
||||
"@maven//:org_typelevel_cats_effect_2_12",
|
||||
"@maven//:org_typelevel_cats_free_2_12",
|
||||
"@maven//:org_typelevel_cats_kernel_2_12",
|
||||
],
|
||||
)
|
||||
|
||||
@ -99,6 +104,15 @@ da_scala_library(
|
||||
]
|
||||
),
|
||||
resources = glob(["src/test/resources/**/*"]),
|
||||
scala_deps = [
|
||||
"@maven//:io_spray_spray_json",
|
||||
"@maven//:org_scalactic_scalactic",
|
||||
"@maven//:org_scalatest_scalatest",
|
||||
"@maven//:org_scalaz_scalaz_core",
|
||||
"@maven//:com_typesafe_akka_akka_actor_typed",
|
||||
"@maven//:com_typesafe_akka_akka_http_core",
|
||||
"@maven//:com_typesafe_akka_akka_parsing",
|
||||
],
|
||||
deps = [
|
||||
":trigger-service",
|
||||
"//bazel_tools/runfiles:scala_runfiles",
|
||||
@ -129,20 +143,19 @@ da_scala_library(
|
||||
"//triggers/service/auth:oauth2-test-server",
|
||||
"@maven//:ch_qos_logback_logback_classic",
|
||||
"@maven//:com_auth0_java_jwt",
|
||||
"@maven//:com_typesafe_akka_akka_actor_typed_2_12",
|
||||
"@maven//:com_typesafe_akka_akka_http_core_2_12",
|
||||
"@maven//:com_typesafe_akka_akka_parsing_2_12",
|
||||
"@maven//:eu_rekawek_toxiproxy_toxiproxy_java_2_1_3",
|
||||
"@maven//:io_spray_spray_json_2_12",
|
||||
"@maven//:org_scalactic_scalactic_2_12",
|
||||
"@maven//:org_scalatest_scalatest_2_12",
|
||||
"@maven//:org_scalaz_scalaz_core_2_12",
|
||||
],
|
||||
)
|
||||
|
||||
da_scala_test_suite(
|
||||
name = "test",
|
||||
srcs = glob(["src/test-suite/scala/**/*.scala"]),
|
||||
scala_deps = [
|
||||
"@maven//:com_typesafe_akka_akka_http_core",
|
||||
"@maven//:io_spray_spray_json",
|
||||
"@maven//:org_scalatest_scalatest",
|
||||
"@maven//:org_scalaz_scalaz_core",
|
||||
],
|
||||
deps = [
|
||||
":trigger-service",
|
||||
":trigger-service-tests",
|
||||
@ -165,12 +178,8 @@ da_scala_test_suite(
|
||||
"//libs-scala/postgresql-testing",
|
||||
"//libs-scala/resources",
|
||||
"//triggers/service/auth:oauth2-test-server",
|
||||
"@maven//:com_typesafe_akka_akka_http_core_2_12",
|
||||
"@maven//:eu_rekawek_toxiproxy_toxiproxy_java_2_1_3",
|
||||
"@maven//:io_spray_spray_json_2_12",
|
||||
"@maven//:org_flywaydb_flyway_core",
|
||||
"@maven//:org_scalatest_scalatest_2_12",
|
||||
"@maven//:org_scalaz_scalaz_core_2_12",
|
||||
],
|
||||
)
|
||||
|
||||
|
@ -6,6 +6,7 @@ load(
|
||||
"da_scala_binary",
|
||||
"da_scala_library",
|
||||
"da_scala_test",
|
||||
"silencer_plugin",
|
||||
)
|
||||
|
||||
exports_files(["release/oauth2-middleware-logback.xml"])
|
||||
@ -15,42 +16,65 @@ scalacopts = []
|
||||
da_scala_library(
|
||||
name = "oauth2-api",
|
||||
srcs = glob(["src/main/scala/com/daml/auth/oauth2/api/**/*.scala"]),
|
||||
scala_deps = [
|
||||
"@maven//:com_typesafe_akka_akka_actor",
|
||||
"@maven//:com_typesafe_akka_akka_http",
|
||||
"@maven//:com_typesafe_akka_akka_http_core",
|
||||
"@maven//:com_typesafe_akka_akka_parsing",
|
||||
"@maven//:com_typesafe_akka_akka_stream",
|
||||
"@maven//:io_spray_spray_json",
|
||||
],
|
||||
scalacopts = scalacopts,
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"@maven//:com_typesafe_akka_akka_actor_2_12",
|
||||
"@maven//:com_typesafe_akka_akka_http_2_12",
|
||||
"@maven//:com_typesafe_akka_akka_http_core_2_12",
|
||||
"@maven//:com_typesafe_akka_akka_parsing_2_12",
|
||||
"@maven//:com_typesafe_akka_akka_stream_2_12",
|
||||
"@maven//:io_spray_spray_json_2_12",
|
||||
],
|
||||
)
|
||||
|
||||
da_scala_library(
|
||||
name = "middleware-api",
|
||||
srcs = glob(["src/main/scala/com/daml/auth/middleware/api/**/*.scala"]),
|
||||
scala_deps = [
|
||||
"@maven//:com_typesafe_akka_akka_actor",
|
||||
"@maven//:com_typesafe_akka_akka_http",
|
||||
"@maven//:com_typesafe_akka_akka_http_core",
|
||||
"@maven//:com_typesafe_akka_akka_http_spray_json",
|
||||
"@maven//:com_typesafe_akka_akka_parsing",
|
||||
"@maven//:com_typesafe_akka_akka_stream",
|
||||
"@maven//:io_spray_spray_json",
|
||||
"@maven//:org_scalaz_scalaz_core",
|
||||
],
|
||||
scalacopts = scalacopts,
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//daml-lf/data",
|
||||
"//language-support/scala/bindings",
|
||||
"@maven//:com_typesafe_akka_akka_actor_2_12",
|
||||
"@maven//:com_typesafe_akka_akka_http_2_12",
|
||||
"@maven//:com_typesafe_akka_akka_http_core_2_12",
|
||||
"@maven//:com_typesafe_akka_akka_http_spray_json_2_12",
|
||||
"@maven//:com_typesafe_akka_akka_parsing_2_12",
|
||||
"@maven//:com_typesafe_akka_akka_stream_2_12",
|
||||
"@maven//:io_spray_spray_json_2_12",
|
||||
"@maven//:org_scalaz_scalaz_core_2_12",
|
||||
],
|
||||
)
|
||||
|
||||
da_scala_library(
|
||||
name = "oauth2-middleware",
|
||||
srcs = glob(["src/main/scala/com/daml/auth/middleware/oauth2/**/*.scala"]),
|
||||
plugins = [silencer_plugin],
|
||||
resources = glob(["src/main/resources/com/daml/auth/middleware/oauth2/**"]),
|
||||
scalacopts = scalacopts,
|
||||
scala_deps = [
|
||||
"@maven//:com_github_scopt_scopt",
|
||||
"@maven//:com_lihaoyi_fastparse",
|
||||
"@maven//:com_lihaoyi_geny",
|
||||
"@maven//:com_lihaoyi_os_lib",
|
||||
"@maven//:com_lihaoyi_sjsonnet",
|
||||
"@maven//:com_lihaoyi_ujson",
|
||||
"@maven//:com_lihaoyi_upickle_core",
|
||||
"@maven//:com_typesafe_akka_akka_actor",
|
||||
"@maven//:com_typesafe_akka_akka_http",
|
||||
"@maven//:com_typesafe_akka_akka_http_core",
|
||||
"@maven//:com_typesafe_akka_akka_http_spray_json",
|
||||
"@maven//:com_typesafe_akka_akka_parsing",
|
||||
"@maven//:com_typesafe_akka_akka_stream",
|
||||
"@maven//:com_typesafe_scala_logging_scala_logging",
|
||||
"@maven//:io_spray_spray_json",
|
||||
"@maven//:org_scalaz_scalaz_core",
|
||||
],
|
||||
scalacopts = scalacopts + [
|
||||
"-P:silencer:lineContentFilters=import scala.collection.compat",
|
||||
],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
":middleware-api",
|
||||
@ -62,22 +86,6 @@ da_scala_library(
|
||||
"//ledger/cli-opts",
|
||||
"//ledger/ledger-api-auth",
|
||||
"//libs-scala/ports",
|
||||
"@maven//:com_github_scopt_scopt_2_12",
|
||||
"@maven//:com_lihaoyi_fastparse_2_12",
|
||||
"@maven//:com_lihaoyi_geny_2_12",
|
||||
"@maven//:com_lihaoyi_os_lib_2_12",
|
||||
"@maven//:com_lihaoyi_sjsonnet_2_12",
|
||||
"@maven//:com_lihaoyi_ujson_2_12",
|
||||
"@maven//:com_lihaoyi_upickle_core_2_12",
|
||||
"@maven//:com_typesafe_akka_akka_actor_2_12",
|
||||
"@maven//:com_typesafe_akka_akka_http_2_12",
|
||||
"@maven//:com_typesafe_akka_akka_http_core_2_12",
|
||||
"@maven//:com_typesafe_akka_akka_http_spray_json_2_12",
|
||||
"@maven//:com_typesafe_akka_akka_parsing_2_12",
|
||||
"@maven//:com_typesafe_akka_akka_stream_2_12",
|
||||
"@maven//:com_typesafe_scala_logging_scala_logging_2_12",
|
||||
"@maven//:io_spray_spray_json_2_12",
|
||||
"@maven//:org_scalaz_scalaz_core_2_12",
|
||||
"@maven//:org_slf4j_slf4j_api",
|
||||
],
|
||||
)
|
||||
@ -97,6 +105,18 @@ da_scala_binary(
|
||||
da_scala_library(
|
||||
name = "oauth2-test-server",
|
||||
srcs = glob(["src/main/scala/com/daml/auth/oauth2/test/server/**/*.scala"]),
|
||||
scala_deps = [
|
||||
"@maven//:com_github_scopt_scopt",
|
||||
"@maven//:com_typesafe_akka_akka_actor",
|
||||
"@maven//:com_typesafe_akka_akka_http",
|
||||
"@maven//:com_typesafe_akka_akka_http_core",
|
||||
"@maven//:com_typesafe_akka_akka_http_spray_json",
|
||||
"@maven//:com_typesafe_akka_akka_parsing",
|
||||
"@maven//:com_typesafe_akka_akka_stream",
|
||||
"@maven//:com_typesafe_scala_logging_scala_logging",
|
||||
"@maven//:io_spray_spray_json",
|
||||
"@maven//:org_scalaz_scalaz_core",
|
||||
],
|
||||
scalacopts = scalacopts,
|
||||
visibility = ["//triggers/service:__subpackages__"],
|
||||
deps = [
|
||||
@ -105,15 +125,6 @@ da_scala_library(
|
||||
"//ledger-service/jwt",
|
||||
"//ledger/ledger-api-auth",
|
||||
"//libs-scala/ports",
|
||||
"@maven//:com_github_scopt_scopt_2_12",
|
||||
"@maven//:com_typesafe_akka_akka_actor_2_12",
|
||||
"@maven//:com_typesafe_akka_akka_http_2_12",
|
||||
"@maven//:com_typesafe_akka_akka_http_core_2_12",
|
||||
"@maven//:com_typesafe_akka_akka_http_spray_json_2_12",
|
||||
"@maven//:com_typesafe_akka_akka_stream_2_12",
|
||||
"@maven//:com_typesafe_scala_logging_scala_logging_2_12",
|
||||
"@maven//:io_spray_spray_json_2_12",
|
||||
"@maven//:org_scalaz_scalaz_core_2_12",
|
||||
"@maven//:org_slf4j_slf4j_api",
|
||||
],
|
||||
)
|
||||
@ -132,6 +143,16 @@ da_scala_binary(
|
||||
da_scala_test(
|
||||
name = "oauth2-test-server-tests",
|
||||
srcs = glob(["src/test/scala/com/daml/auth/oauth2/test/server/**/*.scala"]),
|
||||
scala_deps = [
|
||||
"@maven//:com_typesafe_akka_akka_actor",
|
||||
"@maven//:com_typesafe_akka_akka_http",
|
||||
"@maven//:com_typesafe_akka_akka_http_core",
|
||||
"@maven//:com_typesafe_akka_akka_http_spray_json",
|
||||
"@maven//:com_typesafe_akka_akka_parsing",
|
||||
"@maven//:com_typesafe_akka_akka_stream",
|
||||
"@maven//:io_spray_spray_json",
|
||||
"@maven//:org_scalaz_scalaz_core",
|
||||
],
|
||||
scalacopts = scalacopts,
|
||||
deps = [
|
||||
":oauth2-api",
|
||||
@ -145,20 +166,23 @@ da_scala_test(
|
||||
"//libs-scala/adjustable-clock",
|
||||
"//libs-scala/ports",
|
||||
"//libs-scala/resources",
|
||||
"@maven//:com_typesafe_akka_akka_actor_2_12",
|
||||
"@maven//:com_typesafe_akka_akka_http_2_12",
|
||||
"@maven//:com_typesafe_akka_akka_http_core_2_12",
|
||||
"@maven//:com_typesafe_akka_akka_http_spray_json_2_12",
|
||||
"@maven//:com_typesafe_akka_akka_parsing_2_12",
|
||||
"@maven//:com_typesafe_akka_akka_stream_2_12",
|
||||
"@maven//:io_spray_spray_json_2_12",
|
||||
"@maven//:org_scalaz_scalaz_core_2_12",
|
||||
],
|
||||
)
|
||||
|
||||
da_scala_test(
|
||||
name = "oauth2-middleware-tests",
|
||||
srcs = glob(["src/test/scala/com/daml/auth/middleware/oauth2/**/*.scala"]),
|
||||
scala_deps = [
|
||||
"@maven//:com_typesafe_akka_akka_actor",
|
||||
"@maven//:com_typesafe_akka_akka_http",
|
||||
"@maven//:com_typesafe_akka_akka_http_core",
|
||||
"@maven//:com_typesafe_akka_akka_http_spray_json",
|
||||
"@maven//:com_typesafe_akka_akka_parsing",
|
||||
"@maven//:com_typesafe_akka_akka_stream",
|
||||
"@maven//:com_typesafe_scala_logging_scala_logging",
|
||||
"@maven//:io_spray_spray_json",
|
||||
"@maven//:org_scalaz_scalaz_core",
|
||||
],
|
||||
scalacopts = scalacopts,
|
||||
deps = [
|
||||
":middleware-api",
|
||||
@ -177,14 +201,5 @@ da_scala_test(
|
||||
"//libs-scala/resources",
|
||||
"//libs-scala/scala-utils",
|
||||
"@maven//:com_auth0_java_jwt",
|
||||
"@maven//:com_typesafe_akka_akka_actor_2_12",
|
||||
"@maven//:com_typesafe_akka_akka_http_2_12",
|
||||
"@maven//:com_typesafe_akka_akka_http_core_2_12",
|
||||
"@maven//:com_typesafe_akka_akka_http_spray_json_2_12",
|
||||
"@maven//:com_typesafe_akka_akka_parsing_2_12",
|
||||
"@maven//:com_typesafe_akka_akka_stream_2_12",
|
||||
"@maven//:com_typesafe_scala_logging_scala_logging_2_12",
|
||||
"@maven//:io_spray_spray_json_2_12",
|
||||
"@maven//:org_scalaz_scalaz_core_2_12",
|
||||
],
|
||||
)
|
||||
|
@ -48,7 +48,7 @@ class Client(config: Client.Config) {
|
||||
* Note, a GET request on the `callbackUri` must map to this route.
|
||||
*/
|
||||
val callbackHandler: Route =
|
||||
parameters('state.as[UUID]) { requestId =>
|
||||
parameters(Symbol("state").as[UUID]) { requestId =>
|
||||
callbacks.pop(requestId) match {
|
||||
case None =>
|
||||
complete(StatusCodes.NotFound)
|
||||
|
@ -13,6 +13,7 @@ import com.daml.ledger.api.refinements.ApiTypes.{ApplicationId, Party}
|
||||
import scalaz.{@@, Tag}
|
||||
import spray.json._
|
||||
|
||||
import scala.collection.compat.immutable.LazyList
|
||||
import scala.collection.mutable.ArrayBuffer
|
||||
import scala.concurrent._
|
||||
import scala.util.Try
|
||||
@ -42,10 +43,10 @@ object Request {
|
||||
applicationId: Option[ApplicationId],
|
||||
) {
|
||||
def toQueryString() = {
|
||||
val adminS = if (admin) Stream("admin") else Stream()
|
||||
val actAsS = actAs.toStream.map(party => s"actAs:$party")
|
||||
val readAsS = readAs.toStream.map(party => s"readAs:$party")
|
||||
val applicationIdS = applicationId.toList.toStream.map(appId => s"applicationId:$appId")
|
||||
val adminS = if (admin) LazyList("admin") else LazyList()
|
||||
val actAsS = actAs.to(LazyList).map(party => s"actAs:$party")
|
||||
val readAsS = readAs.to(LazyList).map(party => s"readAs:$party")
|
||||
val applicationIdS = applicationId.toList.to(LazyList).map(appId => s"applicationId:$appId")
|
||||
(adminS ++ actAsS ++ readAsS ++ applicationIdS).mkString(" ")
|
||||
}
|
||||
}
|
||||
@ -85,7 +86,7 @@ object Request {
|
||||
Claims(admin, actAs.toList, readAs.toList, applicationId)
|
||||
}
|
||||
implicit val marshalRequestEntity: Marshaller[Claims, String] =
|
||||
Marshaller.opaque(_.toQueryString)
|
||||
Marshaller.opaque(_.toQueryString())
|
||||
implicit val unmarshalHttpEntity: Unmarshaller[String, Claims] =
|
||||
Unmarshaller { _ => s => Future.fromTry(Try(apply(s))) }
|
||||
}
|
||||
@ -128,7 +129,7 @@ object Response {
|
||||
|
||||
object Login {
|
||||
val callbackParameters: Directive1[Login] =
|
||||
parameters('error, 'error_description ?)
|
||||
parameters(Symbol("error"), Symbol("error_description") ?)
|
||||
.as[LoginError](LoginError)
|
||||
.or(provide(LoginSuccess))
|
||||
}
|
||||
|
@ -62,7 +62,7 @@ object Config {
|
||||
tokenVerifier = null,
|
||||
)
|
||||
|
||||
def parseConfig(args: Seq[String]): Option[Config] =
|
||||
def parseConfig(args: collection.Seq[String]): Option[Config] =
|
||||
configParser.parse(args, Empty)
|
||||
|
||||
@SuppressWarnings(Array("org.wartremover.warts.NonUnitStatements"))
|
||||
@ -123,7 +123,8 @@ object Config {
|
||||
.action((x, c) => c.copy(oauthRefreshTemplate = Some(Paths.get(x))))
|
||||
.text("OAuth2 refresh request Jsonnet template")
|
||||
|
||||
opt[String]("id").hidden
|
||||
opt[String]("id")
|
||||
.hidden()
|
||||
.action((x, c) => c.copy(clientId = x))
|
||||
.withFallback(() => sys.env.getOrElse("DAML_CLIENT_ID", ""))
|
||||
.validate(x =>
|
||||
@ -131,7 +132,8 @@ object Config {
|
||||
else success
|
||||
)
|
||||
|
||||
opt[String]("secret").hidden
|
||||
opt[String]("secret")
|
||||
.hidden()
|
||||
.action((x, c) => c.copy(clientSecret = x))
|
||||
.withFallback(() => sys.env.getOrElse("DAML_CLIENT_SECRET", ""))
|
||||
.validate(x =>
|
||||
|
@ -11,6 +11,7 @@ import com.daml.auth.middleware.api.Request
|
||||
import com.daml.auth.middleware.api.Tagged.RefreshToken
|
||||
import com.daml.ledger.api.refinements.ApiTypes.{ApplicationId, Party}
|
||||
|
||||
import scala.collection.compat._
|
||||
import scala.collection.concurrent.TrieMap
|
||||
import scala.io.{BufferedSource, Source}
|
||||
import scala.util.Try
|
||||
@ -88,7 +89,7 @@ private[oauth2] class RequestTemplates(
|
||||
/** Convert a JSON value to a string mapping representing request parameters.
|
||||
*/
|
||||
private def toRequestParams(value: ujson.Value): Try[Map[String, String]] =
|
||||
Try(value.obj.mapValues(_.str).toMap)
|
||||
Try(value.obj.view.mapValues(_.str).toMap)
|
||||
|
||||
private def createRequest(
|
||||
template: (String, sjsonnet.Path),
|
||||
|
@ -27,6 +27,7 @@ import com.daml.ports.{Port, PortFiles}
|
||||
import scalaz.{-\/, \/-}
|
||||
import spray.json._
|
||||
|
||||
import scala.collection.compat._
|
||||
import scala.concurrent.{ExecutionContext, Future}
|
||||
import scala.language.postfixOps
|
||||
import scala.util.{Failure, Success, Try}
|
||||
@ -97,7 +98,7 @@ class Server(config: Config) extends StrictLogging {
|
||||
}
|
||||
|
||||
private val auth: Route =
|
||||
parameters('claims.as[Request.Claims])
|
||||
parameters(Symbol("claims").as[Request.Claims])
|
||||
.as[Request.Auth](Request.Auth) { auth =>
|
||||
optionalToken {
|
||||
case Some(token)
|
||||
@ -119,14 +120,18 @@ class Server(config: Config) extends StrictLogging {
|
||||
new RequestStore(config.maxLoginRequests, config.loginTimeout)
|
||||
|
||||
private val login: Route =
|
||||
parameters('redirect_uri.as[Uri] ?, 'claims.as[Request.Claims], 'state ?)
|
||||
parameters(
|
||||
Symbol("redirect_uri").as[Uri] ?,
|
||||
Symbol("claims").as[Request.Claims],
|
||||
Symbol("state") ?,
|
||||
)
|
||||
.as[Request.Login](Request.Login) { login =>
|
||||
extractRequest { request =>
|
||||
val requestId = UUID.randomUUID
|
||||
val stored = requests.put(
|
||||
requestId,
|
||||
login.redirectUri.map { redirectUri =>
|
||||
var query = redirectUri.query().to[Seq]
|
||||
var query = redirectUri.query().to(Seq)
|
||||
login.state.foreach(x => query ++= Seq("state" -> x))
|
||||
redirectUri.withQuery(Uri.Query(query: _*))
|
||||
},
|
||||
@ -166,7 +171,7 @@ class Server(config: Config) extends StrictLogging {
|
||||
}
|
||||
|
||||
concat(
|
||||
parameters('code, 'state ?)
|
||||
parameters(Symbol("code"), Symbol("state") ?)
|
||||
.as[OAuthResponse.Authorize](OAuthResponse.Authorize) { authorize =>
|
||||
popRequest(authorize.state) { redirectUri =>
|
||||
extractRequest { request =>
|
||||
@ -219,12 +224,17 @@ class Server(config: Config) extends StrictLogging {
|
||||
}
|
||||
}
|
||||
},
|
||||
parameters('error, 'error_description ?, 'error_uri.as[Uri] ?, 'state ?)
|
||||
parameters(
|
||||
Symbol("error"),
|
||||
Symbol("error_description") ?,
|
||||
Symbol("error_uri").as[Uri] ?,
|
||||
Symbol("state") ?,
|
||||
)
|
||||
.as[OAuthResponse.Error](OAuthResponse.Error) { error =>
|
||||
popRequest(error.state) {
|
||||
case Some(redirectUri) =>
|
||||
val uri = redirectUri.withQuery {
|
||||
var params = redirectUri.query().to[Seq]
|
||||
var params = redirectUri.query().to(Seq)
|
||||
params ++= Seq("error" -> error.error)
|
||||
error.errorDescription.foreach(x => params ++= Seq("error_description" -> x))
|
||||
Uri.Query(params: _*)
|
||||
|
@ -22,7 +22,7 @@ object Config {
|
||||
private val Empty =
|
||||
Config(port = Port.Dynamic, ledgerId = null, jwtSecret = null, clock = None)
|
||||
|
||||
def parseConfig(args: Seq[String]): Option[Config] =
|
||||
def parseConfig(args: collection.Seq[String]): Option[Config] =
|
||||
configParser.parse(args, Empty)
|
||||
|
||||
@SuppressWarnings(Array("org.wartremover.warts.NonUnitStatements"))
|
||||
|
@ -120,7 +120,6 @@ class Server(config: Config) {
|
||||
}
|
||||
}
|
||||
|
||||
import Request.Token.unmarshalHttpEntity
|
||||
import Request.Refresh.unmarshalHttpEntity
|
||||
implicit val unmarshal: Unmarshaller[String, Uri] = Unmarshaller.strict(Uri(_))
|
||||
|
||||
@ -128,12 +127,12 @@ class Server(config: Config) {
|
||||
path("authorize") {
|
||||
get {
|
||||
parameters(
|
||||
'response_type,
|
||||
'client_id,
|
||||
'redirect_uri.as[Uri],
|
||||
'scope ?,
|
||||
'state ?,
|
||||
'audience.as[Uri] ?,
|
||||
Symbol("response_type"),
|
||||
Symbol("client_id"),
|
||||
Symbol("redirect_uri").as[Uri],
|
||||
Symbol("scope") ?,
|
||||
Symbol("state") ?,
|
||||
Symbol("audience").as[Uri] ?,
|
||||
)
|
||||
.as[Request.Authorize](Request.Authorize) { request =>
|
||||
val payload = toPayload(request)
|
||||
|
@ -72,7 +72,7 @@ object Resources {
|
||||
concat(
|
||||
path("authorize") {
|
||||
get {
|
||||
parameters('claims.as[Claims]) { claims =>
|
||||
parameters(Symbol("claims").as[Claims]) { claims =>
|
||||
client.authorize(claims) {
|
||||
case Client.Authorized(authorization) =>
|
||||
import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport._
|
||||
@ -93,7 +93,7 @@ object Resources {
|
||||
},
|
||||
path("login") {
|
||||
get {
|
||||
parameters('claims.as[Claims]) { claims =>
|
||||
parameters(Symbol("claims").as[Claims]) { claims =>
|
||||
import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport._
|
||||
import com.daml.auth.middleware.api.JsonProtocol.ResponseLoginFormat
|
||||
client.login(claims, login => complete(StatusCodes.OK, login))
|
||||
|
@ -391,7 +391,7 @@ class TestMiddlewareClientLimitedCallbackStore
|
||||
.withScheme("http")
|
||||
.withAuthority(host.getHostName, host.getPort)
|
||||
.withPath(Uri.Path./("login"))
|
||||
.withQuery(Uri.Query("claims" -> claims.toQueryString))
|
||||
.withQuery(Uri.Query("claims" -> claims.toQueryString()))
|
||||
val req = HttpRequest(uri = uri)
|
||||
Http().singleRequest(req)
|
||||
}
|
||||
@ -451,7 +451,7 @@ class TestMiddlewareClientNoRedirectToLogin
|
||||
.withScheme("http")
|
||||
.withAuthority(host.getHostName, host.getPort)
|
||||
.withPath(Uri.Path./("authorize"))
|
||||
.withQuery(Uri.Query("claims" -> claims.toQueryString))
|
||||
.withQuery(Uri.Query("claims" -> claims.toQueryString()))
|
||||
val req = HttpRequest(uri = uri)
|
||||
for {
|
||||
resp <- Http().singleRequest(req)
|
||||
@ -461,7 +461,7 @@ class TestMiddlewareClientNoRedirectToLogin
|
||||
challenge = wwwAuthenticate.challenges
|
||||
.find(_.scheme == Response.authenticateChallengeName)
|
||||
.value
|
||||
_ = challenge.params.keys should contain allOf ("auth", "login")
|
||||
_ = challenge.params.keys should contain.allOf("auth", "login")
|
||||
authUri = challenge.params.get("auth").value
|
||||
loginUri = challenge.params.get("login").value
|
||||
headerChallenge = Response.AuthenticateChallenge(
|
||||
@ -499,7 +499,7 @@ class TestMiddlewareClientYesRedirectToLogin
|
||||
.withScheme("http")
|
||||
.withAuthority(host.getHostName, host.getPort)
|
||||
.withPath(Uri.Path./("authorize"))
|
||||
.withQuery(Uri.Query("claims" -> claims.toQueryString))
|
||||
.withQuery(Uri.Query("claims" -> claims.toQueryString()))
|
||||
val req = HttpRequest(uri = uri)
|
||||
for {
|
||||
resp <- Http().singleRequest(req)
|
||||
@ -531,7 +531,7 @@ class TestMiddlewareClientAutoRedirectToLogin
|
||||
.withScheme("http")
|
||||
.withAuthority(host.getHostName, host.getPort)
|
||||
.withPath(Uri.Path./("authorize"))
|
||||
.withQuery(Uri.Query("claims" -> claims.toQueryString))
|
||||
.withQuery(Uri.Query("claims" -> claims.toQueryString()))
|
||||
val acceptHtml: HttpHeader = headers.Accept(MediaTypes.`text/html`)
|
||||
val req = HttpRequest(uri = uri, headers = immutable.Seq(acceptHtml))
|
||||
for {
|
||||
@ -548,7 +548,7 @@ class TestMiddlewareClientAutoRedirectToLogin
|
||||
.withScheme("http")
|
||||
.withAuthority(host.getHostName, host.getPort)
|
||||
.withPath(Uri.Path./("authorize"))
|
||||
.withQuery(Uri.Query("claims" -> claims.toQueryString))
|
||||
.withQuery(Uri.Query("claims" -> claims.toQueryString()))
|
||||
val acceptHtml: HttpHeader = headers.Accept(MediaTypes.`application/json`)
|
||||
val req = HttpRequest(uri = uri, headers = immutable.Seq(acceptHtml))
|
||||
for {
|
||||
|
@ -54,8 +54,15 @@ class TestRequestTemplates
|
||||
val requestId = UUID.randomUUID()
|
||||
val redirectUri = Uri("https://localhost/cb")
|
||||
val params = templates.createAuthRequest(claims, requestId, redirectUri).success.value
|
||||
params.keys should contain only ("audience", "client_id", "redirect_uri", "response_type", "scope", "state")
|
||||
params should contain allOf (
|
||||
params.keys should contain.only(
|
||||
"audience",
|
||||
"client_id",
|
||||
"redirect_uri",
|
||||
"response_type",
|
||||
"scope",
|
||||
"state",
|
||||
)
|
||||
params should contain.allOf(
|
||||
"audience" -> "https://daml.com/ledger-api",
|
||||
"client_id" -> clientId,
|
||||
"redirect_uri" -> redirectUri.toString,
|
||||
@ -70,8 +77,15 @@ class TestRequestTemplates
|
||||
val requestId = UUID.randomUUID()
|
||||
val redirectUri = Uri("https://localhost/cb")
|
||||
val params = templates.createAuthRequest(claims, requestId, redirectUri).success.value
|
||||
params.keys should contain only ("audience", "client_id", "redirect_uri", "response_type", "scope", "state")
|
||||
params should contain allOf (
|
||||
params.keys should contain.only(
|
||||
"audience",
|
||||
"client_id",
|
||||
"redirect_uri",
|
||||
"response_type",
|
||||
"scope",
|
||||
"state",
|
||||
)
|
||||
params should contain.allOf(
|
||||
"audience" -> "https://daml.com/ledger-api",
|
||||
"client_id" -> clientId,
|
||||
"redirect_uri" -> redirectUri.toString,
|
||||
@ -79,7 +93,7 @@ class TestRequestTemplates
|
||||
"state" -> requestId.toString,
|
||||
)
|
||||
val scope = params.valueAt("scope").split(" ")
|
||||
scope should contain allOf ("admin", "offline_access")
|
||||
scope should contain.allOf("admin", "offline_access")
|
||||
}
|
||||
"handle actAs claims" in {
|
||||
val templates = getTemplates()
|
||||
@ -92,8 +106,15 @@ class TestRequestTemplates
|
||||
val requestId = UUID.randomUUID()
|
||||
val redirectUri = Uri("https://localhost/cb")
|
||||
val params = templates.createAuthRequest(claims, requestId, redirectUri).success.value
|
||||
params.keys should contain only ("audience", "client_id", "redirect_uri", "response_type", "scope", "state")
|
||||
params should contain allOf (
|
||||
params.keys should contain.only(
|
||||
"audience",
|
||||
"client_id",
|
||||
"redirect_uri",
|
||||
"response_type",
|
||||
"scope",
|
||||
"state",
|
||||
)
|
||||
params should contain.allOf(
|
||||
"audience" -> "https://daml.com/ledger-api",
|
||||
"client_id" -> clientId,
|
||||
"redirect_uri" -> redirectUri.toString,
|
||||
@ -101,7 +122,7 @@ class TestRequestTemplates
|
||||
"state" -> requestId.toString,
|
||||
)
|
||||
val scope = params.valueAt("scope").split(" ")
|
||||
scope should contain allOf ("actAs:Alice", "actAs:Bob", "offline_access")
|
||||
scope should contain.allOf("actAs:Alice", "actAs:Bob", "offline_access")
|
||||
}
|
||||
"handle readAs claims" in {
|
||||
val templates = getTemplates()
|
||||
@ -114,8 +135,15 @@ class TestRequestTemplates
|
||||
val requestId = UUID.randomUUID()
|
||||
val redirectUri = Uri("https://localhost/cb")
|
||||
val params = templates.createAuthRequest(claims, requestId, redirectUri).success.value
|
||||
params.keys should contain only ("audience", "client_id", "redirect_uri", "response_type", "scope", "state")
|
||||
params should contain allOf (
|
||||
params.keys should contain.only(
|
||||
"audience",
|
||||
"client_id",
|
||||
"redirect_uri",
|
||||
"response_type",
|
||||
"scope",
|
||||
"state",
|
||||
)
|
||||
params should contain.allOf(
|
||||
"audience" -> "https://daml.com/ledger-api",
|
||||
"client_id" -> clientId,
|
||||
"redirect_uri" -> redirectUri.toString,
|
||||
@ -123,7 +151,7 @@ class TestRequestTemplates
|
||||
"state" -> requestId.toString,
|
||||
)
|
||||
val scope = params.valueAt("scope").split(" ")
|
||||
scope should contain allOf ("offline_access", "readAs:Alice", "readAs:Bob")
|
||||
scope should contain.allOf("offline_access", "readAs:Alice", "readAs:Bob")
|
||||
}
|
||||
"handle an applicationId claim" in {
|
||||
val templates = getTemplates()
|
||||
@ -136,8 +164,15 @@ class TestRequestTemplates
|
||||
val requestId = UUID.randomUUID()
|
||||
val redirectUri = Uri("https://localhost/cb")
|
||||
val params = templates.createAuthRequest(claims, requestId, redirectUri).success.value
|
||||
params.keys should contain only ("audience", "client_id", "redirect_uri", "response_type", "scope", "state")
|
||||
params should contain allOf (
|
||||
params.keys should contain.only(
|
||||
"audience",
|
||||
"client_id",
|
||||
"redirect_uri",
|
||||
"response_type",
|
||||
"scope",
|
||||
"state",
|
||||
)
|
||||
params should contain.allOf(
|
||||
"audience" -> "https://daml.com/ledger-api",
|
||||
"client_id" -> clientId,
|
||||
"redirect_uri" -> redirectUri.toString,
|
||||
@ -145,7 +180,7 @@ class TestRequestTemplates
|
||||
"state" -> requestId.toString,
|
||||
)
|
||||
val scope = params.valueAt("scope").split(" ")
|
||||
scope should contain allOf ("applicationId:application-id", "offline_access")
|
||||
scope should contain.allOf("applicationId:application-id", "offline_access")
|
||||
}
|
||||
}
|
||||
"the builtin token template" should {
|
||||
|
@ -101,36 +101,42 @@ object Client {
|
||||
},
|
||||
path("cb") {
|
||||
get {
|
||||
parameters('code, 'state ?).as[Response.Authorize](Response.Authorize) { resp =>
|
||||
extractRequest { request =>
|
||||
// We got the code, now request a token
|
||||
val body = Request.Token(
|
||||
grantType = "authorization_code",
|
||||
code = resp.code,
|
||||
redirectUri = toRedirectUri(request.uri),
|
||||
clientId = config.clientId,
|
||||
clientSecret = config.clientSecret,
|
||||
)
|
||||
val f = for {
|
||||
entity <- Marshal(body).to[RequestEntity]
|
||||
req = HttpRequest(
|
||||
uri = config.authServerUrl.withPath(Path./("token")),
|
||||
entity = entity,
|
||||
method = HttpMethods.POST,
|
||||
)
|
||||
resp <- Http().singleRequest(req)
|
||||
tokenResp <- Unmarshal(resp).to[Response.Token]
|
||||
} yield tokenResp
|
||||
onSuccess(f) { tokenResp =>
|
||||
// Now we have the access_token and potentially the refresh token. At this point,
|
||||
// we would start the trigger.
|
||||
complete(
|
||||
AccessResponse(tokenResp.accessToken, tokenResp.refreshToken.get): Response
|
||||
parameters(Symbol("code"), Symbol("state") ?).as[Response.Authorize](Response.Authorize) {
|
||||
resp =>
|
||||
extractRequest { request =>
|
||||
// We got the code, now request a token
|
||||
val body = Request.Token(
|
||||
grantType = "authorization_code",
|
||||
code = resp.code,
|
||||
redirectUri = toRedirectUri(request.uri),
|
||||
clientId = config.clientId,
|
||||
clientSecret = config.clientSecret,
|
||||
)
|
||||
val f = for {
|
||||
entity <- Marshal(body).to[RequestEntity]
|
||||
req = HttpRequest(
|
||||
uri = config.authServerUrl.withPath(Path./("token")),
|
||||
entity = entity,
|
||||
method = HttpMethods.POST,
|
||||
)
|
||||
resp <- Http().singleRequest(req)
|
||||
tokenResp <- Unmarshal(resp).to[Response.Token]
|
||||
} yield tokenResp
|
||||
onSuccess(f) { tokenResp =>
|
||||
// Now we have the access_token and potentially the refresh token. At this point,
|
||||
// we would start the trigger.
|
||||
complete(
|
||||
AccessResponse(tokenResp.accessToken, tokenResp.refreshToken.get): Response
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
} ~
|
||||
parameters('error, 'error_description ?, 'error_uri.as[Uri] ?, 'state ?)
|
||||
parameters(
|
||||
Symbol("error"),
|
||||
Symbol("error_description") ?,
|
||||
Symbol("error_uri").as[Uri] ?,
|
||||
Symbol("state") ?,
|
||||
)
|
||||
.as[Response.Error](Response.Error) { resp =>
|
||||
complete(ErrorResponse(resp.error): Response)
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ object Request {
|
||||
implicit object IdentifierFormat extends JsonFormat[Identifier] {
|
||||
def read(value: JsValue): Identifier = value match {
|
||||
case JsString(s) =>
|
||||
Identifier fromString s fold (deserializationError(_), identity)
|
||||
Identifier.fromString(s).fold(deserializationError(_), identity)
|
||||
case _ => deserializationError("Expected trigger identifier of the form pkgid:mod:name")
|
||||
}
|
||||
def write(id: Identifier): JsValue = JsString(id.toString)
|
||||
|
@ -324,7 +324,7 @@ class Server(
|
||||
},
|
||||
// List triggers currently running for the given party.
|
||||
get {
|
||||
parameters('party.as[Party]) { party =>
|
||||
parameters(Symbol("party").as[Party]) { party =>
|
||||
val claims = Claims(readAs = List(party))
|
||||
authorize(claims) { _ =>
|
||||
extractExecutionContext { implicit ec =>
|
||||
|
@ -164,7 +164,7 @@ object TriggerRunnerImpl {
|
||||
// here. It won't receive it (many Bothans died to bring
|
||||
// us this information).
|
||||
logger.info(s"Trigger $name stopped")
|
||||
killSwitch.shutdown
|
||||
killSwitch.shutdown()
|
||||
Behaviors.stopped
|
||||
case (_, PreRestart) =>
|
||||
// No need to send any messages here. The server has
|
||||
|
@ -217,7 +217,7 @@ final class DbTriggerDao private (dataSource: DataSource with Closeable, xa: Con
|
||||
private def run[T](query: ConnectionIO[T], errorContext: String = "")(implicit
|
||||
ec: ExecutionContext
|
||||
): Future[T] = {
|
||||
query.transact(xa).unsafeToFuture.recoverWith { case NonFatal(e) =>
|
||||
query.transact(xa).unsafeToFuture().recoverWith { case NonFatal(e) =>
|
||||
Future.failed(new DatabaseError(errorContext, e))
|
||||
}
|
||||
}
|
||||
@ -287,10 +287,13 @@ final class DbTriggerDao private (dataSource: DataSource with Closeable, xa: Con
|
||||
|
||||
@throws[IOException]
|
||||
override def close() =
|
||||
destroyPermanently() fold ({
|
||||
case e: IOException => throw e
|
||||
case e => throw new IOException(e)
|
||||
}, identity)
|
||||
destroyPermanently().fold(
|
||||
{
|
||||
case e: IOException => throw e
|
||||
case e => throw new IOException(e)
|
||||
},
|
||||
identity,
|
||||
)
|
||||
}
|
||||
|
||||
object DbTriggerDao {
|
||||
|
@ -85,7 +85,8 @@ trait HttpCookies extends BeforeAndAfterEach { this: Suite =>
|
||||
Http()
|
||||
.singleRequest {
|
||||
if (cookieJar.nonEmpty) {
|
||||
val cookies = headers.Cookie(values = cookieJar.to[Seq]: _*)
|
||||
val hd +: tl = cookieJar.view.map(headers.HttpCookiePair(_)).toSeq
|
||||
val cookies = headers.Cookie(hd, tl: _*)
|
||||
request.addHeader(cookies)
|
||||
} else {
|
||||
request
|
||||
@ -422,7 +423,7 @@ trait TriggerDaoPostgresFixture
|
||||
}
|
||||
|
||||
override protected def afterAll(): Unit = {
|
||||
triggerDao.destroyPermanently() fold (fail(_), identity)
|
||||
triggerDao.destroyPermanently().fold(fail(_), identity)
|
||||
|
||||
super.afterAll()
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ load(
|
||||
"da_scala_binary",
|
||||
"da_scala_library",
|
||||
"da_scala_test",
|
||||
"silencer_plugin",
|
||||
)
|
||||
load(
|
||||
"//bazel_tools/client_server:client_server_test.bzl",
|
||||
@ -78,6 +79,16 @@ da_scala_library(
|
||||
"src/test/scala/com/digitalasset/daml/lf/engine/trigger/test/AbstractFuncTests.scala",
|
||||
"src/test/scala/com/digitalasset/daml/lf/engine/trigger/test/AbstractTriggerTest.scala",
|
||||
],
|
||||
plugins = [silencer_plugin],
|
||||
scala_deps = [
|
||||
"@maven//:com_typesafe_akka_akka_stream",
|
||||
"@maven//:org_scalactic_scalactic",
|
||||
"@maven//:org_scalatest_scalatest",
|
||||
"@maven//:org_scalaz_scalaz_core",
|
||||
],
|
||||
scalacopts = [
|
||||
"-P:silencer:lineContentFilters=import scala.collection.compat",
|
||||
],
|
||||
deps = [
|
||||
"//bazel_tools/runfiles:scala_runfiles",
|
||||
"//daml-lf/archive:daml_lf_archive_reader",
|
||||
@ -103,10 +114,6 @@ da_scala_library(
|
||||
"//libs-scala/ports",
|
||||
"//libs-scala/resources",
|
||||
"//triggers/runner:trigger-runner-lib",
|
||||
"@maven//:com_typesafe_akka_akka_stream_2_12",
|
||||
"@maven//:org_scalactic_scalactic_2_12",
|
||||
"@maven//:org_scalatest_scalatest_2_12",
|
||||
"@maven//:org_scalaz_scalaz_core_2_12",
|
||||
],
|
||||
)
|
||||
|
||||
@ -131,6 +138,12 @@ da_scala_library(
|
||||
"//ledger/test-common/test-certificates",
|
||||
],
|
||||
resources = ["//triggers/runner:src/main/resources/logback.xml"],
|
||||
scala_deps = [
|
||||
"@maven//:com_typesafe_akka_akka_stream",
|
||||
"@maven//:org_scalacheck_scalacheck",
|
||||
"@maven//:org_scalatestplus_scalacheck_1_14",
|
||||
"@maven//:org_scalaz_scalaz_core",
|
||||
],
|
||||
deps = [
|
||||
":test-utils",
|
||||
"//bazel_tools/runfiles:scala_runfiles",
|
||||
@ -158,10 +171,6 @@ da_scala_library(
|
||||
"//libs-scala/resources",
|
||||
"//libs-scala/scalatest-utils",
|
||||
"//triggers/runner:trigger-runner-lib",
|
||||
"@maven//:com_typesafe_akka_akka_stream_2_12",
|
||||
"@maven//:org_scalacheck_scalacheck_2_12",
|
||||
"@maven//:org_scalatestplus_scalacheck_1_14_2_12",
|
||||
"@maven//:org_scalaz_scalaz_core_2_12",
|
||||
],
|
||||
)
|
||||
for lf_version in DAML_LF_VERSIONS
|
||||
|
@ -9,7 +9,6 @@ import com.daml.lf.speedy.SValue
|
||||
import com.daml.lf.speedy.SValue._
|
||||
import com.daml.lf.value.Value.ContractId
|
||||
import com.daml.ledger.api.testing.utils.SuiteResourceManagementAroundAll
|
||||
import com.daml.ledger.api.v1.commands._
|
||||
import com.daml.ledger.api.v1.commands.CreateCommand
|
||||
import com.daml.ledger.api.v1.{value => LedgerApi}
|
||||
import com.daml.platform.services.time.TimeProviderType
|
||||
|
@ -9,7 +9,7 @@ package test
|
||||
import java.util.UUID
|
||||
|
||||
import akka.stream.scaladsl.Sink
|
||||
import com.daml.bazeltools.BazelRunfiles.requiredResource
|
||||
import com.daml.bazeltools.BazelRunfiles
|
||||
import com.daml.ledger.api.refinements.ApiTypes.ApplicationId
|
||||
import com.daml.ledger.api.v1.command_service.SubmitAndWaitRequest
|
||||
import com.daml.ledger.api.v1.commands.{Command, CreateCommand, ExerciseCommand, _}
|
||||
@ -31,6 +31,7 @@ import org.scalatest._
|
||||
import scalaz.syntax.tag._
|
||||
import scalaz.syntax.traverse._
|
||||
|
||||
import scala.collection.compat._
|
||||
import scala.concurrent.{ExecutionContext, Future}
|
||||
import scala.util.Try
|
||||
|
||||
@ -61,18 +62,18 @@ trait AbstractTriggerTest extends SandboxFixture with TestCommands {
|
||||
} yield client
|
||||
|
||||
override protected def darFile =
|
||||
Try(requiredResource("triggers/tests/acs.dar"))
|
||||
.getOrElse(requiredResource("triggers/tests/acs-1.dev.dar"))
|
||||
Try(BazelRunfiles.requiredResource("triggers/tests/acs.dar"))
|
||||
.getOrElse(BazelRunfiles.requiredResource("triggers/tests/acs-1.dev.dar"))
|
||||
|
||||
protected val dar = DarReader().readArchiveFromFile(darFile).get.map { case (pkgId, archive) =>
|
||||
Decode.readArchivePayload(pkgId, archive)
|
||||
}
|
||||
protected val compiledPackages =
|
||||
PureCompiledPackages(dar.all.toMap, speedy.Compiler.Config.Dev).right.get
|
||||
PureCompiledPackages(dar.all.toMap, speedy.Compiler.Config.Dev).toOption.get
|
||||
|
||||
protected def getRunner(client: LedgerClient, name: QualifiedName, party: String): Runner = {
|
||||
val triggerId = Identifier(packageId, name)
|
||||
val trigger = Trigger.fromIdentifier(compiledPackages, triggerId).right.get
|
||||
val trigger = Trigger.fromIdentifier(compiledPackages, triggerId).toOption.get
|
||||
newLoggingContext(label[Trigger], trigger.loggingExtension) { implicit lc =>
|
||||
new Runner(
|
||||
compiledPackages,
|
||||
@ -152,7 +153,9 @@ trait AbstractTriggerTest extends SandboxFixture with TestCommands {
|
||||
contracts
|
||||
.map(created => (created.getTemplateId, created.getCreateArguments))
|
||||
.groupBy(_._1)
|
||||
.view
|
||||
.mapValues(cs => cs.map(_._2))
|
||||
.toMap
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,6 @@ import com.daml.bazeltools.BazelRunfiles._
|
||||
import com.daml.lf.data.Ref._
|
||||
import com.daml.ledger.api.testing.utils.{SuiteResourceManagementAroundAll}
|
||||
import com.daml.ledger.api.tls.TlsConfiguration
|
||||
import com.daml.ledger.api.v1.commands._
|
||||
import com.daml.ledger.api.v1.commands.CreateCommand
|
||||
import com.daml.ledger.api.v1.{value => LedgerApi}
|
||||
import java.io.File
|
||||
|
@ -38,7 +38,7 @@ class UnfoldStateSpec
|
||||
|
||||
"iterator" should {
|
||||
"retract fromLinearSeq and end with unit" in forAll { xs: List[Int] =>
|
||||
fromLinearSeq(xs).iterator().to[List] should ===((xs map \/.right) :+ -\/(()))
|
||||
fromLinearSeq(xs).iterator().toList should ===((xs map \/.right) :+ -\/(()))
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user