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 2018/02/28 18:56:13 UTC

[incubator-openwhisk-package-alarms] branch master updated: Add self monitoring support (#131)

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 87e138a  Add self monitoring support (#131)
87e138a is described below

commit 87e138adc4a82ff556dcf26015383ad9101bba7b
Author: Jason Peterson <ja...@us.ibm.com>
AuthorDate: Wed Feb 28 13:56:11 2018 -0500

    Add self monitoring support (#131)
---
 provider/app.js                                    |  10 +-
 provider/lib/active.js                             |   4 +-
 provider/lib/constants.js                          |   4 +-
 provider/lib/cronAlarm.js                          |   3 +-
 provider/lib/dateAlarm.js                          |   3 +-
 provider/lib/health.js                             | 135 ++++++++++++++-
 provider/lib/intervalAlarm.js                      |   3 +-
 provider/lib/sanitizer.js                          |   3 +
 provider/lib/utils.js                              |  60 ++++---
 .../system/redundancy/AlarmsRedundancyTests.scala  | 184 ---------------------
 10 files changed, 196 insertions(+), 213 deletions(-)

diff --git a/provider/app.js b/provider/app.js
index afd880d..d4df969 100755
--- a/provider/app.js
+++ b/provider/app.js
@@ -34,6 +34,8 @@ var dbProtocol = process.env.DB_PROTOCOL;
 var dbPrefix = process.env.DB_PREFIX;
 var databaseName = dbPrefix + constants.TRIGGER_DB_SUFFIX;
 var redisUrl = process.env.REDIS_URL;
+var monitoringAuth = process.env.MONITORING_AUTH;
+var monitoringInterval = process.env.MONITORING_INTERVAL;
 var filterDDName = '_design/' + constants.FILTERS_DESIGN_DOC;
 var viewDDName = '_design/' + constants.VIEWS_DESIGN_DOC;
 
@@ -185,7 +187,7 @@ function init(server) {
     })
     .then(() => {
         var providerRAS = new ProviderRAS();
-        var providerHealth = new ProviderHealth(providerUtils);
+        var providerHealth = new ProviderHealth(logger, providerUtils);
         var providerActivation = new ProviderActivation(logger, providerUtils);
 
         // RAS Endpoint
@@ -198,6 +200,12 @@ function init(server) {
         app.get(providerActivation.endPoint, providerUtils.authorize, providerActivation.active);
 
         providerUtils.initAllTriggers();
+
+        if (monitoringAuth) {
+            setInterval(function () {
+                providerHealth.monitor(monitoringAuth);
+            }, monitoringInterval || constants.MONITOR_INTERVAL);
+        }
     })
     .catch(err => {
         logger.error(method, 'an error occurred creating database:', err);
diff --git a/provider/lib/active.js b/provider/lib/active.js
index b5c7ea1..25a8a6b 100644
--- a/provider/lib/active.js
+++ b/provider/lib/active.js
@@ -3,13 +3,15 @@ module.exports = function(logger, utils) {
   // Active Endpoint
   this.endPoint = '/active';
 
+  var hostMachine = process.env.HOST_MACHINE;
+
   this.active = function(req, res) {
       var method = 'active';
 
       var response = {
           worker: utils.worker,
           host: utils.host,
-          hostMachine: utils.hostMachine,
+          hostMachine: hostMachine,
           active: utils.host === utils.activeHost
       };
 
diff --git a/provider/lib/constants.js b/provider/lib/constants.js
index f5d7915..5352696 100644
--- a/provider/lib/constants.js
+++ b/provider/lib/constants.js
@@ -6,6 +6,7 @@ const REDIS_KEY = 'active';
 const FILTERS_DESIGN_DOC = 'triggerFilters';
 const VIEWS_DESIGN_DOC = 'triggerViews';
 const TRIGGERS_BY_WORKER = 'triggers_by_worker';
+const MONITOR_INTERVAL = 5 * 1000 * 60; //in milliseconds
 
 
 module.exports = {
@@ -16,5 +17,6 @@ module.exports = {
     REDIS_KEY: REDIS_KEY,
     FILTERS_DESIGN_DOC: FILTERS_DESIGN_DOC,
     VIEWS_DESIGN_DOC: VIEWS_DESIGN_DOC,
-    TRIGGERS_BY_WORKER: TRIGGERS_BY_WORKER
+    TRIGGERS_BY_WORKER: TRIGGERS_BY_WORKER,
+    MONITOR_INTERVAL: MONITOR_INTERVAL
 };
diff --git a/provider/lib/cronAlarm.js b/provider/lib/cronAlarm.js
index ff89d39..42d3150 100644
--- a/provider/lib/cronAlarm.js
+++ b/provider/lib/cronAlarm.js
@@ -13,7 +13,8 @@ module.exports = function(logger, newTrigger) {
         payload: newTrigger.payload,
         cron: newTrigger.cron,
         triggerID: newTrigger.triggerID,
-        uri: newTrigger.uri
+        uri: newTrigger.uri,
+        monitor: newTrigger.monitor
     };
 
     this.scheduleAlarm = function(triggerIdentifier, callback) {
diff --git a/provider/lib/dateAlarm.js b/provider/lib/dateAlarm.js
index f505ca2..247ef03 100644
--- a/provider/lib/dateAlarm.js
+++ b/provider/lib/dateAlarm.js
@@ -10,7 +10,8 @@ module.exports = function(logger, newTrigger) {
         date: newTrigger.date,
         deleteAfterFire: newTrigger.deleteAfterFire,
         triggerID: newTrigger.triggerID,
-        uri: newTrigger.uri
+        uri: newTrigger.uri,
+        monitor: newTrigger.monitor
     };
 
     this.scheduleAlarm = function(triggerIdentifier, callback) {
diff --git a/provider/lib/health.js b/provider/lib/health.js
index bbdc01d..9157e82 100644
--- a/provider/lib/health.js
+++ b/provider/lib/health.js
@@ -1,11 +1,18 @@
 var si = require('systeminformation');
 var v8 = require('v8');
+var request = require('request');
+var _ = require('lodash');
 
-module.exports = function(utils) {
+module.exports = function(logger, utils) {
 
     // Health Endpoint
     this.endPoint = '/health';
 
+    var triggerName;
+    var monitorStatus;
+    var alarmTypes = ['interval', 'date', 'cron'];
+    var healthMonitor = this;
+
     // Health Logic
     this.health = function (req, res) {
 
@@ -20,13 +27,13 @@ module.exports = function(utils) {
             si.inetLatency(utils.routerHost)
         ])
         .then(results => {
+            stats.triggerMonitor = monitorStatus;
             stats.memory = results[0];
-            stats.cpu = results[1];
+            stats.cpu = _.omit(results[1], 'cpus');
             stats.disk = results[2];
             stats.network = results[3];
             stats.apiHostLatency = results[4];
             stats.heapStatistics = v8.getHeapStatistics();
-            stats.heapSpaceStatistics =v8.getHeapSpaceStatistics();
             res.send(stats);
         })
         .catch(error => {
@@ -35,4 +42,126 @@ module.exports = function(utils) {
         });
     };
 
+    this.monitor = function(apikey) {
+        var method = 'monitor';
+
+        var auth = apikey.split(':');
+
+        if (triggerName) {
+            monitorStatus = Object.assign({}, utils.monitorStatus);
+            var existingID = `${apikey}/_/${triggerName}`;
+
+            //delete trigger feed from database
+            utils.sanitizer.deleteTriggerFromDB(existingID, 0);
+
+            //delete the trigger
+            var dataTrigger = {
+                uri: utils.uriHost + '/api/v1/namespaces/_/triggers/' + triggerName,
+                triggerID: existingID
+            };
+            utils.sanitizer.deleteTrigger(dataTrigger, auth, 0)
+                .then((info) => {
+                    logger.info(method, existingID, info);
+                })
+                .catch(err => {
+                    logger.error(method, existingID, err);
+                });
+        }
+
+        //create new alarm trigger
+        triggerName = 'alarms_' + utils.worker + utils.host + '_' + Date.now();
+
+        var triggerURL = utils.uriHost + '/api/v1/namespaces/_/triggers/' + triggerName;
+        var triggerID = `${apikey}/_/${triggerName}`;
+        healthMonitor.createTrigger(triggerURL, auth)
+            .then((info) => {
+                logger.info(method, triggerID, info);
+                var newTrigger = healthMonitor.createAlarmTrigger(triggerID, triggerName, apikey);
+                healthMonitor.createTriggerInDB(triggerID, newTrigger);
+            })
+            .catch(err => {
+                logger.error(method, triggerID, err);
+            });
+    };
+
+    this.createAlarmTrigger = function(triggerID, triggerName, apikey) {
+        var method = 'createAlarmTrigger';
+
+        var existingTypeIndex = -1;
+        if (monitorStatus && alarmTypes.indexOf(monitorStatus.triggerType) !== 2) {
+            existingTypeIndex = alarmTypes.indexOf(monitorStatus.triggerType);
+        }
+        var alarmType = alarmTypes[existingTypeIndex + 1];
+
+        //update status monitor object
+        utils.monitorStatus.triggerName = triggerName;
+        utils.monitorStatus.triggerType = alarmType;
+        utils.monitorStatus.triggerStarted = false;
+        utils.monitorStatus.triggerFired = false;
+        utils.monitorStatus.triggerUpdated = false;
+
+        var newTrigger = {
+            apikey: apikey,
+            name: triggerName,
+            namespace: '_',
+            payload: {},
+            maxTriggers: -1,
+            worker: utils.worker,
+            monitor: utils.host
+        };
+
+        var currentDate = Date.now();
+        if (alarmType === 'interval') {
+            newTrigger.minutes = 1;
+            newTrigger.startDate = currentDate + (1000 * 60);
+            newTrigger.stopDate = currentDate + (1000 * 70);
+        }
+        else if (alarmType === 'date') {
+            newTrigger.date = currentDate + (1000 * 60);
+        }
+        else {
+            newTrigger.cron = '* * * * *';
+            newTrigger.stopDate = currentDate + (1000 * 70);
+        }
+
+        return newTrigger;
+    };
+
+    this.createTrigger = function(triggerURL, auth) {
+        var method = 'createTrigger';
+
+        return new Promise(function(resolve, reject) {
+            request({
+                method: 'put',
+                uri: triggerURL,
+                auth: {
+                    user: auth[0],
+                    pass: auth[1]
+                },
+                json: true,
+                body: {}
+            }, function (error, response) {
+                if (error || response.statusCode >= 400) {
+                    reject('monitoring trigger create request failed');
+                }
+                else {
+                    resolve('monitoring trigger create request was successful');
+                }
+            });
+        });
+    };
+
+    this.createTriggerInDB = function(triggerID, newTrigger) {
+        var method = 'createTriggerInDB';
+
+        utils.db.insert(newTrigger, triggerID, function (err) {
+            if (!err) {
+                logger.info(method, triggerID, 'successfully inserted monitoring trigger');
+            }
+            else {
+                logger.error(method, triggerID, err);
+            }
+        });
+    };
+
 };
diff --git a/provider/lib/intervalAlarm.js b/provider/lib/intervalAlarm.js
index 39d1a78..f3f6540 100644
--- a/provider/lib/intervalAlarm.js
+++ b/provider/lib/intervalAlarm.js
@@ -10,7 +10,8 @@ module.exports = function(logger, newTrigger) {
         payload: newTrigger.payload,
         minutes: newTrigger.minutes,
         triggerID: newTrigger.triggerID,
-        uri: newTrigger.uri
+        uri: newTrigger.uri,
+        monitor: newTrigger.monitor
     };
 
     this.scheduleAlarm = function(triggerIdentifier, callback) {
diff --git a/provider/lib/sanitizer.js b/provider/lib/sanitizer.js
index 19bb747..8f8cd26 100644
--- a/provider/lib/sanitizer.js
+++ b/provider/lib/sanitizer.js
@@ -21,6 +21,9 @@ module.exports = function(logger, triggerDB, uriHost) {
                             logger.error(method, triggerID, 'there was an error deleting the trigger from the database');
                         }
                     }
+                    else {
+                        logger.info(method, triggerID, 'trigger was successfully deleted from the database');
+                    }
                 });
             }
             else {
diff --git a/provider/lib/utils.js b/provider/lib/utils.js
index 6402b85..a428a46 100644
--- a/provider/lib/utils.js
+++ b/provider/lib/utils.js
@@ -9,19 +9,19 @@ var Sanitizer = require('./sanitizer');
 
 module.exports = function(logger, triggerDB, redisClient) {
 
-    this.module = 'utils';
     this.triggers = {};
     this.endpointAuth = process.env.ENDPOINT_AUTH;
     this.routerHost = process.env.ROUTER_HOST || 'localhost';
     this.worker = process.env.WORKER || 'worker0';
     this.host = process.env.HOST_INDEX || 'host0';
-    this.hostMachine = process.env.HOST_MACHINE;
     this.activeHost = 'host0'; //default value on init (will be updated for existing redis)
+    this.db = triggerDB;
     this.redisClient = redisClient;
     this.redisHash = triggerDB.config.db + '_' + this.worker;
     this.redisKey = constants.REDIS_KEY;
     this.uriHost ='https://' + this.routerHost + ':443';
     this.sanitizer = new Sanitizer(logger, triggerDB, this.uriHost);
+    this.monitorStatus = {};
 
     var retryDelay = constants.RETRY_DELAY;
     var retryAttempts = constants.RETRY_ATTEMPTS;
@@ -34,14 +34,12 @@ module.exports = function(logger, triggerDB, redisClient) {
         var method = 'createTrigger';
 
         var callback = function onTick() {
-            if (utils.activeHost === utils.host) {
-                var triggerHandle = utils.triggers[triggerIdentifier];
-                if (triggerHandle && (!triggerHandle.maxTriggers || triggerHandle.maxTriggers === -1 || triggerHandle.triggersLeft > 0)) {
-                    try {
-                        utils.fireTrigger(triggerHandle);
-                    } catch (e) {
-                        logger.error(method, 'Exception occurred while firing trigger', triggerIdentifier, e);
-                    }
+            var triggerHandle = utils.triggers[triggerIdentifier];
+            if (triggerHandle && utils.shouldFireTrigger(triggerHandle) && utils.hasTriggersRemaining(triggerHandle)) {
+                try {
+                    utils.fireTrigger(triggerHandle);
+                } catch (e) {
+                    logger.error(method, 'Exception occurred while firing trigger', triggerIdentifier, e);
                 }
             }
         };
@@ -73,11 +71,11 @@ module.exports = function(logger, triggerDB, redisClient) {
         utils.postTrigger(dataTrigger, auth, 0)
         .then(triggerId => {
             logger.info(method, 'Trigger', triggerId, 'was successfully fired');
-            utils.handleExpiredTriggers(dataTrigger);
+            utils.handleFiredTrigger(dataTrigger, dataTrigger.monitor !== undefined);
         })
         .catch(err => {
             logger.error(method, err);
-            utils.handleExpiredTriggers(dataTrigger);
+            utils.handleFiredTrigger(dataTrigger);
         });
     };
 
@@ -149,8 +147,26 @@ module.exports = function(logger, triggerDB, redisClient) {
             [HttpStatus.REQUEST_TIMEOUT, HttpStatus.TOO_MANY_REQUESTS].indexOf(statusCode) === -1);
     };
 
-    this.handleExpiredTriggers = function(dataTrigger) {
-        var method = 'handleExpiredTriggers';
+    this.shouldFireTrigger = function(trigger) {
+        if (!trigger.monitor && utils.activeHost === utils.host) {
+           return true;
+        }
+        else if (trigger.monitor === utils.host) {
+            return true;
+        }
+        return false;
+    };
+
+    this.hasTriggersRemaining = function(trigger) {
+        return !trigger.maxTriggers || trigger.maxTriggers === -1 || trigger.triggersLeft > 0;
+    };
+
+    this.handleFiredTrigger = function(dataTrigger, isMonitorTrigger) {
+        var method = 'handleFiredTrigger';
+
+        if (isMonitorTrigger) {
+            utils.monitorStatus.triggerFired = true;
+        }
 
         var triggerIdentifier = dataTrigger.triggerID;
         if (dataTrigger.date) {
@@ -195,7 +211,6 @@ module.exports = function(logger, triggerDB, redisClient) {
             utils.disableTrigger(triggerIdentifier, undefined, 'Automatically disabled after reaching max triggers');
             logger.warn(method, 'no more triggers left, disabled', triggerIdentifier);
         }
-
     };
 
     this.disableTrigger = function(triggerIdentifier, statusCode, message) {
@@ -286,7 +301,7 @@ module.exports = function(logger, triggerDB, redisClient) {
                                 .then(cachedTrigger => {
                                     utils.triggers[triggerIdentifier] = cachedTrigger;
                                     logger.info(method, triggerIdentifier, 'created successfully');
-                                    if (cachedTrigger.intervalHandle && utils.activeHost === utils.host) {
+                                    if (cachedTrigger.intervalHandle && utils.shouldFireTrigger(cachedTrigger)) {
                                         try {
                                             utils.fireTrigger(cachedTrigger);
                                         } catch (e) {
@@ -328,6 +343,9 @@ module.exports = function(logger, triggerDB, redisClient) {
 
                 if (utils.triggers[triggerIdentifier]) {
                     if (doc.status && doc.status.active === false) {
+                        if (doc.monitor && doc.monitor === utils.host) {
+                            utils.monitorStatus.triggerUpdated = true;
+                        }
                         utils.stopTrigger(triggerIdentifier);
                     }
                 }
@@ -338,7 +356,12 @@ module.exports = function(logger, triggerDB, redisClient) {
                         .then(cachedTrigger => {
                             utils.triggers[triggerIdentifier] = cachedTrigger;
                             logger.info(method, triggerIdentifier, 'created successfully');
-                            if (cachedTrigger.intervalHandle && utils.activeHost === utils.host) {
+
+                            if (doc.monitor && doc.monitor === utils.host) {
+                                utils.monitorStatus.triggerStarted = true;
+                            }
+
+                            if (cachedTrigger.intervalHandle && utils.shouldFireTrigger(cachedTrigger)) {
                                 try {
                                     utils.fireTrigger(cachedTrigger);
                                 } catch (e) {
@@ -370,7 +393,6 @@ module.exports = function(logger, triggerDB, redisClient) {
         var method = 'authorize';
 
         if (utils.endpointAuth) {
-
             if (!req.headers.authorization) {
                 res.set('www-authenticate', 'Basic realm="Private"');
                 res.status(HttpStatus.UNAUTHORIZED);
@@ -390,9 +412,7 @@ module.exports = function(logger, triggerDB, redisClient) {
 
             var uuid = auth[1];
             var key = auth[2];
-
             var endpointAuth = utils.endpointAuth.split(':');
-
             if (endpointAuth[0] === uuid && endpointAuth[1] === key) {
                 next();
             }
diff --git a/tests/src/test/scala/system/redundancy/AlarmsRedundancyTests.scala b/tests/src/test/scala/system/redundancy/AlarmsRedundancyTests.scala
deleted file mode 100644
index 12e626e..0000000
--- a/tests/src/test/scala/system/redundancy/AlarmsRedundancyTests.scala
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package system.redundancy
-
-import com.jayway.restassured.RestAssured
-import com.jayway.restassured.config.SSLConfig
-import common._
-import org.junit.runner.RunWith
-import org.scalatest.junit.JUnitRunner
-import org.scalatest.{BeforeAndAfterAll, FlatSpec, Matchers}
-import spray.json.DefaultJsonProtocol.StringJsonFormat
-import spray.json.{pimpAny, _}
-
-/**
- * These tests verify that an alarms redundancy (master/slave) configuration
- * works as expected.  They will only run properly in an environment with two
- * alarms containers running concurrently and env var HOST_INDEX set to host0 in
- * one container and host1 in the other.  This test also assumes that redis and
- * the active endpoint authorization are configured.  For the auth set the
- * ENDPOINT_AUTH env var in your containers to match the testing.auth property
- * found in your whisk.properties.  To configure redis simply set the REDIS_URL
- * env var in your containers to point to the openwhisk redis container and make
- * sure the container is deployed.  You can run redis.yml to deploy it.
- */
-@RunWith(classOf[JUnitRunner])
-class AlarmsRedundancyTests
-    extends FlatSpec
-    with Matchers
-    with BeforeAndAfterAll
-    with WskTestHelpers {
-
-    val wskprops = WskProps()
-    val wsk = new Wsk
-    var edgeHost = WhiskProperties.getEdgeHost
-    val auth = WhiskProperties.getBasicAuth
-    val user = auth.fst
-    val password = auth.snd
-
-    var endpointPrefix = s"https://$user:$password@$edgeHost/alarmstrigger/worker0/"
-
-    val defaultAction = Some(TestUtils.getTestActionFilename("hello.js"))
-
-    behavior of "Alarms redundancy tests"
-
-    it should "fire alarms trigger before the swap" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            implicit val wskprops = wp // shadow global props and make implicit
-            val triggerName = s"dummyAlarmsTrigger-${System.currentTimeMillis}"
-            val ruleName = s"dummyAlarmsRule-${System.currentTimeMillis}"
-            val actionName = s"dummyAlarmsAction-${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)
-            }
-
-            // create action
-            assetHelper.withCleaner(wsk.action, actionName) { (action, name) =>
-                action.create(name, defaultAction)
-            }
-
-            // create trigger feed
-            assetHelper.withCleaner(wsk.trigger, triggerName) {
-                (trigger, name) =>
-                trigger.create(name, feed = Some(s"$packageName/alarm"), parameters = Map(
-                    "trigger_payload" -> "alarmTest".toJson,
-                    "cron" -> "* * * * * *".toJson))
-            }
-
-            // create rule
-            assetHelper.withCleaner(wsk.rule, ruleName) { (rule, name) =>
-                rule.create(name, trigger = triggerName, action = actionName)
-            }
-
-            println("waiting for triggers")
-            val activations = wsk.activation.pollFor(N = 3, Some(triggerName)).length
-            println(s"Found activation size (should be at least 3): $activations")
-            activations should be >= 3
-    }
-
-
-    it should "perform active swap by setting host0 active=false" in {
-        val endpointURL = endpointPrefix + "0/active?active=false"
-        val expectedResult = "{\"worker\":\"worker0\",\"host\":\"host0\",\"active\":\"swapping\"}".parseJson.asJsObject
-
-        makeGetCallWithExpectedResult(endpointURL, expectedResult)
-    }
-
-    it should "verify active swap by checking for host0 active=false" in {
-        val endpointURL = endpointPrefix + "0/active"
-        val expectedResult = "{\"worker\":\"worker0\",\"host\":\"host0\",\"active\":false}".parseJson.asJsObject
-
-        Thread.sleep(3000)
-        makeGetCallWithExpectedResult(endpointURL, expectedResult)
-    }
-
-    it should "verify active swap by checking for host1 active=true" in {
-        val endpointURL = endpointPrefix + "1/active"
-        val expectedResult = "{\"worker\":\"worker0\",\"host\":\"host1\",\"active\":true}".parseJson.asJsObject
-
-        makeGetCallWithExpectedResult(endpointURL, expectedResult)
-    }
-
-    it should "fire alarms trigger again after the swap" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            implicit val wskprops = wp // shadow global props and make implicit
-            val triggerName = s"dummyAlarmsTrigger-${System.currentTimeMillis}"
-            val ruleName = s"dummyAlarmsRule-${System.currentTimeMillis}"
-            val actionName = s"dummyAlarmsAction-${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)
-            }
-
-            // create action
-            assetHelper.withCleaner(wsk.action, actionName) { (action, name) =>
-                action.create(name, defaultAction)
-            }
-
-            // create trigger feed
-            assetHelper.withCleaner(wsk.trigger, triggerName) {
-                (trigger, name) =>
-                    trigger.create(name, feed = Some(s"$packageName/alarm"), parameters = Map(
-                        "trigger_payload" -> "alarmTest".toJson,
-                        "cron" -> "* * * * * *".toJson))
-            }
-
-            // create rule
-            assetHelper.withCleaner(wsk.rule, ruleName) { (rule, name) =>
-                rule.create(name, trigger = triggerName, action = actionName)
-            }
-
-            println("waiting for triggers")
-            val activations = wsk.activation.pollFor(N = 3, Some(triggerName)).length
-            println(s"Found activation size (should be at least 3): $activations")
-            activations should be >= 3
-    }
-
-    private def makeGetCallWithExpectedResult(endpointURL: String, expectedResult: JsObject) = {
-        val response = RestAssured.
-                given().
-                config(RestAssured.config().sslConfig(new SSLConfig().relaxedHTTPSValidation())).
-                get(endpointURL)
-        assert(response.statusCode() == 200)
-        var result = response.body.asString.parseJson.asJsObject
-        JsObject(result.fields - "hostMachine") shouldBe expectedResult
-    }
-
-    override def afterAll() {
-        //swap back to original configuration
-        RestAssured.
-                given().
-                config(RestAssured.config().sslConfig(new SSLConfig().relaxedHTTPSValidation())).
-                get(endpointPrefix + "0/active?active=true")
-    }
-
-}

-- 
To stop receiving notification emails like this one, please contact
csantanapr@apache.org.