openwhisk-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From csantan...@apache.org
Subject [incubator-openwhisk-package-alarms] branch master updated: Trigger management (#101)
Date Wed, 01 Nov 2017 14:34:11 GMT
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-alarms.git


The following commit(s) were added to refs/heads/master by this push:
     new e34b0ea  Trigger management (#101)
e34b0ea is described below

commit e34b0eab9ccbe35bb4bf42659f8cf5dd364550e5
Author: Adnan Baruni <abaruni@users.noreply.github.com>
AuthorDate: Wed Nov 1 09:34:09 2017 -0500

    Trigger management (#101)
    
    * initial implementation of trigger management get status and configuration
    
    * add test for get status and configuration
    
    * formatting
    
    * formatting
    
    * remove trailing whitespace
    
    * fix scanCode complaint
    
    * handle namespace of legacy alarms when fetching trigger document
    
    * update dateChanged field to millis since epoch to provide consistency
    
    * remove maxTriggers from response, add dateChangedISO to response
---
 action/alarm.js                                    | 18 ++++--
 action/alarmWebAction.js                           | 63 +++++++++++++++++++-
 provider/lib/utils.js                              |  2 +-
 .../scala/system/packages/AlarmsFeedTests.scala    | 69 +++++++++++++++++++++-
 4 files changed, 140 insertions(+), 12 deletions(-)

diff --git a/action/alarm.js b/action/alarm.js
index cda9aee..a5c217f 100644
--- a/action/alarm.js
+++ b/action/alarm.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/alarmsWeb/alarmWebAction.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/action/alarmWebAction.js b/action/alarmWebAction.js
index 232d82d..31ed6fd 100644
--- a/action/alarmWebAction.js
+++ b/action/alarmWebAction.js
@@ -1,5 +1,6 @@
 var request = require('request');
 var CronJob = require('cron').CronJob;
+var moment = require('moment');
 
 function main(params) {
 
@@ -45,7 +46,7 @@ function main(params) {
             maxTriggers: params.maxTriggers || -1,
             status: {
                 'active': true,
-                'dateChanged': new Date().toISOString()
+                'dateChanged': Date.now()
             }
         };
 
@@ -72,6 +73,38 @@ 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.name,
+                        namespace: doc.namespace,
+                        cron: doc.cron,
+                        payload: doc.payload
+                    },
+                    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) {
@@ -95,7 +128,7 @@ function main(params) {
         });
     }
     else {
-        return sendError(400, 'lifecycleEvent must be CREATE or DELETE');
+        return sendError(400, 'unsupported lifecycleEvent');
     }
 }
 
@@ -152,6 +185,32 @@ function createTrigger(triggerDB, triggerID, newTrigger) {
     });
 }
 
+function getTrigger(triggerDB, triggerID, retry = true) {
+
+    return new Promise(function(resolve, reject) {
+
+        triggerDB.get(triggerID, function (err, existing) {
+            if (err) {
+                if (retry) {
+                    var parts = triggerID.split('/');
+                    var id = parts[0] + '/_/' + parts[2];
+                    getTrigger(triggerDB, id, false)
+                    .then(doc => {
+                        resolve(doc);
+                    })
+                    .catch(err => {
+                        reject(err);
+                    });
+                } else {
+                    reject(sendError(err.statusCode, 'could not find the trigger in the database'));
+                }
+            } 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 5103356..c804cb8 100644
--- a/provider/lib/utils.js
+++ b/provider/lib/utils.js
@@ -170,7 +170,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/AlarmsFeedTests.scala b/tests/src/test/scala/system/packages/AlarmsFeedTests.scala
index c175722..5377287 100644
--- a/tests/src/test/scala/system/packages/AlarmsFeedTests.scala
+++ b/tests/src/test/scala/system/packages/AlarmsFeedTests.scala
@@ -17,16 +17,16 @@
 package system.packages
 
 import org.junit.runner.RunWith
-import org.scalatest.FlatSpec
+import org.scalatest.{FlatSpec, Inside}
 import org.scalatest.junit.JUnitRunner
-
 import common.TestHelpers
 import common.Wsk
 import common.WskProps
 import common.WskTestHelpers
 import spray.json.DefaultJsonProtocol.IntJsonFormat
 import spray.json.DefaultJsonProtocol.StringJsonFormat
-import spray.json.pimpAny
+import spray.json.DefaultJsonProtocol.BooleanJsonFormat
+import spray.json.{JsObject, JsString, pimpAny}
 
 /**
  * Tests for alarms trigger service
@@ -34,6 +34,7 @@ import spray.json.pimpAny
 @RunWith(classOf[JUnitRunner])
 class AlarmsFeedTests
     extends FlatSpec
+    with Inside
     with TestHelpers
     with WskTestHelpers {
 
@@ -100,4 +101,66 @@ class AlarmsFeedTests
         activations should be(3)
     }
 
+    it should "return correct status and configuration" in withAssetCleaner(wskprops) {
+        val currentTime = s"${System.currentTimeMillis}"
+
+        (wp, assetHelper) =>
+            implicit val wskProps = wp
+            val triggerName = s"dummyAlarmsTrigger-${System.currentTimeMillis}"
+            val packageName = "dummyAlarmsPackage"
+
+            // the package alarms should be there
+            val packageGetResult = wsk.pkg.get("/whisk.system/alarms")
+            println("fetched package alarms")
+            packageGetResult.stdout should include("ok")
+
+            // create package binding
+            assetHelper.withCleaner(wsk.pkg, packageName) {
+                (pkg, name) => pkg.bind("/whisk.system/alarms", name)
+            }
+
+            val triggerPayload = JsObject(
+                "test" -> JsString("alarmsTest")
+            )
+            val cronString = "* * * * * *"
+            val maxTriggers = -1
+
+            // create whisk stuff
+            val feedCreationResult = assetHelper.withCleaner(wsk.trigger, triggerName) {
+                (trigger, name) =>
+                    trigger.create(name, feed = Some(s"$packageName/alarm"), parameters =
Map(
+                        "trigger_payload" -> triggerPayload,
+                        "cron" -> cronString.toJson))
+            }
+            feedCreationResult.stdout should include("ok")
+
+            val actionName = s"$packageName/alarm"
+            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("cron" -> cronString.toJson)
+                            config should contain("payload" -> triggerPayload)
+                            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")
+                    }
+            }
+
+    }
 }

-- 
To stop receiving notification emails like this one, please contact
['"commits@openwhisk.apache.org" <commits@openwhisk.apache.org>'].

Mime
View raw message