You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openwhisk.apache.org by ra...@apache.org on 2017/06/29 19:04:44 UTC

[incubator-openwhisk] branch master updated: Updates for Max Activation List Limit (#2215)

This is an automated email from the ASF dual-hosted git repository.

rabbah pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-openwhisk.git


The following commit(s) were added to refs/heads/master by this push:
     new 868b29e  Updates for Max Activation List Limit (#2215)
868b29e is described below

commit 868b29ec915b98de9d30cf5514139dc6c24f306d
Author: James Dubee <jw...@us.ibm.com>
AuthorDate: Thu Jun 29 15:04:41 2017 -0400

    Updates for Max Activation List Limit (#2215)
    
    
    Inform users that 200 activations is the maximum limit for the list command when exceeding the limit.
---
 .../src/main/scala/whisk/http/ErrorResponse.scala  |  1 +
 .../scala/whisk/core/controller/Activations.scala  | 35 +++++++++++++++-------
 .../core/controller/test/ActivationsApiTests.scala | 10 +++++++
 tools/cli/go-whisk-cli/commands/activation.go      |  7 +++--
 .../go-whisk-cli/wski18n/resources/en_US.all.json  |  4 +--
 5 files changed, 42 insertions(+), 15 deletions(-)

diff --git a/common/scala/src/main/scala/whisk/http/ErrorResponse.scala b/common/scala/src/main/scala/whisk/http/ErrorResponse.scala
index 09edb60..525fdeb 100644
--- a/common/scala/src/main/scala/whisk/http/ErrorResponse.scala
+++ b/common/scala/src/main/scala/whisk/http/ErrorResponse.scala
@@ -112,6 +112,7 @@ object Messages {
     def entityTooBig(error: SizeError) = {
         s"${error.field} larger than allowed: ${error.is.toBytes} > ${error.allowed.toBytes} bytes."
     }
+    def maxActivationLimitExceeded(value: Int, max: Int) = s"Activation limit of $value exceeds maximum limit of $max."
 
     def truncateLogs(limit: ByteSize) = {
         s"Logs were truncated because the total bytes size exceeds the limit of ${limit.toBytes} bytes."
diff --git a/core/controller/src/main/scala/whisk/core/controller/Activations.scala b/core/controller/src/main/scala/whisk/core/controller/Activations.scala
index 294dfd8..9c46853 100644
--- a/core/controller/src/main/scala/whisk/core/controller/Activations.scala
+++ b/core/controller/src/main/scala/whisk/core/controller/Activations.scala
@@ -31,6 +31,7 @@ import spray.httpx.unmarshalling.MalformedContent
 import spray.routing.Directives
 import spray.json.DefaultJsonProtocol.RootJsObjectFormat
 import spray.json._
+import spray.http.StatusCodes.BadRequest
 
 import whisk.common.TransactionId
 import whisk.core.entitlement.Collection
@@ -40,6 +41,11 @@ import whisk.core.entitlement.Resource
 import whisk.core.entity._
 import whisk.core.entity.types.ActivationStore
 import whisk.http.Messages
+import whisk.http.ErrorResponse.terminate
+
+object WhiskActivationsApi {
+    protected[core] val maxActivationLimit = 200
+}
 
 /** A trait implementing the activations API. */
 trait WhiskActivationsApi
@@ -110,19 +116,26 @@ trait WhiskActivationsApi
     private def list(namespace: EntityPath)(implicit transid: TransactionId) = {
         parameter('skip ? 0, 'limit ? collection.listLimit, 'count ? false, 'docs ? false, 'name.as[EntityName]?, 'since.as[Instant]?, 'upto.as[Instant]?) {
             (skip, limit, count, docs, name, since, upto) =>
-                // regardless of limit, cap at 200 records, client must paginate
-                val cappedLimit = if (limit == 0 || limit > 200) 200 else limit
-                val activations = name match {
-                    case Some(action) =>
-                        WhiskActivation.listCollectionByName(activationStore, namespace, action, skip, cappedLimit, docs, since, upto)
-                    case None =>
-                        WhiskActivation.listCollectionInNamespace(activationStore, namespace, skip, cappedLimit, docs, since, upto)
-                }
+                val cappedLimit = if (limit == 0) WhiskActivationsApi.maxActivationLimit else limit
+
+                // regardless of limit, cap at maxActivationLimit (200) records, client must paginate
+                if (cappedLimit <= WhiskActivationsApi.maxActivationLimit) {
+                    val activations = name match {
+                        case Some(action) =>
+                            WhiskActivation.listCollectionByName(activationStore, namespace, action, skip, cappedLimit, docs, since, upto)
+                        case None =>
+                            WhiskActivation.listCollectionInNamespace(activationStore, namespace, skip, cappedLimit, docs, since, upto)
+                    }
 
-                listEntities {
-                    activations map {
-                        l => if (docs) l.right.get map { _.toExtendedJson } else l.left.get
+                    listEntities {
+                        activations map {
+                            l => if (docs) l.right.get map {
+                                _.toExtendedJson
+                            } else l.left.get
+                        }
                     }
+                } else {
+                    terminate(BadRequest, Messages.maxActivationLimitExceeded(limit, WhiskActivationsApi.maxActivationLimit))
                 }
         }
     }
diff --git a/tests/src/test/scala/whisk/core/controller/test/ActivationsApiTests.scala b/tests/src/test/scala/whisk/core/controller/test/ActivationsApiTests.scala
index d3f7b45..967213c 100644
--- a/tests/src/test/scala/whisk/core/controller/test/ActivationsApiTests.scala
+++ b/tests/src/test/scala/whisk/core/controller/test/ActivationsApiTests.scala
@@ -215,6 +215,16 @@ class ActivationsApiTests extends ControllerTestCommon with WhiskActivationsApi
         }
     }
 
+    it should "reject activation list when limit is greater than maximum allowed value" in {
+        implicit val tid = transid()
+        val exceededMaxLimit = WhiskActivationsApi.maxActivationLimit + 1
+        val response = Get(s"$collectionPath?limit=$exceededMaxLimit") ~> sealRoute(routes(creds)) ~> check {
+            val response = responseAs[String]
+            response should include(Messages.maxActivationLimitExceeded(exceededMaxLimit, WhiskActivationsApi.maxActivationLimit))
+            status should be(BadRequest)
+        }
+    }
+
     it should "reject get activation by namespace and action name when action name is not a valid name" in {
         implicit val tid = transid()
         Get(s"$collectionPath?name=0%20") ~> sealRoute(routes(creds)) ~> check {
diff --git a/tools/cli/go-whisk-cli/commands/activation.go b/tools/cli/go-whisk-cli/commands/activation.go
index de29c11..04762dd 100644
--- a/tools/cli/go-whisk-cli/commands/activation.go
+++ b/tools/cli/go-whisk-cli/commands/activation.go
@@ -34,9 +34,10 @@ import (
 const (
     PollInterval = time.Second * 2
     Delay        = time.Second * 5
+    MAX_ACTIVATION_LIMIT = 200
+    DEFAULT_ACTIVATION_LIMIT = 30
 )
 
-// activationCmd represents the activation command
 var activationCmd = &cobra.Command{
     Use:   "activation",
     Short: wski18n.T("work with activations"),
@@ -76,6 +77,7 @@ var activationListCmd = &cobra.Command{
             Since: flags.activation.since,
             Docs:  flags.common.full,
         }
+
         activations, _, err := client.Activations.List(options)
         if err != nil {
             whisk.Debug(whisk.DbgError, "client.Activations.List() error: %s\n", err)
@@ -331,7 +333,8 @@ var activationPollCmd = &cobra.Command{
 
 func init() {
     activationListCmd.Flags().IntVarP(&flags.common.skip, "skip", "s", 0, wski18n.T("exclude the first `SKIP` number of activations from the result"))
-    activationListCmd.Flags().IntVarP(&flags.common.limit, "limit", "l", 30, wski18n.T("only return `LIMIT` number of activations from the collection"))
+    activationListCmd.Flags().IntVarP(&flags.common.limit, "limit", "l", DEFAULT_ACTIVATION_LIMIT, wski18n.T("only return `LIMIT` number of activations from the collection with a maximum LIMIT of {{.max}} activations",
+        map[string]interface{}{"max": MAX_ACTIVATION_LIMIT}))
     activationListCmd.Flags().BoolVarP(&flags.common.full, "full", "f", false, wski18n.T("include full activation description"))
     activationListCmd.Flags().Int64Var(&flags.activation.upto, "upto", 0, wski18n.T("return activations with timestamps earlier than `UPTO`; measured in milliseconds since Th, 01, Jan 1970"))
     activationListCmd.Flags().Int64Var(&flags.activation.since, "since", 0, wski18n.T("return activations with timestamps later than `SINCE`; measured in milliseconds since Th, 01, Jan 1970"))
diff --git a/tools/cli/go-whisk-cli/wski18n/resources/en_US.all.json b/tools/cli/go-whisk-cli/wski18n/resources/en_US.all.json
index fd27946..7d3a9bd 100644
--- a/tools/cli/go-whisk-cli/wski18n/resources/en_US.all.json
+++ b/tools/cli/go-whisk-cli/wski18n/resources/en_US.all.json
@@ -996,8 +996,8 @@
     "translation": "exclude the first `SKIP` number of activations from the result"
   },
   {
-    "id": "only return `LIMIT` number of activations from the collection",
-    "translation": "only return `LIMIT` number of activations from the collection"
+    "id": "only return `LIMIT` number of activations from the collection with a maximum LIMIT of {{.max}} activations",
+    "translation": "only return `LIMIT` number of activations from the collection with a maximum LIMIT of {{.max}} activations"
   },
   {
     "id": "include full activation description",

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