This is an automated email from the ASF dual-hosted git repository. dubeejw 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 25c8e3c Impose list limit on all entity types. (#3087) 25c8e3c is described below commit 25c8e3c5c109f59093e3bcd8f102a295fea69869 Author: rodric rabbah <rod...@gmail.com> AuthorDate: Wed Jan 10 23:51:41 2018 -0500 Impose list limit on all entity types. (#3087) * Impose list limit on all entity types. --- .../src/main/scala/whisk/http/ErrorResponse.scala | 6 +- .../main/scala/whisk/core/controller/Actions.scala | 21 +++---- .../scala/whisk/core/controller/Activations.scala | 36 ++++++------ .../scala/whisk/core/controller/Packages.scala | 50 +++++++++-------- .../scala/whisk/core/controller/RestAPIs.scala | 21 +++++++ .../main/scala/whisk/core/controller/Rules.scala | 37 ++++++------- .../scala/whisk/core/controller/Triggers.scala | 64 ++++++++-------------- .../scala/whisk/core/entitlement/Collection.scala | 7 ++- .../test/scala/system/basic/WskBasicTests.scala | 7 --- .../whisk/core/cli/test/WskBasicUsageTests.scala | 2 +- .../core/controller/test/ActionsApiTests.scala | 12 ++++ .../core/controller/test/ActivationsApiTests.scala | 20 +++---- .../core/controller/test/PackagesApiTests.scala | 16 ++++-- .../whisk/core/controller/test/RulesApiTests.scala | 17 ++++-- .../core/controller/test/TriggersApiTests.scala | 12 ++++ 15 files changed, 186 insertions(+), 142 deletions(-) diff --git a/common/scala/src/main/scala/whisk/http/ErrorResponse.scala b/common/scala/src/main/scala/whisk/http/ErrorResponse.scala index c6ee4ae..d26ebf3 100644 --- a/common/scala/src/main/scala/whisk/http/ErrorResponse.scala +++ b/common/scala/src/main/scala/whisk/http/ErrorResponse.scala @@ -132,7 +132,11 @@ 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 maxListLimitExceeded(collection: String, value: Int, max: Int) = { + s"The value $value exceeds the allowed limit $max for $collection." + } + def listLimitIsNotAString = s"The API expects the 'limit' value to be an integer but the given value is not." 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/Actions.scala b/core/controller/src/main/scala/whisk/core/controller/Actions.scala index 97489bf..2dd0bbc 100644 --- a/core/controller/src/main/scala/whisk/core/controller/Actions.scala +++ b/core/controller/src/main/scala/whisk/core/controller/Actions.scala @@ -21,9 +21,7 @@ import scala.concurrent.Future import scala.concurrent.duration._ import scala.language.postfixOps import scala.util.{Failure, Success, Try} - import org.apache.kafka.common.errors.RecordTooLargeException - import akka.actor.ActorSystem import akka.http.scaladsl.model.HttpMethod import akka.http.scaladsl.model.StatusCodes._ @@ -32,12 +30,11 @@ import akka.http.scaladsl.server.RouteResult import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport._ import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport.sprayJsonMarshaller import akka.http.scaladsl.unmarshalling._ - import spray.json._ import spray.json.DefaultJsonProtocol._ - import whisk.common.TransactionId import whisk.core.WhiskConfig +import whisk.core.controller.RestApiCommons.ListLimit import whisk.core.controller.actions.PostActionActivation import whisk.core.database.CacheChangeNotification import whisk.core.database.NoDocumentException @@ -331,13 +328,14 @@ trait WhiskActionsApi extends WhiskCollectionAPI with PostActionActivation with // and would require finding all bindings in namespace and // joining the actions explicitly here. val docs = false - parameter('skip ? 0, 'limit ? collection.listLimit, 'count ? false) { (skip, limit, count) => - listEntities { - WhiskAction.listCollectionInNamespace(entityStore, namespace, skip, limit, docs) map { list => - val actions = list.fold((js) => js, (as) => as.map(WhiskAction.serdes.write(_))) - FilterEntityList.filter(actions, excludePrivate) + parameter('skip ? 0, 'limit.as[ListLimit] ? ListLimit(collection.defaultListLimit), 'count ? false) { + (skip, limit, count) => + listEntities { + WhiskAction.listCollectionInNamespace(entityStore, namespace, skip, limit.n, docs) map { list => + val actions = list.fold((js) => js, (as) => as.map(WhiskAction.serdes.write(_))) + FilterEntityList.filter(actions, excludePrivate) + } } - } } } @@ -682,6 +680,9 @@ trait WhiskActionsApi extends WhiskCollectionAPI with PostActionActivation with } } } + + /** Custom unmarshaller for query parameters "limit" for "list" operations. */ + private implicit val stringToListLimit: Unmarshaller[String, ListLimit] = RestApiCommons.stringToListLimit(collection) } private case class TooManyActionsInSequence() extends IllegalArgumentException 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 c51e00a..c136eb2 100644 --- a/core/controller/src/main/scala/whisk/core/controller/Activations.scala +++ b/core/controller/src/main/scala/whisk/core/controller/Activations.scala @@ -19,30 +19,27 @@ package whisk.core.controller import java.time.Instant +import scala.concurrent.Future import scala.language.postfixOps -import scala.util.Failure -import scala.util.Success -import scala.util.Try +import scala.util.{Failure, Success, Try} import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport.sprayJsonMarshaller import akka.http.scaladsl.model.StatusCodes.BadRequest import akka.http.scaladsl.server.Directives import akka.http.scaladsl.unmarshalling._ -import scala.concurrent.Future import spray.json._ import spray.json.DefaultJsonProtocol.RootJsObjectFormat -import spray.json.DeserializationException import whisk.common.TransactionId import whisk.core.containerpool.logging.LogStore +import whisk.core.controller.RestApiCommons.ListLimit import whisk.core.database.StaleParameter -import whisk.core.entitlement.{Collection, Privilege, Resource} import whisk.core.entitlement.Privilege.READ +import whisk.core.entitlement.{Collection, Privilege, Resource} import whisk.core.entity._ import whisk.core.entity.types.ActivationStore import whisk.http.ErrorResponse.terminate import whisk.http.Messages object WhiskActivationsApi { - protected[core] val maxActivationLimit = 200 /** Custom unmarshaller for query parameters "name" into valid package/action name path. */ private implicit val stringToRestrictedEntityPath: Unmarshaller[String, Option[EntityPath]] = @@ -62,6 +59,11 @@ object WhiskActivationsApi { case Failure(t) => throw new IllegalArgumentException(Messages.badEpoch(value)) } } + + /** Custom unmarshaller for query parameters "limit" for "list" operations. */ + private implicit val stringToListLimit: Unmarshaller[String, ListLimit] = + RestApiCommons.stringToListLimit(Collection(Collection.ACTIVATIONS)) + } /** A trait implementing the activations API. */ @@ -139,20 +141,19 @@ trait WhiskActivationsApi extends Directives with AuthenticatedRouteProvider wit private def list(namespace: EntityPath)(implicit transid: TransactionId) = { import WhiskActivationsApi.stringToRestrictedEntityPath import WhiskActivationsApi.stringToInstantDeserializer + import WhiskActivationsApi.stringToListLimit parameter( 'skip ? 0, - 'limit ? collection.listLimit, + 'limit.as[ListLimit] ? ListLimit(collection.defaultListLimit), 'count ? false, 'docs ? false, 'name.as[Option[EntityPath]] ?, 'since.as[Instant] ?, 'upto.as[Instant] ?) { (skip, limit, count, docs, name, since, upto) => val invalidDocs = count && docs - val cappedLimit = if (limit == 0) WhiskActivationsApi.maxActivationLimit else limit - // regardless of limit, cap at maxActivationLimit (200) records, client must paginate - if (!invalidDocs && cappedLimit <= WhiskActivationsApi.maxActivationLimit) { + if (!invalidDocs) { val activations = name.flatten match { case Some(action) => WhiskActivation.listActivationsMatchingName( @@ -160,7 +161,7 @@ trait WhiskActivationsApi extends Directives with AuthenticatedRouteProvider wit namespace, action, skip, - cappedLimit, + limit.n, docs, since, upto, @@ -170,20 +171,15 @@ trait WhiskActivationsApi extends Directives with AuthenticatedRouteProvider wit activationStore, namespace, skip, - cappedLimit, + limit.n, docs, since, upto, StaleParameter.UpdateAfter) } - - listEntities { - activations map (_.fold((js) => js, (wa) => wa.map(_.toExtendedJson))) - } - } else if (invalidDocs) { - terminate(BadRequest, Messages.docsNotAllowedWithCount) + listEntities(activations map (_.fold((js) => js, (wa) => wa.map(_.toExtendedJson)))) } else { - terminate(BadRequest, Messages.maxActivationLimitExceeded(limit, WhiskActivationsApi.maxActivationLimit)) + terminate(BadRequest, Messages.docsNotAllowedWithCount) } } } diff --git a/core/controller/src/main/scala/whisk/core/controller/Packages.scala b/core/controller/src/main/scala/whisk/core/controller/Packages.scala index 74b2d93..a6388b1 100644 --- a/core/controller/src/main/scala/whisk/core/controller/Packages.scala +++ b/core/controller/src/main/scala/whisk/core/controller/Packages.scala @@ -18,20 +18,18 @@ package whisk.core.controller import scala.concurrent.Future -import scala.util.Failure -import scala.util.Success +import scala.util.{Failure, Success} -import akka.http.scaladsl.model.StatusCodes._ import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport._ -import akka.http.scaladsl.server.RequestContext -import akka.http.scaladsl.server.RouteResult +import akka.http.scaladsl.model.StatusCodes._ +import akka.http.scaladsl.server.{RequestContext, RouteResult} +import akka.http.scaladsl.unmarshalling.Unmarshaller import spray.json._ import whisk.common.TransactionId -import whisk.core.database.DocumentTypeMismatchException -import whisk.core.database.CacheChangeNotification -import whisk.core.database.NoDocumentException +import whisk.core.controller.RestApiCommons.ListLimit +import whisk.core.database.{CacheChangeNotification, DocumentTypeMismatchException, NoDocumentException} import whisk.core.entitlement._ import whisk.core.entity._ import whisk.core.entity.types.EntityStore @@ -182,23 +180,24 @@ trait WhiskPackagesApi extends WhiskCollectionAPI with ReferencedEntities { // Actions API for more. val docs = false - parameter('skip ? 0, 'limit ? collection.listLimit, 'count ? false) { (skip, limit, count) => - listEntities { - WhiskPackage.listCollectionInNamespace(entityStore, namespace, skip, limit, docs) map { list => - // any subject is entitled to list packages in any namespace - // however, they shall only observe public packages if the packages - // are not in one of the namespaces the subject is entitled to - val packages = list.fold((js) => js, (ps) => ps.map(WhiskPackage.serdes.write(_))) - - FilterEntityList.filter(packages, excludePrivate, additionalFilter = { - // additionally exclude bindings - _.fields.get(WhiskPackage.bindingFieldName) match { - case Some(JsBoolean(isbinding)) => !isbinding - case _ => false // exclude anything that does not conform - } - }) + parameter('skip ? 0, 'limit.as[ListLimit] ? ListLimit(collection.defaultListLimit), 'count ? false) { + (skip, limit, count) => + listEntities { + WhiskPackage.listCollectionInNamespace(entityStore, namespace, skip, limit.n, docs) map { list => + // any subject is entitled to list packages in any namespace + // however, they shall only observe public packages if the packages + // are not in one of the namespaces the subject is entitled to + val packages = list.fold((js) => js, (ps) => ps.map(WhiskPackage.serdes.write(_))) + + FilterEntityList.filter(packages, excludePrivate, additionalFilter = { + // additionally exclude bindings + _.fields.get(WhiskPackage.bindingFieldName) match { + case Some(JsBoolean(isbinding)) => !isbinding + case _ => false // exclude anything that does not conform + } + }) + } } - } } } @@ -338,4 +337,7 @@ trait WhiskPackagesApi extends WhiskCollectionAPI with ReferencedEntities { } } } + + /** Custom unmarshaller for query parameters "limit" for "list" operations. */ + private implicit val stringToListLimit: Unmarshaller[String, ListLimit] = RestApiCommons.stringToListLimit(collection) } diff --git a/core/controller/src/main/scala/whisk/core/controller/RestAPIs.scala b/core/controller/src/main/scala/whisk/core/controller/RestAPIs.scala index 8015f60..ffcf01b 100644 --- a/core/controller/src/main/scala/whisk/core/controller/RestAPIs.scala +++ b/core/controller/src/main/scala/whisk/core/controller/RestAPIs.scala @@ -19,6 +19,10 @@ package whisk.core.controller import scala.concurrent.ExecutionContext +import scala.util.Failure +import scala.util.Success +import scala.util.Try + import akka.actor.ActorSystem import akka.http.scaladsl.model.StatusCodes._ import akka.http.scaladsl.model.Uri @@ -43,6 +47,7 @@ import whisk.core.entity.ActivationId.ActivationIdGenerator import whisk.core.entity.WhiskAuthStore import whisk.core.entity.types._ import whisk.core.loadBalancer.LoadBalancerService +import whisk.http.Messages /** * Abstract class which provides basic Directives which are used to construct route structures @@ -115,6 +120,22 @@ protected[controller] object RestApiCommons { } } + /** Custom unmarshaller for query parameters "limit" for "list" operations. */ + case class ListLimit(n: Int) + + def stringToListLimit(collection: Collection): Unmarshaller[String, ListLimit] = { + Unmarshaller.strict[String, ListLimit] { value => + Try { value.toInt } match { + case Success(n) if (n == 0) => ListLimit(Collection.MAX_LIST_LIMIT) + case Success(n) if (n > 0 && n <= Collection.MAX_LIST_LIMIT) => ListLimit(n) + case Success(n) => + throw new IllegalArgumentException( + Messages.maxListLimitExceeded(collection.path, n, Collection.MAX_LIST_LIMIT)) + case Failure(t) => throw new IllegalArgumentException(Messages.listLimitIsNotAString) + } + } + } + /** Pretty print JSON response. */ implicit val jsonPrettyResponsePrinter = PrettyPrinter diff --git a/core/controller/src/main/scala/whisk/core/controller/Rules.scala b/core/controller/src/main/scala/whisk/core/controller/Rules.scala index 0964f38..9f4be64 100644 --- a/core/controller/src/main/scala/whisk/core/controller/Rules.scala +++ b/core/controller/src/main/scala/whisk/core/controller/Rules.scala @@ -17,28 +17,23 @@ package whisk.core.controller -import scala.concurrent.Future -import scala.util.Failure -import scala.util.Success - import akka.actor.ActorSystem -import akka.http.scaladsl.model.StatusCodes._ import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport._ +import akka.http.scaladsl.model.StatusCodes._ import akka.http.scaladsl.server.StandardRoute - +import akka.http.scaladsl.unmarshalling.Unmarshaller import spray.json.DeserializationException - import whisk.common.TransactionId -import whisk.core.database.DocumentConflictException -import whisk.core.database.CacheChangeNotification -import whisk.core.database.NoDocumentException +import whisk.core.controller.RestApiCommons.ListLimit +import whisk.core.database.{CacheChangeNotification, DocumentConflictException, NoDocumentException} +import whisk.core.entitlement.{Collection, Privilege, ReferencedEntities} import whisk.core.entity._ import whisk.core.entity.types.EntityStore import whisk.http.ErrorResponse.terminate import whisk.http.Messages._ -import whisk.core.entitlement.Collection -import whisk.core.entitlement.Privilege -import whisk.core.entitlement.ReferencedEntities + +import scala.concurrent.Future +import scala.util.{Failure, Success} /** A trait implementing the rules API */ trait WhiskRulesApi extends WhiskCollectionAPI with ReferencedEntities { @@ -245,13 +240,14 @@ trait WhiskRulesApi extends WhiskCollectionAPI with ReferencedEntities { // offer an option to fetch entities with full docs yet; see comment in // Actions API for more. val docs = false - parameter('skip ? 0, 'limit ? collection.listLimit, 'count ? false) { (skip, limit, count) => - listEntities { - WhiskRule.listCollectionInNamespace(entityStore, namespace, skip, limit, docs) map { list => - val rules = list.fold((js) => js, (rls) => rls.map(WhiskRule.serdes.write(_))) - FilterEntityList.filter(rules, excludePrivate) + parameter('skip ? 0, 'limit.as[ListLimit] ? ListLimit(collection.defaultListLimit), 'count ? false) { + (skip, limit, count) => + listEntities { + WhiskRule.listCollectionInNamespace(entityStore, namespace, skip, limit.n, docs) map { list => + val rules = list.fold((js) => js, (rls) => rls.map(WhiskRule.serdes.write(_))) + FilterEntityList.filter(rules, excludePrivate) + } } - } } } @@ -410,6 +406,9 @@ trait WhiskRulesApi extends WhiskCollectionAPI with ReferencedEntities { implicit val statusSerdes = Status.serdesRestricted entity(as[Status]) } + + /** Custom unmarshaller for query parameters "limit" for "list" operations. */ + private implicit val stringToListLimit: Unmarshaller[String, ListLimit] = RestApiCommons.stringToListLimit(collection) } private case class IgnoredRuleActivation(noop: Boolean) extends Throwable 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 f0fbf52..7cc292d 100644 --- a/core/controller/src/main/scala/whisk/core/controller/Triggers.scala +++ b/core/controller/src/main/scala/whisk/core/controller/Triggers.scala @@ -17,48 +17,28 @@ package whisk.core.controller -import java.time.Clock -import java.time.Instant - -import scala.concurrent.Future +import java.time.{Clock, Instant} import akka.actor.ActorSystem -import akka.stream.ActorMaterializer -import akka.http.scaladsl.model.headers.BasicHttpCredentials -import akka.http.scaladsl.model.HttpRequest -import akka.http.scaladsl.model.StatusCodes._ -import akka.http.scaladsl.model.Uri -import akka.http.scaladsl.model.Uri.Path -import akka.http.scaladsl.server.RouteResult -import akka.http.scaladsl.model.HttpMethods.POST -import akka.http.scaladsl.model.headers.Authorization -import akka.http.scaladsl.model.HttpMethods._ -import akka.http.scaladsl.model.MediaTypes -import akka.http.scaladsl.model.HttpEntity -import akka.http.scaladsl.server.RequestContext import akka.http.scaladsl.Http import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport._ -import akka.http.scaladsl.unmarshalling.Unmarshal - +import akka.http.scaladsl.model.HttpMethods.POST +import akka.http.scaladsl.model.StatusCodes._ +import akka.http.scaladsl.model.{HttpEntity, HttpRequest, MediaTypes, Uri} +import akka.http.scaladsl.model.Uri.Path +import akka.http.scaladsl.model.headers.{Authorization, BasicHttpCredentials} +import akka.http.scaladsl.server.{RequestContext, RouteResult} +import akka.http.scaladsl.unmarshalling.{Unmarshal, Unmarshaller} +import akka.stream.ActorMaterializer import spray.json._ -import spray.json.DefaultJsonProtocol.RootJsObjectFormat - import whisk.common.TransactionId +import whisk.core.controller.RestApiCommons.ListLimit import whisk.core.database.CacheChangeNotification import whisk.core.entitlement.Collection -import whisk.core.entity.ActivationResponse -import whisk.core.entity.EntityPath -import whisk.core.entity.Parameters -import whisk.core.entity.SemVer -import whisk.core.entity.Status -import whisk.core.entity.TriggerLimits -import whisk.core.entity.WhiskActivation -import whisk.core.entity.WhiskTrigger -import whisk.core.entity.WhiskTriggerPut -import whisk.core.entity.types.ActivationStore -import whisk.core.entity.types.EntityStore -import whisk.core.entity.Identity -import whisk.core.entity.FullyQualifiedEntityName +import whisk.core.entity._ +import whisk.core.entity.types.{ActivationStore, EntityStore} + +import scala.concurrent.Future /** A trait implementing the triggers API. */ trait WhiskTriggersApi extends WhiskCollectionAPI { @@ -261,13 +241,14 @@ trait WhiskTriggersApi extends WhiskCollectionAPI { // offer an option to fetch entities with full docs yet; see comment in // Actions API for more. val docs = false - parameter('skip ? 0, 'limit ? collection.listLimit, 'count ? false) { (skip, limit, count) => - listEntities { - WhiskTrigger.listCollectionInNamespace(entityStore, namespace, skip, limit, docs) map { list => - val triggers = list.fold((js) => js, (ts) => ts.map(WhiskTrigger.serdes.write(_))) - FilterEntityList.filter(triggers, excludePrivate) + parameter('skip ? 0, 'limit.as[ListLimit] ? ListLimit(collection.defaultListLimit), 'count ? false) { + (skip, limit, count) => + listEntities { + WhiskTrigger.listCollectionInNamespace(entityStore, namespace, skip, limit.n, docs) map { list => + val triggers = list.fold((js) => js, (ts) => ts.map(WhiskTrigger.serdes.write(_))) + FilterEntityList.filter(triggers, excludePrivate) + } } - } } } @@ -343,4 +324,7 @@ trait WhiskTriggersApi extends WhiskCollectionAPI { private def completeAsTriggerResponse(trigger: WhiskTrigger): RequestContext => Future[RouteResult] = { complete(OK, trigger.withoutRules) } + + /** Custom unmarshaller for query parameters "limit" for "list" operations. */ + private implicit val stringToListLimit: Unmarshaller[String, ListLimit] = RestApiCommons.stringToListLimit(collection) } diff --git a/core/controller/src/main/scala/whisk/core/entitlement/Collection.scala b/core/controller/src/main/scala/whisk/core/entitlement/Collection.scala index 3cd43f0..6bf6403 100644 --- a/core/controller/src/main/scala/whisk/core/entitlement/Collection.scala +++ b/core/controller/src/main/scala/whisk/core/entitlement/Collection.scala @@ -47,7 +47,8 @@ import whisk.core.entity.types.EntityStore * @param activate the privilege for an activate (may be ACTIVATE or REJECT for example) * @param listLimit the default limit on number of entities returned from a collection on a list operation */ -protected[core] case class Collection protected (val path: String, val listLimit: Int = 30) { +protected[core] case class Collection protected (val path: String, + val defaultListLimit: Int = Collection.DEFAULT_LIST_LIMIT) { override def toString = path /** Determines the right to request for the resources and context. */ @@ -109,6 +110,10 @@ protected[core] object Collection { protected[core] def requiredProperties = WhiskEntityStore.requiredProperties + /** Number of records allowed per query. */ + protected[core] val DEFAULT_LIST_LIMIT = 30 + protected[core] val MAX_LIST_LIMIT = 200 + protected[core] val ACTIONS = WhiskAction.collectionName protected[core] val TRIGGERS = WhiskTrigger.collectionName protected[core] val RULES = WhiskRule.collectionName diff --git a/tests/src/test/scala/system/basic/WskBasicTests.scala b/tests/src/test/scala/system/basic/WskBasicTests.scala index d5faee9..e51f5f3 100644 --- a/tests/src/test/scala/system/basic/WskBasicTests.scala +++ b/tests/src/test/scala/system/basic/WskBasicTests.scala @@ -781,13 +781,6 @@ class WskBasicTests extends TestHelpers with WskTestHelpers { wsk.namespace.get(expectedExitCode = SUCCESS_EXIT)(WskProps()).stdout should include("default") } - it should "not list entities with an invalid namespace" in { - val namespace = "fakeNamespace" - val stderr = wsk.namespace.get(Some(s"/${namespace}"), expectedExitCode = FORBIDDEN).stderr - - stderr should include(s"Unable to obtain the list of entities for namespace '${namespace}'") - } - behavior of "Wsk Activation CLI" it should "create a trigger, and fire a trigger to get its individual fields from an activation" in withAssetCleaner( diff --git a/tests/src/test/scala/whisk/core/cli/test/WskBasicUsageTests.scala b/tests/src/test/scala/whisk/core/cli/test/WskBasicUsageTests.scala index 265b22f..eae45c0 100644 --- a/tests/src/test/scala/whisk/core/cli/test/WskBasicUsageTests.scala +++ b/tests/src/test/scala/whisk/core/cli/test/WskBasicUsageTests.scala @@ -1630,7 +1630,7 @@ class WskBasicUsageTests extends TestHelpers with WskTestHelpers { (Seq("activation", "result", "activationID", invalidArg), s"${tooManyArgsMsg}${invalidArg}."), (Seq("activation", "poll", "activationID", invalidArg), s"${tooManyArgsMsg}${invalidArg}. ${optNamespaceMsg}"), (Seq("namespace", "list", invalidArg), s"${tooManyArgsMsg}${invalidArg}. ${noArgsReqMsg}"), - (Seq("namespace", "get", "namespace", invalidArg), s"${tooManyArgsMsg}${invalidArg}. ${optNamespaceMsg}"), + (Seq("namespace", "get", invalidArg), s"${tooManyArgsMsg}${invalidArg}. ${noArgsReqMsg}"), (Seq("package", "create"), s"${tooFewArgsMsg} ${packageNameReqMsg}"), (Seq("package", "create", "packageName", invalidArg), s"${tooManyArgsMsg}${invalidArg}."), (Seq("package", "create", "packageName", "--shared", invalidArg), invalidShared), diff --git a/tests/src/test/scala/whisk/core/controller/test/ActionsApiTests.scala b/tests/src/test/scala/whisk/core/controller/test/ActionsApiTests.scala index ac5558b..6c2dcd1 100644 --- a/tests/src/test/scala/whisk/core/controller/test/ActionsApiTests.scala +++ b/tests/src/test/scala/whisk/core/controller/test/ActionsApiTests.scala @@ -36,6 +36,7 @@ import spray.json.DefaultJsonProtocol._ import whisk.core.controller.WhiskActionsApi import whisk.core.entity._ import whisk.core.entity.size._ +import whisk.core.entitlement.Collection import whisk.http.ErrorResponse import whisk.http.Messages @@ -90,6 +91,17 @@ class ActionsApiTests extends ControllerTestCommon with WhiskActionsApi { } } + it should "reject list when limit is greater than maximum allowed value" in { + implicit val tid = transid() + val exceededMaxLimit = Collection.MAX_LIST_LIMIT + 1 + val response = Get(s"$collectionPath?limit=$exceededMaxLimit") ~> Route.seal(routes(creds)) ~> check { + status should be(BadRequest) + responseAs[String] should include { + Messages.maxListLimitExceeded(Collection.ACTIONS, exceededMaxLimit, Collection.MAX_LIST_LIMIT) + } + } + } + // ?docs disabled ignore should "list action by default namespace with full docs" in { implicit val tid = transid() 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 edda225..d37dae7 100644 --- a/tests/src/test/scala/whisk/core/controller/test/ActivationsApiTests.scala +++ b/tests/src/test/scala/whisk/core/controller/test/ActivationsApiTests.scala @@ -17,24 +17,22 @@ package whisk.core.controller.test -import java.time.Clock -import java.time.Instant - -import org.junit.runner.RunWith -import org.scalatest.junit.JUnitRunner +import java.time.{Clock, Instant} import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport._ import akka.http.scaladsl.model.StatusCodes._ import akka.http.scaladsl.server.Route import akka.stream.ActorMaterializer -import spray.json._ +import org.junit.runner.RunWith +import org.scalatest.junit.JUnitRunner import spray.json.DefaultJsonProtocol._ +import spray.json._ import whisk.core.controller.WhiskActivationsApi import whisk.core.database.ArtifactStoreProvider +import whisk.core.entitlement.Collection import whisk.core.entity._ import whisk.core.entity.size._ -import whisk.http.ErrorResponse -import whisk.http.Messages +import whisk.http.{ErrorResponse, Messages} import whisk.spi.SpiLoader /** @@ -381,11 +379,11 @@ 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 exceededMaxLimit = Collection.MAX_LIST_LIMIT + 1 val response = Get(s"$collectionPath?limit=$exceededMaxLimit") ~> Route.seal(routes(creds)) ~> check { status should be(BadRequest) - responseAs[ErrorResponse].error shouldBe { - Messages.maxActivationLimitExceeded(exceededMaxLimit, WhiskActivationsApi.maxActivationLimit) + responseAs[String] should include { + Messages.maxListLimitExceeded(Collection.ACTIVATIONS, exceededMaxLimit, Collection.MAX_LIST_LIMIT) } } } diff --git a/tests/src/test/scala/whisk/core/controller/test/PackagesApiTests.scala b/tests/src/test/scala/whisk/core/controller/test/PackagesApiTests.scala index 1e4c389..0fd2825 100644 --- a/tests/src/test/scala/whisk/core/controller/test/PackagesApiTests.scala +++ b/tests/src/test/scala/whisk/core/controller/test/PackagesApiTests.scala @@ -18,19 +18,16 @@ package whisk.core.controller.test import scala.language.postfixOps - import org.junit.runner.RunWith import org.scalatest.junit.JUnitRunner - import akka.http.scaladsl.model.StatusCodes._ import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport._ import akka.http.scaladsl.server.Route - import spray.json.DefaultJsonProtocol._ import spray.json._ - import whisk.core.entity._ import whisk.core.controller.WhiskPackagesApi +import whisk.core.entitlement.Collection import whisk.http.ErrorResponse import whisk.http.Messages @@ -136,6 +133,17 @@ class PackagesApiTests extends ControllerTestCommon with WhiskPackagesApi { } } + it should "reject list when limit is greater than maximum allowed value" in { + implicit val tid = transid() + val exceededMaxLimit = Collection.MAX_LIST_LIMIT + 1 + val response = Get(s"$collectionPath?limit=$exceededMaxLimit") ~> Route.seal(routes(creds)) ~> check { + status should be(BadRequest) + responseAs[String] should include { + Messages.maxListLimitExceeded(Collection.PACKAGES, exceededMaxLimit, Collection.MAX_LIST_LIMIT) + } + } + } + ignore should "list all public packages excluding bindings" in { implicit val tid = transid() // create packages and package bindings, set some public and confirm API lists only public packages diff --git a/tests/src/test/scala/whisk/core/controller/test/RulesApiTests.scala b/tests/src/test/scala/whisk/core/controller/test/RulesApiTests.scala index a4c19b8..60804b7 100644 --- a/tests/src/test/scala/whisk/core/controller/test/RulesApiTests.scala +++ b/tests/src/test/scala/whisk/core/controller/test/RulesApiTests.scala @@ -18,21 +18,19 @@ package whisk.core.controller.test import scala.language.postfixOps - import org.junit.runner.RunWith import org.scalatest.junit.JUnitRunner - import akka.http.scaladsl.model.StatusCodes._ import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport._ import akka.http.scaladsl.server.Route - import spray.json.DefaultJsonProtocol._ import spray.json._ - import whisk.core.controller.WhiskRulesApi +import whisk.core.entitlement.Collection import whisk.core.entity._ import whisk.core.entity.test.OldWhiskTrigger import whisk.http.ErrorResponse + import scala.language.postfixOps import whisk.core.entity.test.OldWhiskRule import whisk.http.Messages @@ -99,6 +97,17 @@ class RulesApiTests extends ControllerTestCommon with WhiskRulesApi { } } + it should "reject list when limit is greater than maximum allowed value" in { + implicit val tid = transid() + val exceededMaxLimit = Collection.MAX_LIST_LIMIT + 1 + val response = Get(s"$collectionPath?limit=$exceededMaxLimit") ~> Route.seal(routes(creds)) ~> check { + status should be(BadRequest) + responseAs[String] should include { + Messages.maxListLimitExceeded(Collection.RULES, exceededMaxLimit, Collection.MAX_LIST_LIMIT) + } + } + } + //?docs disabled ignore should "list rules by default namespace with full docs" in { implicit val tid = transid() 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 382d08d..513c05f 100644 --- a/tests/src/test/scala/whisk/core/controller/test/TriggersApiTests.scala +++ b/tests/src/test/scala/whisk/core/controller/test/TriggersApiTests.scala @@ -34,6 +34,7 @@ import spray.json._ import spray.json.DefaultJsonProtocol._ import whisk.core.controller.WhiskTriggersApi +import whisk.core.entitlement.Collection import whisk.core.entity._ import whisk.core.entity.WhiskRule import whisk.core.entity.size._ @@ -99,6 +100,17 @@ class TriggersApiTests extends ControllerTestCommon with WhiskTriggersApi { } } + it should "reject list when limit is greater than maximum allowed value" in { + implicit val tid = transid() + val exceededMaxLimit = Collection.MAX_LIST_LIMIT + 1 + val response = Get(s"$collectionPath?limit=$exceededMaxLimit") ~> Route.seal(routes(creds)) ~> check { + status should be(BadRequest) + responseAs[String] should include { + Messages.maxListLimitExceeded(Collection.TRIGGERS, exceededMaxLimit, Collection.MAX_LIST_LIMIT) + } + } + } + // ?docs disabled ignore should "list triggers by default namespace with full docs" in { implicit val tid = transid() -- To stop receiving notification emails like this one, please contact ['"commits@openwhisk.apache.org" <commits@openwhisk.apache.org>'].