mdeuser closed pull request #3187: reduce rule activation records
URL: https://github.com/apache/incubator-openwhisk/pull/3187
This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:
As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):
diff --git
a/core/controller/src/main/scala/whisk/core/controller/Triggers.scala
b/core/controller/src/main/scala/whisk/core/controller/Triggers.scala
index 3893f57a4f..7b6d41f4f9 100644
--- a/core/controller/src/main/scala/whisk/core/controller/Triggers.scala
+++ b/core/controller/src/main/scala/whisk/core/controller/Triggers.scala
@@ -22,6 +22,7 @@ import java.time.{Clock, Instant}
import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport._
+import akka.http.scaladsl.model.ContentTypes
import akka.http.scaladsl.model.HttpMethods.POST
import akka.http.scaladsl.model.StatusCodes._
import akka.http.scaladsl.model.{HttpEntity, HttpRequest, MediaTypes, Uri}
@@ -37,7 +38,9 @@ import whisk.core.database.CacheChangeNotification
import whisk.core.entitlement.Collection
import whisk.core.entity._
import whisk.core.entity.types.{ActivationStore, EntityStore}
+import whisk.http.ErrorResponse
+import scala.collection.immutable.Map
import scala.concurrent.Future
/** A trait implementing the triggers API. */
@@ -63,6 +66,7 @@ trait WhiskTriggersApi extends WhiskCollectionAPI {
/** Path to Triggers REST API. */
protected val triggersPath = "triggers"
+ protected val url = Uri(s"http://localhost:${whiskConfig.servicePort}")
protected implicit val materializer: ActorMaterializer
@@ -107,10 +111,8 @@ trait WhiskTriggersApi extends WhiskCollectionAPI {
entity(as[Option[JsObject]]) { payload =>
getEntity(WhiskTrigger, entityStore, entityName.toDocId, Some {
trigger: WhiskTrigger =>
- val args = trigger.parameters.merge(payload)
val triggerActivationId = activationIdFactory.make()
logging.info(this, s"[POST] trigger activation id:
${triggerActivationId}")
-
val triggerActivation = WhiskActivation(
namespace = user.namespace.toPath, // all activations should end
up in the one space regardless trigger.namespace,
entityName.name,
@@ -122,72 +124,133 @@ trait WhiskTriggersApi extends WhiskCollectionAPI {
version = trigger.version,
duration = None)
- logging.info(this, s"[POST] trigger activated, writing activation
record to datastore: $triggerActivationId")
- WhiskActivation.put(activationStore, triggerActivation) recover {
- case t =>
- logging.error(this, s"[POST] storing trigger activation
$triggerActivationId failed: ${t.getMessage}")
- }
-
- val url = Uri(s"http://localhost:${whiskConfig.servicePort}")
-
- trigger.rules.map {
- _.filter {
- case (ruleName, rule) => rule.status == Status.ACTIVE
- } foreach {
- case (ruleName, rule) =>
- val ruleActivationId = activationIdFactory.make()
- val ruleActivation = WhiskActivation(
- namespace = user.namespace.toPath, // all activations should
end up in the one space regardless trigger.namespace,
- ruleName.name,
- user.subject,
- ruleActivationId,
- Instant.now(Clock.systemUTC()),
- Instant.EPOCH,
- cause = Some(triggerActivationId),
- response = ActivationResponse.success(),
- version = trigger.version,
- duration = None)
- WhiskActivation.put(activationStore, ruleActivation) recover {
- case t =>
- logging.error(this, s"[POST] storing rule activation
$ruleActivationId failed: ${t.getMessage}")
- }
-
- val actionNamespace = rule.action.path.root.asString
- val actionPath = {
- rule.action.path.relativePath.map { pkg =>
- (Path.SingleSlash + pkg.namespace) /
rule.action.name.asString
- } getOrElse {
- Path.SingleSlash + rule.action.name.asString
- }
- }.toString
-
- val actionUrl = Path("/api/v1") / "namespaces" /
actionNamespace / "actions"
- val request = HttpRequest(
- method = POST,
- uri = url.withPath(actionUrl + actionPath),
- headers =
-
List(Authorization(BasicHttpCredentials(user.authkey.uuid.asString,
user.authkey.key.asString))),
- entity = HttpEntity(MediaTypes.`application/json`,
args.getOrElse(JsObject()).compactPrint))
-
- Http().singleRequest(request).map {
- response =>
- response.status match {
- case OK | Accepted =>
- Unmarshal(response.entity).to[JsObject].map { a =>
- logging.info(this, s"${rule.action} activated
${a.fields("activationId")}")
- }
- case NotFound =>
- response.discardEntityBytes()
- logging.info(this, s"${rule.action} failed, action not
found")
- case _ =>
- Unmarshal(response.entity).to[String].map { error =>
- logging.warn(this, s"${rule.action} failed due to
$error")
+ // List of active rules associated with the trigger
+ val activeRules = trigger.rules map { _.filter((r) => r._2.status ==
Status.ACTIVE) } getOrElse Map.empty
+
+ if (activeRules.nonEmpty) {
+ val args = trigger.parameters.merge(payload)
+
+ // Iterate through each active rule; invoking each mapped action
+ val actionLogList = activeRules
+ .map {
+ case (ruleName, rule) =>
+ // Build the url to invoke an action mapped to the rule
+ val actionNamespace = rule.action.path.root.asString
+ val actionPath = {
+ rule.action.path.relativePath.map { pkg =>
+ (Path.SingleSlash + pkg.namespace) /
rule.action.name.asString
+ } getOrElse {
+ Path.SingleSlash + rule.action.name.asString
+ }
+ }.toString
+
+ val actionUrl = Path("/api/v1/namespaces") / actionNamespace
/ "actions"
+ val request = HttpRequest(
+ method = POST,
+ uri = url.withPath(actionUrl + actionPath),
+ headers =
+
List(Authorization(BasicHttpCredentials(user.authkey.uuid.asString,
user.authkey.key.asString))),
+ entity = HttpEntity(MediaTypes.`application/json`,
args.getOrElse(JsObject()).compactPrint))
+
+ // Invoke the action. Retain action results for inclusion in
the trigger activation record
+ Http()
+ .singleRequest(request)
+ .flatMap {
+ response =>
+ response.status match {
+ case OK | Accepted =>
+ Unmarshal(response.entity).to[JsObject].map { a =>
+ logging.info(
+ this,
+ s"trigger-fired action '${rule.action}'
invoked with activation ${a.fields("activationId")}")
+ (ruleName.asString -> ruleResult(
+ ActivationResponse.Success,
+ ruleName.asString,
+ rule.action.asString,
+
Some(a.fields("activationId").replaceAll("^\"|\"$", ""))))
+ }
+ case NotFound =>
+ logging.info(this, s"trigger-fired action
'${rule.action}' not found")
+ Unmarshal(response.entity)
+ .to[ErrorResponse]
+ .map(
+ e =>
+ (ruleName.asString -> ruleResult(
+ ActivationResponse.ApplicationError,
+ ruleName.asString,
+ rule.action.asString,
+ errorMsg = Some(e.error))))
+ case _ =>
+ logging.info(this, s"trigger-fired action
'${rule.action}' response unknown")
+ if (response.entity.contentType ==
ContentTypes.`application/json`) {
+ Unmarshal(response.entity)
+ .to[ErrorResponse]
+ .map(
+ e =>
+ (ruleName.asString -> ruleResult(
+ ActivationResponse.WhiskError,
+ ruleName.asString,
+ rule.action.asString,
+ errorMsg = Some(e.error))))
+ } else {
+ Unmarshal(response.entity).to[String].map {
error =>
+ (ruleName.asString -> ruleResult(
+ ActivationResponse.WhiskError,
+ ruleName.asString,
+ rule.action.asString,
+ errorMsg = Some(error)))
+ }
+ }
}
}
- }
- }
+ .recover {
+ case ex =>
+ logging.error(this, s"trigger-fired action
'${rule.action}' invocation failure: $ex")
+ (ruleName.asString -> ruleResult(
+ ActivationResponse.WhiskError,
+ ruleName.asString,
+ rule.action.asString,
+ errorMsg = Some(ex.toString)))
+ }
+ }
+
+ // To write out activation logs, need to convert the action result
list
+ // of tuples into a vector of strings. Convert
List[Future[(String, JsObject)]] => Future[Vector(String)]
+ val triggerLogs = Future
+ .sequence(actionLogList)
+ .map { tupleList =>
+ tupleList
+ .map {
+ case (ruleName, ruleResultJsObj) =>
ruleResultJsObj.compactPrint
+ }
+ .to[Vector]
+ }
+ .onComplete {
+ case scala.util.Success(triggerLogs) =>
+ logging.info(this, s"Writing action activation results to
trigger activation")
+ val triggerActivationDoc =
triggerActivation.withLogs(ActivationLogs(triggerLogs))
+ logging
+ .info(
+ this,
+ s"[POST] trigger activated, writing activation record to
datastore: $triggerActivationId")
+ WhiskActivation.put(activationStore, triggerActivationDoc)
recover {
+ case t =>
+ logging
+ .error(this, s"[POST] storing trigger activation
$triggerActivationId failed: ${t.getMessage}")
+ }
+ case scala.util.Failure(e) =>
+ logging.error(this, s"Failed to write action activation
results to trigger activation: $e")
+ logging
+ .info(
+ this,
+ s"[POST] trigger activated, writing activation record to
datastore: $triggerActivationId")
+ WhiskActivation.put(activationStore, triggerActivation)
recover {
+ case t =>
+ logging
+ .error(this, s"[POST] storing trigger activation
$triggerActivationId failed: ${t.getMessage}")
+ }
+ }
}
-
complete(Accepted, triggerActivationId.toJsObject)
})
}
@@ -326,6 +389,47 @@ trait WhiskTriggersApi extends WhiskCollectionAPI {
complete(OK, trigger.withoutRules)
}
+ /**
+ * Create JSON object containing the pertinent rule activation details
+ *
+ * @param statusCode
+ * @param ruleName
+ * @param actionName
+ * @param actionActivationId
+ * @param msg
+ * @return
+ */
+ private def ruleResult(statusCode: Int,
+ ruleName: String,
+ actionName: String,
+ actionActivationId: Option[String] = None,
+ errorMsg: Option[String] = None): JsObject = {
+ val objMap: Map[String, JsValue] = Map(
+ "rule" -> JsString(ruleName),
+ "action" -> JsString(actionName),
+ "statusCode" -> JsNumber(statusCode),
+ "success" -> JsBoolean(statusCode == ActivationResponse.Success)) ++ {
+ actionActivationId map { id =>
+ Seq("activationId" -> JsString(id))
+ } getOrElse Seq()
+ } ++ {
+ errorMsg map { err =>
+ Seq("error" -> JsString(err))
+ } getOrElse Seq()
+ }
+
+ // Final rule result looks like
+ // {
+ // "rule": "my-rule",
+ // "action": "my-action",
+ // "statusCode": 0,
+ // "status": "success",
+ // "activationId": "90c84e7b33c84ceb884e7b33c8ecebf6", // Optional
+ // "error": "The requested resource does not exist." // Optional
+ // }
+ JsObject(objMap)
+ }
+
/** Custom unmarshaller for query parameters "limit" for "list" operations.
*/
private implicit val stringToListLimit: Unmarshaller[String, ListLimit] =
RestApiCommons.stringToListLimit(collection)
}
diff --git a/tests/src/test/scala/system/basic/WskBasicTests.scala
b/tests/src/test/scala/system/basic/WskBasicTests.scala
index e51f5f328a..fd7397bb75 100644
--- a/tests/src/test/scala/system/basic/WskBasicTests.scala
+++ b/tests/src/test/scala/system/basic/WskBasicTests.scala
@@ -45,6 +45,11 @@ class WskBasicTests extends TestHelpers with WskTestHelpers {
val wsk = new Wsk
val defaultAction = Some(TestUtils.getTestActionFilename("hello.js"))
+ /**
+ * Append the current timestamp in ms
+ */
+ def withTimestamp(text: String) = s"${text}-${System.currentTimeMillis}"
+
behavior of "Wsk CLI"
it should "reject creating duplicate entity" in withAssetCleaner(wskprops) {
(wp, assetHelper) =>
@@ -464,34 +469,50 @@ class WskBasicTests extends TestHelpers with
WskTestHelpers {
behavior of "Wsk Trigger CLI"
it should "create, update, get, fire and list trigger" in
withAssetCleaner(wskprops) { (wp, assetHelper) =>
- val name = "listTriggers"
+ val ruleName = withTimestamp("r1toa1")
+ val triggerName = withTimestamp("t1tor1")
+ val actionName = withTimestamp("a1")
val params = Map("a" -> "A".toJson)
- assetHelper.withCleaner(wsk.trigger, name) { (trigger, _) =>
- trigger.create(name, parameters = params)
- trigger.create(name, update = true)
+
+ assetHelper.withCleaner(wsk.trigger, triggerName) { (trigger, _) =>
+ trigger.create(triggerName, parameters = params)
+ trigger.create(triggerName, update = true)
+ }
+
+ assetHelper.withCleaner(wsk.action, actionName) { (action, name) =>
+ action.create(name, defaultAction)
}
- val stdout = wsk.trigger.get(name).stdout
+
+ assetHelper.withCleaner(wsk.rule, ruleName) { (rule, name) =>
+ rule.create(name, trigger = triggerName, action = actionName)
+ }
+
+ val stdout = wsk.trigger.get(triggerName).stdout
stdout should include regex (""""key": "a"""")
stdout should include regex (""""value": "A"""")
stdout should include regex (""""publish": false""")
stdout should include regex (""""version": "0.0.2"""")
val dynamicParams = Map("t" -> "T".toJson)
- val run = wsk.trigger.fire(name, dynamicParams)
+ val run = wsk.trigger.fire(triggerName, dynamicParams)
withActivation(wsk.activation, run) { activation =>
activation.response.result shouldBe Some(dynamicParams.toJson)
activation.duration shouldBe 0L // shouldn't exist but CLI generates it
activation.end shouldBe Instant.EPOCH // shouldn't exist but CLI
generates it
+ activation.logs shouldBe defined
+ val logs = activation.logs.get.toString
+ logs should include("activationId")
+ logs should include(""""statusCode":0""")
}
- val runWithNoParams = wsk.trigger.fire(name, Map())
+ val runWithNoParams = wsk.trigger.fire(triggerName, Map())
withActivation(wsk.activation, runWithNoParams) { activation =>
activation.response.result shouldBe Some(JsObject())
activation.duration shouldBe 0L // shouldn't exist but CLI generates it
activation.end shouldBe Instant.EPOCH // shouldn't exist but CLI
generates it
}
- wsk.trigger.list().stdout should include(name)
+ wsk.trigger.list().stdout should include(triggerName)
}
it should "create, and get a trigger summary" in withAssetCleaner(wskprops)
{ (wp, assetHelper) =>
@@ -523,17 +544,26 @@ class WskBasicTests extends TestHelpers with
WskTestHelpers {
}
it should "create, and fire a trigger using a parameter file" in
withAssetCleaner(wskprops) {
- val name = "paramFileTrigger"
- val file = Some(TestUtils.getTestActionFilename("argCheck.js"))
+ val ruleName = withTimestamp("r1toa1")
+ val triggerName = withTimestamp("paramFileTrigger")
+ val actionName = withTimestamp("a1")
val argInput = Some(TestUtils.getTestActionFilename("validInput2.json"))
(wp, assetHelper) =>
- assetHelper.withCleaner(wsk.trigger, name) { (trigger, _) =>
- trigger.create(name)
+ assetHelper.withCleaner(wsk.trigger, triggerName) { (trigger, _) =>
+ trigger.create(triggerName)
+ }
+
+ assetHelper.withCleaner(wsk.action, actionName) { (action, name) =>
+ action.create(name, defaultAction)
+ }
+
+ assetHelper.withCleaner(wsk.rule, ruleName) { (rule, name) =>
+ rule.create(name, trigger = triggerName, action = actionName)
}
val expectedOutput = JsObject("payload" -> JsString("test"))
- val run = wsk.trigger.fire(name, parameterFile = argInput)
+ val run = wsk.trigger.fire(triggerName, parameterFile = argInput)
withActivation(wsk.activation, run) { activation =>
activation.response.result shouldBe Some(expectedOutput)
}
@@ -568,12 +598,23 @@ class WskBasicTests extends TestHelpers with
WskTestHelpers {
}
it should "create, and fire a trigger to ensure result is empty" in
withAssetCleaner(wskprops) { (wp, assetHelper) =>
- val name = "emptyResultTrigger"
- assetHelper.withCleaner(wsk.trigger, name) { (trigger, _) =>
- trigger.create(name)
+ val ruleName = withTimestamp("r1toa1")
+ val triggerName = withTimestamp("emptyResultTrigger")
+ val actionName = withTimestamp("a1")
+
+ assetHelper.withCleaner(wsk.trigger, triggerName) { (trigger, _) =>
+ trigger.create(triggerName)
+ }
+
+ assetHelper.withCleaner(wsk.action, actionName) { (action, name) =>
+ action.create(name, defaultAction)
}
- val run = wsk.trigger.fire(name)
+ assetHelper.withCleaner(wsk.rule, ruleName) { (rule, name) =>
+ rule.create(name, trigger = triggerName, action = actionName)
+ }
+
+ val run = wsk.trigger.fire(triggerName)
withActivation(wsk.activation, run) { activation =>
activation.response.result shouldBe Some(JsObject())
}
@@ -785,21 +826,31 @@ class WskBasicTests extends TestHelpers with
WskTestHelpers {
it should "create a trigger, and fire a trigger to get its individual fields
from an activation" in withAssetCleaner(
wskprops) { (wp, assetHelper) =>
- val name = "activationFields"
+ val ruleName = withTimestamp("r1toa1")
+ val triggerName = withTimestamp("activationFields")
+ val actionName = withTimestamp("a1")
- assetHelper.withCleaner(wsk.trigger, name) { (trigger, _) =>
- trigger.create(name)
+ assetHelper.withCleaner(wsk.trigger, triggerName) { (trigger, _) =>
+ trigger.create(triggerName)
+ }
+
+ assetHelper.withCleaner(wsk.action, actionName) { (action, name) =>
+ action.create(name, defaultAction)
+ }
+
+ assetHelper.withCleaner(wsk.rule, ruleName) { (rule, name) =>
+ rule.create(name, trigger = triggerName, action = actionName)
}
val ns = s""""${wsk.namespace.whois()}""""
- val run = wsk.trigger.fire(name)
+ val run = wsk.trigger.fire(triggerName)
withActivation(wsk.activation, run) { activation =>
val successMsg = s"ok: got activation ${activation.activationId},
displaying field"
wsk.activation
.get(Some(activation.activationId), fieldFilter = Some("namespace"))
.stdout should include regex (s"""(?i)$successMsg namespace\n$ns""")
wsk.activation.get(Some(activation.activationId), fieldFilter =
Some("name")).stdout should include(
- s"""$successMsg name\n"$name"""")
+ s"""$successMsg name\n"$triggerName"""")
wsk.activation.get(Some(activation.activationId), fieldFilter =
Some("version")).stdout should include(
s"""$successMsg version\n"0.0.1"""")
wsk.activation.get(Some(activation.activationId), fieldFilter =
Some("publish")).stdout should include(
diff --git a/tests/src/test/scala/system/basic/WskRuleTests.scala
b/tests/src/test/scala/system/basic/WskRuleTests.scala
index 2baac6d850..bcb9dea083 100644
--- a/tests/src/test/scala/system/basic/WskRuleTests.scala
+++ b/tests/src/test/scala/system/basic/WskRuleTests.scala
@@ -100,13 +100,11 @@ abstract class WskRuleTests extends TestHelpers with
WskTestHelpers {
withActivation(wsk.activation, run) { triggerActivation =>
triggerActivation.cause shouldBe None
-
- withActivationsFromEntity(
- wsk.activation,
- ruleName,
- since =
Some(triggerActivation.start.minusMillis(activationTimeSkewFactorMs))) {
- _.head.cause shouldBe Some(triggerActivation.activationId)
- }
+ triggerActivation.logs.get.size shouldBe (1)
+ val logs = triggerActivation.logs.get.mkString(" ")
+ logs should include(""""statusCode":0""")
+ logs should include(""""activationId":""")
+ logs should include(""""success":true""")
withActivationsFromEntity(
wsk.activation,
@@ -137,13 +135,11 @@ abstract class WskRuleTests extends TestHelpers with
WskTestHelpers {
withActivation(wsk.activation, run) { triggerActivation =>
triggerActivation.cause shouldBe None
-
- withActivationsFromEntity(
- wsk.activation,
- ruleName,
- since =
Some(triggerActivation.start.minusMillis(activationTimeSkewFactorMs))) {
- _.head.cause shouldBe Some(triggerActivation.activationId)
- }
+ triggerActivation.logs.get.size shouldBe (1)
+ val logs = triggerActivation.logs.get.mkString(" ")
+ logs should include(""""statusCode":0""")
+ logs should include(""""activationId":""")
+ logs should include(""""success":true""")
withActivationsFromEntity(
wsk.activation,
@@ -177,13 +173,11 @@ abstract class WskRuleTests extends TestHelpers with
WskTestHelpers {
withActivation(wsk.activation, run) { triggerActivation =>
triggerActivation.cause shouldBe None
-
- withActivationsFromEntity(
- wsk.activation,
- ruleName,
- since =
Some(triggerActivation.start.minusMillis(activationTimeSkewFactorMs))) {
- _.head.cause shouldBe Some(triggerActivation.activationId)
- }
+ triggerActivation.logs.get.size shouldBe (1)
+ val logs = triggerActivation.logs.get.mkString(" ")
+ logs should include(""""statusCode":0""")
+ logs should include(""""activationId":""")
+ logs should include(""""success":true""")
withActivationsFromEntity(
wsk.activation,
diff --git a/tests/src/test/scala/whisk/core/cli/test/Swift311Tests.scala
b/tests/src/test/scala/whisk/core/cli/test/Swift311Tests.scala
index a00b1ea6e4..1dc19f0cfb 100644
--- a/tests/src/test/scala/whisk/core/cli/test/Swift311Tests.scala
+++ b/tests/src/test/scala/whisk/core/cli/test/Swift311Tests.scala
@@ -37,6 +37,7 @@ class Swift311Tests extends TestHelpers with WskTestHelpers
with Matchers {
val wsk = new WskRest
val expectedDuration = 45 seconds
val activationPollDuration = 60 seconds
+ val defaultJsAction = Some(TestUtils.getTestActionFilename("hello.js"))
lazy val runtimeContainer = "swift:3.1.1"
@@ -116,10 +117,20 @@ class Swift311Tests extends TestHelpers with
WskTestHelpers with Matchers {
it should "allow Swift actions to trigger events" in
withAssetCleaner(wskprops) { (wp, assetHelper) =>
// create a trigger
val triggerName = s"TestTrigger ${System.currentTimeMillis()}"
+ val ruleName = s"TestTriggerRule ${System.currentTimeMillis()}"
+ val ruleActionName = s"TestTriggerAction ${System.currentTimeMillis()}"
assetHelper.withCleaner(wsk.trigger, triggerName) { (trigger, _) =>
trigger.create(triggerName)
}
+ assetHelper.withCleaner(wsk.action, ruleActionName) { (action, name) =>
+ action.create(name, defaultJsAction)
+ }
+
+ assetHelper.withCleaner(wsk.rule, ruleName) { (rule, name) =>
+ rule.create(name, trigger = triggerName, action = ruleActionName)
+ }
+
// create an action that fires the trigger
val file = TestUtils.getTestActionFilename("trigger.swift")
val actionName = "ActionThatTriggers"
diff --git
a/tests/src/test/scala/whisk/core/controller/test/TriggersApiTests.scala
b/tests/src/test/scala/whisk/core/controller/test/TriggersApiTests.scala
index 200086f6da..3a8d3cee4f 100644
--- a/tests/src/test/scala/whisk/core/controller/test/TriggersApiTests.scala
+++ b/tests/src/test/scala/whisk/core/controller/test/TriggersApiTests.scala
@@ -64,6 +64,7 @@ class TriggersApiTests extends ControllerTestCommon with
WhiskTriggersApi {
val namespace = EntityPath(creds.subject.asString)
val collectionPath = s"/${EntityPath.DEFAULT}/${collection.path}"
def aname() = MakeName.next("triggers_tests")
+ def afullname(namespace: EntityPath, name: String) =
FullyQualifiedEntityName(namespace, EntityName(name))
val parametersLimit = Parameters.sizeLimit
//// GET /triggers
@@ -319,9 +320,13 @@ class TriggersApiTests extends ControllerTestCommon with
WhiskTriggersApi {
//// POST /triggers/name
it should "fire a trigger" in {
implicit val tid = transid()
- val trigger = WhiskTrigger(namespace, aname(), Parameters("x", "b"))
+ val rule = WhiskRule(namespace, aname(), afullname(namespace,
aname().name), afullname(namespace, "bogus action"))
+ val trigger = WhiskTrigger(namespace, rule.trigger.name, rules = Some {
+ Map(rule.fullyQualifiedName(false) -> ReducedRule(rule.action,
Status.ACTIVE))
+ })
val content = JsObject("xxx" -> "yyy".toJson)
put(entityStore, trigger)
+ put(entityStore, rule)
Post(s"$collectionPath/${trigger.name}", content) ~>
Route.seal(routes(creds)) ~> check {
status should be(Accepted)
val response = responseAs[JsObject]
@@ -342,8 +347,12 @@ class TriggersApiTests extends ControllerTestCommon with
WhiskTriggersApi {
it should "fire a trigger without args" in {
implicit val tid = transid()
- val trigger = WhiskTrigger(namespace, aname(), Parameters("x", "b"))
+ val rule = WhiskRule(namespace, aname(), afullname(namespace,
aname().name), afullname(namespace, "bogus action"))
+ val trigger = WhiskTrigger(namespace, rule.trigger.name, Parameters("x",
"b"), rules = Some {
+ Map(rule.fullyQualifiedName(false) -> ReducedRule(rule.action,
Status.ACTIVE))
+ })
put(entityStore, trigger)
+ put(entityStore, rule)
Post(s"$collectionPath/${trigger.name}") ~> Route.seal(routes(creds)) ~>
check {
val response = responseAs[JsObject]
val JsString(id) = response.fields("activationId")
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
[email protected]
With regards,
Apache Git Services