dubeejw closed pull request #2402: Add Configurable Limits to Controller
URL: https://github.com/apache/incubator-openwhisk/pull/2402
This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:
As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):
diff --git a/ansible/environments/local/group_vars/all
b/ansible/environments/local/group_vars/all
index 27b8515c07..e3e96659d5 100755
--- a/ansible/environments/local/group_vars/all
+++ b/ansible/environments/local/group_vars/all
@@ -17,9 +17,13 @@ db_port: "{{ lookup('ini', 'db_port section=db_creds file={{
playbook_dir }}/db_
limits:
actions:
invokes:
- perMinute: 60
+ blockingTimeout: 60
concurrent: 30
concurrentInSystem: 5000
+ perMinute: 60
+ activations:
+ polls:
+ maxRecords: 200
triggers:
fires:
perMinute: 60
diff --git a/ansible/environments/mac/group_vars/all
b/ansible/environments/mac/group_vars/all
index 6d14d1ddb7..6177b96030 100644
--- a/ansible/environments/mac/group_vars/all
+++ b/ansible/environments/mac/group_vars/all
@@ -22,9 +22,13 @@ db_port: "{{ lookup('ini', 'db_port section=db_creds file={{
playbook_dir }}/db_
limits:
actions:
invokes:
- perMinute: 60
+ blockingTimeout: 60
concurrent: 30
concurrentInSystem: 5000
+ perMinute: 60
+ activations:
+ polls:
+ maxRecords: 200
triggers:
fires:
perMinute: 60
diff --git a/ansible/group_vars/all b/ansible/group_vars/all
index 4e42368c7c..d792b0372e 100644
--- a/ansible/group_vars/all
+++ b/ansible/group_vars/all
@@ -78,11 +78,15 @@ runtimesManifest:
defaultLimits:
actions:
invokes:
- perMinute: 120
+ blockingTimeout: 60
concurrent: 100
concurrentInSystem: 5000
+ perMinute: 120
sequence:
maxLength: 50
+ activations:
+ polls:
+ maxRecords: 200
triggers:
fires:
perMinute: 60
diff --git a/ansible/templates/whisk.properties.j2
b/ansible/templates/whisk.properties.j2
index 5ee84f7f4b..32f235e849 100644
--- a/ansible/templates/whisk.properties.j2
+++ b/ansible/templates/whisk.properties.j2
@@ -33,16 +33,20 @@ whisk.api.localhost.name={{ whisk_api_localhost_name |
default(whisk_api_host_na
whisk.api.vanity.subdomain.parts=1
runtimes.manifest={{ runtimesManifest | to_json }}
-defaultLimits.actions.invokes.perMinute={{
defaultLimits.actions.invokes.perMinute }}
+defaultLimits.actions.invokes.blockingTimeout={{
defaultLimits.actions.invokes.blockingTimeout }}
defaultLimits.actions.invokes.concurrent={{
defaultLimits.actions.invokes.concurrent }}
-defaultLimits.triggers.fires.perMinute={{
defaultLimits.triggers.fires.perMinute }}
defaultLimits.actions.invokes.concurrentInSystem={{
defaultLimits.actions.invokes.concurrentInSystem }}
+defaultLimits.actions.invokes.perMinute={{
defaultLimits.actions.invokes.perMinute }}
defaultLimits.actions.sequence.maxLength={{
defaultLimits.actions.sequence.maxLength }}
+defaultLimits.activations.polls.maxRecords={{
defaultLimits.activations.polls.maxRecords }}
+defaultLimits.triggers.fires.perMinute={{
defaultLimits.triggers.fires.perMinute }}
{% if limits is defined %}
-limits.actions.invokes.perMinute={{ limits.actions.invokes.perMinute }}
+limits.actions.invokes.blockingTimeout={{
limits.actions.invokes.blockingTimeout }}
limits.actions.invokes.concurrent={{ limits.actions.invokes.concurrent }}
limits.actions.invokes.concurrentInSystem={{
limits.actions.invokes.concurrentInSystem }}
+limits.actions.invokes.perMinute={{ limits.actions.invokes.perMinute }}
+limits.activations.polls.maxRecords={{ limits.activations.polls.maxRecords }}
limits.triggers.fires.perMinute={{ limits.triggers.fires.perMinute }}
{% endif %}
diff --git a/common/scala/src/main/scala/whisk/core/WhiskConfig.scala
b/common/scala/src/main/scala/whisk/core/WhiskConfig.scala
index 267ad382ee..d39747291c 100644
--- a/common/scala/src/main/scala/whisk/core/WhiskConfig.scala
+++ b/common/scala/src/main/scala/whisk/core/WhiskConfig.scala
@@ -112,11 +112,13 @@ class WhiskConfig(
val runtimesManifest = this(WhiskConfig.runtimesManifest)
- val actionInvokePerMinuteLimit =
this(WhiskConfig.actionInvokePerMinuteDefaultLimit,
WhiskConfig.actionInvokePerMinuteLimit)
+ val actionInvokeBlockingTimeoutLimit =
this(WhiskConfig.actionInvokeBlockingTimeoutDefaultLimit,
WhiskConfig.actionInvokeBlockingTimeoutLimit)
val actionInvokeConcurrentLimit =
this(WhiskConfig.actionInvokeConcurrentDefaultLimit,
WhiskConfig.actionInvokeConcurrentLimit)
- val triggerFirePerMinuteLimit =
this(WhiskConfig.triggerFirePerMinuteDefaultLimit,
WhiskConfig.triggerFirePerMinuteLimit)
val actionInvokeSystemOverloadLimit =
this(WhiskConfig.actionInvokeSystemOverloadDefaultLimit,
WhiskConfig.actionInvokeSystemOverloadLimit)
+ val actionInvokePerMinuteLimit =
this(WhiskConfig.actionInvokePerMinuteDefaultLimit,
WhiskConfig.actionInvokePerMinuteLimit)
val actionSequenceLimit = this(WhiskConfig.actionSequenceDefaultLimit)
+ val activationPollMaxRecordLimit =
this(WhiskConfig.activationPollMaxRecordDefaultLimit,
WhiskConfig.activationPollMaxRecordLimit)
+ val triggerFirePerMinuteLimit =
this(WhiskConfig.triggerFirePerMinuteDefaultLimit,
WhiskConfig.triggerFirePerMinuteLimit)
}
object WhiskConfig {
@@ -275,13 +277,18 @@ object WhiskConfig {
val runtimesManifest = "runtimes.manifest"
- val actionInvokePerMinuteDefaultLimit =
"defaultLimits.actions.invokes.perMinute"
+ val actionInvokeBlockingTimeoutLimit =
"limits.actions.invokes.blockingTimeout"
+ val actionInvokeBlockingTimeoutDefaultLimit =
"defaultLimits.actions.invokes.blockingTimeout"
+ val actionInvokeConcurrentLimit = "limits.actions.invokes.concurrent"
val actionInvokeConcurrentDefaultLimit =
"defaultLimits.actions.invokes.concurrent"
- val actionInvokeSystemOverloadDefaultLimit =
"defaultLimits.actions.invokes.concurrentInSystem"
- val triggerFirePerMinuteDefaultLimit =
"defaultLimits.triggers.fires.perMinute"
- val actionSequenceDefaultLimit = "defaultLimits.actions.sequence.maxLength"
val actionInvokePerMinuteLimit = "limits.actions.invokes.perMinute"
- val actionInvokeConcurrentLimit = "limits.actions.invokes.concurrent"
+ val actionInvokePerMinuteDefaultLimit =
"defaultLimits.actions.invokes.perMinute"
val actionInvokeSystemOverloadLimit =
"limits.actions.invokes.concurrentInSystem"
+ val actionInvokeSystemOverloadDefaultLimit =
"defaultLimits.actions.invokes.concurrentInSystem"
+ val actionSequenceDefaultLimit = "defaultLimits.actions.sequence.maxLength"
+ val activationPollMaxRecordLimit = "limits.activations.polls.maxRecords"
+ val activationPollMaxRecordDefaultLimit =
"defaultLimits.activations.polls.maxRecords"
val triggerFirePerMinuteLimit = "limits.triggers.fires.perMinute"
+ val triggerFirePerMinuteDefaultLimit =
"defaultLimits.triggers.fires.perMinute"
+
}
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 e685bf478a..222d7c7451 100644
--- a/core/controller/src/main/scala/whisk/core/controller/Actions.scala
+++ b/core/controller/src/main/scala/whisk/core/controller/Actions.scala
@@ -54,13 +54,13 @@ import whisk.http.Messages._
* in order to implement the actions API.
*/
object WhiskActionsApi {
- def requiredProperties = Map(WhiskConfig.actionSequenceDefaultLimit ->
null)
+ def requiredProperties = Map(WhiskConfig.actionSequenceDefaultLimit ->
null,
+ WhiskConfig.actionInvokeBlockingTimeoutDefaultLimit -> null)
+
+ def optionalProperties = Set(WhiskConfig.actionInvokeBlockingTimeoutLimit)
/** Grace period after action timeout limit to poll for result. */
protected[core] val blockingInvokeGrace = 5 seconds
-
- /** Max duration to wait for a blocking activation. */
- protected[core] val maxWaitForBlockingActivation = 60 seconds
}
/** A trait implementing the actions API. */
@@ -212,7 +212,7 @@ trait WhiskActionsApi
* - 500 Internal Server Error
*/
override def activate(user: Identity, entityName:
FullyQualifiedEntityName, env: Option[Parameters])(implicit transid:
TransactionId) = {
- parameter('blocking ? false, 'result ? false, 'timeout ?
WhiskActionsApi.maxWaitForBlockingActivation) { (blocking, result,
waitOverride) =>
+ parameter('blocking ? false, 'result ? false, 'timeout ?
actionInvokeBlockingTimeoutLimit) { (blocking, result, waitOverride) =>
entity(as[Option[JsObject]]) { payload =>
getEntity(WhiskAction, entityStore, entityName.toDocId, Some {
act: WhiskAction =>
@@ -625,14 +625,16 @@ trait WhiskActionsApi
/** Max atomic action count allowed for sequences */
private lazy val actionSequenceLimit =
whiskConfig.actionSequenceLimit.toInt
+ lazy val actionInvokeBlockingTimeoutLimit =
whiskConfig.actionInvokeBlockingTimeoutLimit.toInt.seconds
+
/** Custom deserializer for timeout query parameter. */
private implicit val stringToTimeoutDeserializer = new
FromStringDeserializer[FiniteDuration] {
- val max = WhiskActionsApi.maxWaitForBlockingActivation.toMillis
+ val max = actionInvokeBlockingTimeoutLimit.toMillis
def apply(msecs: String): Either[DeserializationError, FiniteDuration]
= {
Try { msecs.toInt } match {
case Success(i) if i > 0 && i <= max => Right(i.milliseconds)
case _ => Left {
-
MalformedContent(Messages.invalidTimeout(WhiskActionsApi.maxWaitForBlockingActivation))
+
MalformedContent(Messages.invalidTimeout(actionInvokeBlockingTimeoutLimit))
}
}
}
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 294dfd80a0..cc3d7baf6e 100644
--- a/core/controller/src/main/scala/whisk/core/controller/Activations.scala
+++ b/core/controller/src/main/scala/whisk/core/controller/Activations.scala
@@ -39,8 +39,15 @@ import whisk.core.entitlement.Privilege.READ
import whisk.core.entitlement.Resource
import whisk.core.entity._
import whisk.core.entity.types.ActivationStore
+import whisk.core.WhiskConfig
import whisk.http.Messages
+object WhiskActivationsApi {
+ def requiredProperties =
Map(WhiskConfig.activationPollMaxRecordDefaultLimit -> null)
+
+ def optionalProperties = Set(WhiskConfig.activationPollMaxRecordLimit)
+}
+
/** A trait implementing the activations API. */
trait WhiskActivationsApi
extends Directives
@@ -63,6 +70,10 @@ trait WhiskActivationsApi
/** Only GET is supported in this API. */
protected override lazy val entityOps = get
+ protected val whiskConfig: WhiskConfig
+
+ private lazy val activationPollMaxRecordLimit =
whiskConfig.activationPollMaxRecordLimit.toInt
+
/** Validated entity name as an ActivationId from the matched path
segment. */
protected override def entityname(n: String) = {
val activationId = Try { ActivationId(n) }
@@ -111,7 +122,7 @@ trait WhiskActivationsApi
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 cappedLimit = if (limit == 0 || limit >
activationPollMaxRecordLimit) activationPollMaxRecordLimit else limit
val activations = name match {
case Some(action) =>
WhiskActivation.listCollectionByName(activationStore,
namespace, action, skip, cappedLimit, docs, since, upto)
diff --git
a/core/controller/src/main/scala/whisk/core/controller/Controller.scala
b/core/controller/src/main/scala/whisk/core/controller/Controller.scala
index f383cd0b3e..383f3424e6 100644
--- a/core/controller/src/main/scala/whisk/core/controller/Controller.scala
+++ b/core/controller/src/main/scala/whisk/core/controller/Controller.scala
@@ -146,8 +146,7 @@ object Controller {
def requiredProperties = Map(WhiskConfig.servicePort -> 8080.toString) ++
ExecManifest.requiredProperties ++
RestApiCommons.requiredProperties ++
- LoadBalancerService.requiredProperties ++
- EntitlementProvider.requiredProperties
+ LoadBalancerService.requiredProperties
def optionalProperties = EntitlementProvider.optionalProperties
@@ -160,7 +159,9 @@ object Controller {
"limits" -> JsObject(
"actions_per_minute" ->
config.actionInvokePerMinuteLimit.toInt.toJson,
"triggers_per_minute" ->
config.triggerFirePerMinuteLimit.toInt.toJson,
- "concurrent_actions" ->
config.actionInvokeConcurrentLimit.toInt.toJson),
+ "concurrent_actions" ->
config.actionInvokeConcurrentLimit.toInt.toJson,
+ "action_blocking_timeout" ->
config.actionInvokeBlockingTimeoutLimit.toInt.toJson,
+ "activation_poll_record_limit" ->
config.activationPollMaxRecordLimit.toInt.toJson),
"runtimes" -> runtimes.toJson)
// akka-style factory to create a Controller object
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 6202868ad3..83f2d9930a 100644
--- a/core/controller/src/main/scala/whisk/core/controller/RestAPIs.scala
+++ b/core/controller/src/main/scala/whisk/core/controller/RestAPIs.scala
@@ -95,7 +95,8 @@ protected[controller] object RestApiCommons {
EntitlementProvider.requiredProperties ++
WhiskActionsApi.requiredProperties ++
Authenticate.requiredProperties ++
- Collection.requiredProperties
+ Collection.requiredProperties ++
+ WhiskActivationsApi.requiredProperties
/**
* The web actions API is available in both v1 and v2.
@@ -273,7 +274,8 @@ protected[controller] class RestAPIVersion(apipath: String,
apiversion: String)(
implicit override val activationStore: ActivationStore,
override val entitlementProvider: EntitlementProvider,
override val executionContext: ExecutionContext,
- override val logging: Logging)
+ override val logging: Logging,
+ override val whiskConfig: WhiskConfig)
extends WhiskActivationsApi
class PackagesApi(
diff --git
a/core/controller/src/main/scala/whisk/core/controller/WebActions.scala
b/core/controller/src/main/scala/whisk/core/controller/WebActions.scala
index 9d30d706f9..e1aa4fddef 100644
--- a/core/controller/src/main/scala/whisk/core/controller/WebActions.scala
+++ b/core/controller/src/main/scala/whisk/core/controller/WebActions.scala
@@ -25,6 +25,7 @@ import scala.concurrent.Future
import scala.util.Failure
import scala.util.Success
import scala.util.Try
+import scala.concurrent.duration._
import WhiskWebActionsApi.MediaExtension
import spray.http._
@@ -43,6 +44,7 @@ import spray.routing.RequestContext
import spray.routing.Route
import spray.http.HttpMethods.{ OPTIONS, GET, DELETE, POST, PUT, HEAD, PATCH }
import whisk.common.TransactionId
+import whisk.core.WhiskConfig
import whisk.core.controller.actions.BlockingInvokeTimeout
import whisk.core.controller.actions.PostActionActivation
import whisk.core.database._
@@ -69,6 +71,10 @@ protected[controller] sealed class WebApiDirectives private
(prefix: String) {
lazy val reservedProperties: Set[String] = Set(method, headers, path,
namespace, query, body)
protected final def fields(f: String) = s"$prefix$f"
+
+ def requiredProperties =
Map(WhiskConfig.actionInvokeBlockingTimeoutDefaultLimit -> null)
+
+ def optionalProperties = Set(WhiskConfig.actionInvokeBlockingTimeoutLimit)
}
// field names for /web with raw-http action
@@ -322,6 +328,8 @@ trait WhiskWebActionsApi
private val allowOrigin = `Access-Control-Allow-Origin`(AllOrigins)
private val allowMethods = `Access-Control-Allow-Methods`(OPTIONS, GET,
DELETE, POST, PUT, HEAD, PATCH)
+ private lazy val actionInvokeBlockingTimeoutLimit =
whiskConfig.actionInvokeBlockingTimeoutLimit.toInt.seconds
+
/** Extracts the HTTP method, headers, query params and unmatched
(remaining) path. */
private val requestMethodParamsAndPath = {
extract { ctx =>
@@ -540,7 +548,7 @@ trait WhiskWebActionsApi
// they will be overwritten
if (isRawHttpAction ||
context.overrides(webApiDirectives.reservedProperties ++
action.immutableParameters).isEmpty) {
val content = context.toActionArgument(onBehalfOf,
isRawHttpAction)
- val waitOverride =
Some(WhiskActionsApi.maxWaitForBlockingActivation)
+ val waitOverride = Some(actionInvokeBlockingTimeoutLimit)
invokeAction(actionOwnerIdentity, action,
Some(JsObject(content)), blocking = true, waitOverride)
} else {
Future.failed(RejectRequest(BadRequest,
Messages.parametersNotAllowed))
diff --git
a/core/controller/src/main/scala/whisk/core/controller/actions/PrimitiveActions.scala
b/core/controller/src/main/scala/whisk/core/controller/actions/PrimitiveActions.scala
index 9f98a71cd6..8e861c800b 100644
---
a/core/controller/src/main/scala/whisk/core/controller/actions/PrimitiveActions.scala
+++
b/core/controller/src/main/scala/whisk/core/controller/actions/PrimitiveActions.scala
@@ -30,7 +30,6 @@ import whisk.common.LoggingMarkers
import whisk.common.TransactionId
import whisk.core.connector.ActivationMessage
import whisk.core.controller.WhiskServices
-import whisk.core.controller.WhiskActionsApi
import whisk.core.database.NoDocumentException
import whisk.core.entity._
import whisk.core.entity.types.ActivationStore
@@ -55,7 +54,7 @@ protected[actions] trait PrimitiveActions {
protected val activationStore: ActivationStore
/** Max duration for active ack. */
- protected val activeAckTimeout =
WhiskActionsApi.maxWaitForBlockingActivation
+ protected val activeAckTimeout =
whiskConfig.actionInvokeBlockingTimeoutLimit.toInt.seconds
/**
* Gets document from datastore to confirm a valid action activation then
posts request to loadbalancer.
diff --git
a/core/controller/src/main/scala/whisk/core/controller/actions/SequenceActions.scala
b/core/controller/src/main/scala/whisk/core/controller/actions/SequenceActions.scala
index 042bc0854f..19329b2ac0 100644
---
a/core/controller/src/main/scala/whisk/core/controller/actions/SequenceActions.scala
+++
b/core/controller/src/main/scala/whisk/core/controller/actions/SequenceActions.scala
@@ -111,7 +111,7 @@ protected[actions] trait SequenceActions {
if (topmost) { // need to deal with blocking and closing connection
if (blocking) {
logging.info(this, s"invoke sequence blocking topmost!")
- val timeout = maxWaitForBlockingActivation +
blockingInvokeGrace
+ val timeout =
whiskConfig.actionInvokeBlockingTimeoutLimit.toInt.seconds + blockingInvokeGrace
// if the future fails with a timeout, the failure is dealt
with at the caller level
futureSeqResult.withTimeout(timeout, new
BlockingInvokeTimeout(seqActivationId))
} else {
diff --git a/tests/src/test/scala/common/WhiskProperties.java
b/tests/src/test/scala/common/WhiskProperties.java
index 3591225f94..6e908c063d 100644
--- a/tests/src/test/scala/common/WhiskProperties.java
+++ b/tests/src/test/scala/common/WhiskProperties.java
@@ -254,10 +254,38 @@ public static int getControllerPort() {
return
Integer.parseInt(whiskProperties.getProperty("controller.host.port"));
}
+ public static int getActionInvokeBlockingTimeout() {
+ return getPropertyLimit("limits.actions.invokes.blockingTimeout",
"defaultLimits.actions.invokes.blockingTimeout");
+ }
+
+ public static int getActionInvokeConcurent() {
+ return getPropertyLimit("limits.actions.invokes.concurrent",
"defaultLimits.actions.invokes.concurrent");
+ }
+
+ public static int getActionInvokeConcurentInSystem() {
+ return getPropertyLimit("limits.actions.invokes.concurrentInSystem",
"defaultLimits.actions.invokes.concurrentInSystem");
+ }
+
public static int getMaxActionInvokesPerMinute() {
- String valStr =
whiskProperties.getProperty("limits.actions.invokes.perMinute");
+ return getPropertyLimit("limits.actions.invokes.perMinute",
"defaultLimits.actions.invokes.perMinute");
+ }
+
+ public static int getActionSequenceMaxLength() {
+ return getPropertyLimit("limits.actions.sequence.maxLength",
"defaultLimits.actions.sequence.maxLength");
+ }
+
+ public static int getActivationPollMaxRecords() {
+ return getPropertyLimit("limits.activations.polls.maxRecords",
"defaultLimits.activations.polls.maxRecords");
+ }
+
+ public static int getTriggerFiresPerMinute() {
+ return getPropertyLimit("limits.triggers.fires.perMinute",
"defaultLimits.triggers.fires.perMinute");
+ }
+
+ private static int getPropertyLimit(String property, String
defaultProperty) {
+ String valStr = whiskProperties.getProperty(property);
if (null == valStr) {
- valStr =
whiskProperties.getProperty("defaultLimits.actions.invokes.perMinute");
+ valStr = whiskProperties.getProperty(defaultProperty);
}
return Integer.parseInt(valStr);
}
diff --git a/tests/src/test/scala/system/rest/ControllerInfo.scala
b/tests/src/test/scala/system/rest/ControllerInfo.scala
new file mode 100644
index 0000000000..5171b27fe9
--- /dev/null
+++ b/tests/src/test/scala/system/rest/ControllerInfo.scala
@@ -0,0 +1,55 @@
+/*
+ * 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.rest
+
+import org.junit.runner.RunWith
+import org.scalatest.FlatSpec
+import org.scalatest.Matchers
+import org.scalatest.junit.JUnitRunner
+
+import com.jayway.restassured.RestAssured
+
+import common.WhiskProperties
+
+import spray.json._
+
+@RunWith(classOf[JUnitRunner])
+class ControllerInfo extends FlatSpec with Matchers with RestUtil {
+
+ it should "get info route from controller" in {
+ val response = RestAssured.given.config(sslconfig).get(getServiceURL)
+
+ response.statusCode shouldBe 200
+ response.body.asString.contains("\"support\":") shouldBe true
+ response.body.asString.contains("\"description\":") shouldBe true
+ response.body.asString.contains("\"runtimes\":") shouldBe true
+ response.body.asString.contains("\"limits\":") shouldBe true
+
+ val limits =
response.body.asString.parseJson.asJsObject.fields("limits").asJsObject
+ val expectedLimits = JsObject(
+ "action_blocking_timeout" ->
JsNumber(WhiskProperties.getActionInvokeBlockingTimeout),
+ "concurrent_actions" ->
JsNumber(WhiskProperties.getActionInvokeConcurent),
+ //"concurrent_actions_in_system" ->
JsNumber(WhiskProperties.getActionInvokeConcurentInSystem),
+ "actions_per_minute" ->
JsNumber(WhiskProperties.getMaxActionInvokesPerMinute),
+ //"action_sequence_max" ->
JsNumber(WhiskProperties.getActionSequenceMaxLength),
+ "activation_poll_record_limit" ->
JsNumber(WhiskProperties.getActivationPollMaxRecords),
+ "triggers_per_minute" ->
JsNumber(WhiskProperties.getTriggerFiresPerMinute))
+
+ limits shouldBe expectedLimits
+ }
+}
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 a41e3287b9..ae22db2a93 100644
--- a/tests/src/test/scala/whisk/core/controller/test/ActionsApiTests.scala
+++ b/tests/src/test/scala/whisk/core/controller/test/ActionsApiTests.scala
@@ -661,12 +661,12 @@ class ActionsApiTests extends ControllerTestCommon with
WhiskActionsApi {
Post(s"$collectionPath/${action.name}?blocking=true&timeout=0") ~>
sealRoute(routes(creds)) ~> check {
status shouldBe BadRequest
- responseAs[String] should
include(Messages.invalidTimeout(WhiskActionsApi.maxWaitForBlockingActivation))
+ responseAs[String] should
include(Messages.invalidTimeout(actionInvokeBlockingTimeoutLimit))
}
Post(s"$collectionPath/${action.name}?blocking=true&timeout=65000") ~>
sealRoute(routes(creds)) ~> check {
status shouldBe BadRequest
- responseAs[String] should
include(Messages.invalidTimeout(WhiskActionsApi.maxWaitForBlockingActivation))
+ responseAs[String] should
include(Messages.invalidTimeout(actionInvokeBlockingTimeoutLimit))
}
// will not wait long enough should get accepted status
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
[email protected]
With regards,
Apache Git Services