You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openwhisk.apache.org by cs...@apache.org on 2017/10/31 19:54:53 UTC
[incubator-openwhisk-package-cloudant] branch master updated:
Trigger management (#137)
This is an automated email from the ASF dual-hosted git repository.
csantanapr pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-openwhisk-package-cloudant.git
The following commit(s) were added to refs/heads/master by this push:
new 44e6613 Trigger management (#137)
44e6613 is described below
commit 44e6613301af0d8b80e9341ae0dc726dafb7169f
Author: Adnan Baruni <ab...@users.noreply.github.com>
AuthorDate: Tue Oct 31 14:54:48 2017 -0500
Trigger management (#137)
* implementation of trigger management get status and configuration, tests
* formatting
* remove trailing whitespace
* fix scanCode complaint
* update dateChanged field to millis since epoch to provide consistency
* remove maxTriggers from response, add dateChangedISO to response
---
actions/changes.js | 18 ++-
actions/changesWebAction.js | 56 ++++++-
provider/lib/utils.js | 2 +-
.../scala/system/packages/CloudantFeedTests.scala | 167 ++++++++++++++++++++-
4 files changed, 233 insertions(+), 10 deletions(-)
diff --git a/actions/changes.js b/actions/changes.js
index 7115024..41c03a2 100644
--- a/actions/changes.js
+++ b/actions/changes.js
@@ -2,7 +2,14 @@ var request = require('request');
function main(msg) {
+ let eventMap = {
+ CREATE: 'put',
+ READ: 'get',
+ // UPDATE: 'put',
+ DELETE: 'delete'
+ };
// for creation -> CREATE
+ // for reading -> READ
// for deletion -> DELETE
var lifecycleEvent = msg.lifecycleEvent;
@@ -11,12 +18,11 @@ function main(msg) {
var url = `https://${endpoint}/api/v1/web/whisk.system/cloudantWeb/changesWebAction.http`;
- if (lifecycleEvent !== 'CREATE' && lifecycleEvent !== 'DELETE') {
- return Promise.reject('lifecycleEvent must be CREATE or DELETE');
- }
- else {
- var method = lifecycleEvent === 'CREATE' ? 'put' : 'delete';
+ if (lifecycleEvent in eventMap) {
+ var method = eventMap[lifecycleEvent];
return requestHelper(url, webparams, method);
+ } else {
+ return Promise.reject('unsupported lifecycleEvent');
}
}
@@ -32,7 +38,7 @@ function requestHelper(url, input, method) {
}, function(error, response, body) {
if (!error && response.statusCode === 200) {
- resolve();
+ resolve(body);
}
else {
if (response) {
diff --git a/actions/changesWebAction.js b/actions/changesWebAction.js
index 1899dd3..8a405e2 100644
--- a/actions/changesWebAction.js
+++ b/actions/changesWebAction.js
@@ -1,4 +1,5 @@
var request = require('request');
+var moment = require('moment');
function main(params) {
@@ -68,7 +69,7 @@ function main(params) {
query_params: query_params,
status: {
'active': true,
- 'dateChanged': new Date().toISOString()
+ 'dateChanged': Date.now()
}
};
@@ -98,6 +99,45 @@ function main(params) {
});
}
+ else if (params.__ow_method === "get") {
+ return new Promise(function (resolve, reject) {
+ verifyTriggerAuth(triggerURL, params.authKey, false)
+ .then(() => {
+ return getTrigger(db, triggerID);
+ })
+ .then(doc => {
+ var body = {
+ config: {
+ name: doc.id.split(':')[2],
+ namespace: doc.id.split(':')[1],
+ host: doc.host,
+ port: doc.port,
+ protocol: doc.protocol,
+ dbname: doc.dbname,
+ username: doc.user,
+ password: doc.pass,
+ since: doc.since,
+ filter: doc.filter,
+ query_params: doc.query_params,
+ },
+ status: {
+ active: doc.status.active,
+ dateChanged: moment(doc.status.dateChanged).utc().valueOf(),
+ dateChangedISO: moment(doc.status.dateChanged).utc().format(),
+ reason: doc.status.reason
+ }
+ };
+ resolve({
+ statusCode: 200,
+ headers: {'Content-Type': 'application/json'},
+ body: new Buffer(JSON.stringify(body)).toString('base64')
+ });
+ })
+ .catch(err => {
+ reject(err);
+ });
+ });
+ }
else if (params.__ow_method === "delete") {
return new Promise(function (resolve, reject) {
@@ -178,6 +218,20 @@ function createTrigger(triggerDB, triggerID, newTrigger) {
});
}
+function getTrigger(triggerDB, triggerID) {
+
+ return new Promise(function(resolve, reject) {
+
+ triggerDB.get(triggerID, function (err, existing) {
+ if (err) {
+ reject(err);
+ } else {
+ resolve(existing);
+ }
+ });
+ });
+}
+
function updateTrigger(triggerDB, triggerID, retryCount) {
return new Promise(function(resolve, reject) {
diff --git a/provider/lib/utils.js b/provider/lib/utils.js
index ea6d906..f22909b 100644
--- a/provider/lib/utils.js
+++ b/provider/lib/utils.js
@@ -133,7 +133,7 @@ module.exports = function(
var updatedTrigger = existing;
var status = {
'active': false,
- 'dateChanged': new Date().toISOString(),
+ 'dateChanged': Date.now(),
'reason': {'kind': 'AUTO', 'statusCode': statusCode, 'message': message}
};
updatedTrigger.status = status;
diff --git a/tests/src/test/scala/system/packages/CloudantFeedTests.scala b/tests/src/test/scala/system/packages/CloudantFeedTests.scala
index 3ed99cd..ef6ba84 100644
--- a/tests/src/test/scala/system/packages/CloudantFeedTests.scala
+++ b/tests/src/test/scala/system/packages/CloudantFeedTests.scala
@@ -19,9 +19,9 @@ package system.packages
import common.TestUtils.ANY_ERROR_EXIT
import common._
import org.junit.runner.RunWith
-import org.scalatest.FlatSpec
+import org.scalatest.{FlatSpec, Inside}
import org.scalatest.junit.JUnitRunner
-import spray.json.DefaultJsonProtocol.{IntJsonFormat, StringJsonFormat}
+import spray.json.DefaultJsonProtocol.{IntJsonFormat, StringJsonFormat, BooleanJsonFormat}
import spray.json.{JsObject, JsString, pimpAny}
import system.CloudantUtil
@@ -32,6 +32,7 @@ import system.CloudantUtil
class CloudantFeedTests
extends FlatSpec
with TestHelpers
+ with Inside
with WskTestHelpers
with WskActorSystem {
@@ -324,4 +325,166 @@ class CloudantFeedTests
}
}
+ it should "return correct status and configuration" in withAssetCleaner(wskprops) {
+ val currentTime = s"${System.currentTimeMillis}"
+
+ (wp, assetHelper) =>
+ implicit val wskProps = wp
+ val triggerName = s"dummyCloudantTrigger-${System.currentTimeMillis}"
+ val packageName = "dummyCloudantPackage"
+ val feed = "changes"
+
+ try {
+ CloudantUtil.setUp(myCloudantCreds)
+
+ // the package alarms should be there
+ val packageGetResult = wsk.pkg.get("/whisk.system/cloudant")
+ println("fetched package cloudant")
+ packageGetResult.stdout should include("ok")
+
+ // create package binding
+ assetHelper.withCleaner(wsk.pkg, packageName) {
+ (pkg, name) => pkg.bind("/whisk.system/cloudant", name)
+ }
+
+ val username = myCloudantCreds.user
+ val password = myCloudantCreds.password
+ val host = myCloudantCreds.host()
+ val dbName = myCloudantCreds.dbname
+ val port = 443
+ val protocol = "https"
+ val since = "now"
+ val filter = "test_filter/fruit"
+ val queryParams = JsObject("type" -> JsString("tomato"))
+
+ // create whisk stuff
+ val feedCreationResult = assetHelper.withCleaner(wsk.trigger, triggerName, confirmDelete = false) {
+ (trigger, name) =>
+ trigger.create(name, feed = Some(s"$packageName/$feed"), parameters = Map(
+ "username" -> username.toJson,
+ "password" -> password.toJson,
+ "host" -> host.toJson,
+ "dbname" -> dbName.toJson,
+ "filter" -> filter.toJson,
+ "query_params" -> queryParams,
+ "protocol" -> protocol.toJson,
+ "port" -> port.toJson,
+ "since" -> since.toJson
+ ))
+ }
+ feedCreationResult.stdout should include("ok")
+
+ val actionName = s"$packageName/$feed"
+ val run = wsk.action.invoke(actionName, parameters = Map(
+ "triggerName" -> triggerName.toJson,
+ "lifecycleEvent" -> "READ".toJson,
+ "authKey" -> wskProps.authKey.toJson
+ ))
+
+ withActivation(wsk.activation, run) {
+ activation =>
+ activation.response.success shouldBe true
+
+ inside(activation.response.result) {
+ case Some(result) =>
+ val config = result.getFields("config").head.asInstanceOf[JsObject].fields
+ val status = result.getFields("status").head.asInstanceOf[JsObject].fields
+
+ config should contain("name" -> triggerName.toJson)
+ config should contain("username" -> username.toJson)
+ config should contain("password" -> password.toJson)
+ config should contain("dbname" -> dbName.toJson)
+ config should contain("filter" -> filter.toJson)
+ config should contain("query_params" -> queryParams)
+ config should contain("protocol" -> protocol.toJson)
+ config should contain("port" -> port.toJson)
+ config should contain("since" -> since.toJson)
+ config should contain key "namespace"
+
+ status should contain("active" -> true.toJson)
+ status should contain key "dateChanged"
+ status should contain key "dateChangedISO"
+ status should not(contain key "reason")
+ }
+ }
+ } finally {
+ CloudantUtil.unsetUp(myCloudantCreds)
+ }
+
+ }
+
+ it should "not return fields in configuration that are not passed in during trigger create" in withAssetCleaner(wskprops) {
+ val currentTime = s"${System.currentTimeMillis}"
+
+ (wp, assetHelper) =>
+ implicit val wskProps = wp
+ val triggerName = s"dummyCloudantTrigger-${System.currentTimeMillis}"
+ val packageName = "dummyCloudantPackage"
+ val feed = "changes"
+
+ try {
+ CloudantUtil.setUp(myCloudantCreds)
+
+ // the package alarms should be there
+ val packageGetResult = wsk.pkg.get("/whisk.system/cloudant")
+ println("fetched package cloudant")
+ packageGetResult.stdout should include("ok")
+
+ // create package binding
+ assetHelper.withCleaner(wsk.pkg, packageName) {
+ (pkg, name) => pkg.bind("/whisk.system/cloudant", name)
+ }
+
+ val username = myCloudantCreds.user
+ val password = myCloudantCreds.password
+ val host = myCloudantCreds.host()
+ val dbName = myCloudantCreds.dbname
+
+ // create whisk stuff
+ val feedCreationResult = assetHelper.withCleaner(wsk.trigger, triggerName, confirmDelete = false) {
+ (trigger, name) =>
+ trigger.create(name, feed = Some(s"$packageName/$feed"), parameters = Map(
+ "username" -> username.toJson,
+ "password" -> password.toJson,
+ "host" -> host.toJson,
+ "dbname" -> dbName.toJson
+ ))
+ }
+ feedCreationResult.stdout should include("ok")
+
+ val actionName = s"$packageName/$feed"
+ val run = wsk.action.invoke(actionName, parameters = Map(
+ "triggerName" -> triggerName.toJson,
+ "lifecycleEvent" -> "READ".toJson,
+ "authKey" -> wskProps.authKey.toJson
+ ))
+
+ withActivation(wsk.activation, run) {
+ activation =>
+ activation.response.success shouldBe true
+
+ inside(activation.response.result) {
+ case Some(result) =>
+ val config = result.getFields("config").head.asInstanceOf[JsObject].fields
+
+ config should contain key "username"
+ config should contain key "password"
+ config should contain key "host"
+ config should contain key "dbname"
+
+ config should not {
+ contain key "query_params"
+ contain key "filter"
+ contain key "protocol"
+ contain key "since"
+ contain key "port"
+ }
+ }
+ }
+ } finally {
+ CloudantUtil.unsetUp(myCloudantCreds)
+ }
+
+ }
+
}
--
To stop receiving notification emails like this one, please contact
['"commits@openwhisk.apache.org" <co...@openwhisk.apache.org>'].