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 2017/06/30 19:00:18 UTC

[incubator-openwhisk] branch master updated: Normalize rate checks to the identity namespace (uuid). (#2433)

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.git


The following commit(s) were added to refs/heads/master by this push:
     new 544d065  Normalize rate checks to the identity namespace (uuid). (#2433)
544d065 is described below

commit 544d0657db2a3c3bac11e143f4fecf1b888e5079
Author: rodric rabbah <ro...@gmail.com>
AuthorDate: Fri Jun 30 15:00:16 2017 -0400

    Normalize rate checks to the identity namespace (uuid). (#2433)
---
 .../main/scala/whisk/core/entity/Identity.scala    |  4 ++-
 .../core/entitlement/ActivationThrottler.scala     | 15 +++++-----
 .../scala/whisk/core/entitlement/Entitlement.scala | 32 +++++++++++-----------
 .../whisk/core/entitlement/RateThrottler.scala     | 20 ++++++++------
 .../core/loadBalancer/LoadBalancerService.scala    | 31 +++++++++++----------
 docs/reference.md                                  |  2 +-
 .../whisk/core/cli/test/WskWebActionsTests.scala   | 18 +++++-------
 .../controller/test/ControllerTestCommon.scala     |  2 +-
 .../core/controller/test/RateThrottleTests.scala   |  3 +-
 .../core/controller/test/WebActionsApiTests.scala  |  2 +-
 10 files changed, 66 insertions(+), 63 deletions(-)

diff --git a/common/scala/src/main/scala/whisk/core/entity/Identity.scala b/common/scala/src/main/scala/whisk/core/entity/Identity.scala
index e150653..9fb0ef2 100644
--- a/common/scala/src/main/scala/whisk/core/entity/Identity.scala
+++ b/common/scala/src/main/scala/whisk/core/entity/Identity.scala
@@ -28,7 +28,9 @@ import whisk.core.database.NoDocumentException
 import whisk.core.entitlement.Privilege
 import whisk.core.entitlement.Privilege.Privilege
 
-protected[core] case class Identity(subject: Subject, namespace: EntityName, authkey: AuthKey, rights: Set[Privilege])
+protected[core] case class Identity(subject: Subject, namespace: EntityName, authkey: AuthKey, rights: Set[Privilege]) {
+    def uuid = authkey.uuid
+}
 
 object Identity extends MultipleReadersSingleWriterCache[Identity, DocInfo] with DefaultJsonProtocol {
 
diff --git a/core/controller/src/main/scala/whisk/core/entitlement/ActivationThrottler.scala b/core/controller/src/main/scala/whisk/core/entitlement/ActivationThrottler.scala
index 4ba44e9..a778607 100644
--- a/core/controller/src/main/scala/whisk/core/entitlement/ActivationThrottler.scala
+++ b/core/controller/src/main/scala/whisk/core/entitlement/ActivationThrottler.scala
@@ -24,7 +24,8 @@ import akka.actor.ActorSystem
 import whisk.common.Logging
 import whisk.common.Scheduler
 import whisk.common.TransactionId
-import whisk.core.entity.Subject
+import whisk.core.entity.Identity
+import whisk.core.entity.UUID
 import whisk.core.loadBalancer.LoadBalancer
 
 /**
@@ -48,16 +49,16 @@ class ActivationThrottler(consulServer: String, loadBalancer: LoadBalancer, conc
      * the number of concurrent invocations it has in the system
      */
     @volatile
-    private var userActivationCounter = Map.empty[String, Int]
+    private var namespaceActivationCounter = Map.empty[UUID, Int]
 
     private val healthCheckInterval = 5.seconds
 
     /**
      * Checks whether the operation should be allowed to proceed.
      */
-    def check(subject: Subject)(implicit tid: TransactionId): Boolean = {
-        val concurrentActivations = userActivationCounter.getOrElse(subject.asString, 0)
-        logging.info(this, s"subject = ${subject.toString}, concurrent activations = $concurrentActivations, below limit = $concurrencyLimit")
+    def check(user: Identity)(implicit tid: TransactionId): Boolean = {
+        val concurrentActivations = namespaceActivationCounter.getOrElse(user.uuid, 0)
+        logging.debug(this, s"namespace = ${user.uuid.asString}, concurrent activations = $concurrentActivations, below limit = $concurrencyLimit")
         concurrentActivations < concurrencyLimit
     }
 
@@ -65,13 +66,13 @@ class ActivationThrottler(consulServer: String, loadBalancer: LoadBalancer, conc
      * Checks whether the system is in a generally overloaded state.
      */
     def isOverloaded()(implicit tid: TransactionId): Boolean = {
-        val concurrentActivations = userActivationCounter.values.sum
+        val concurrentActivations = namespaceActivationCounter.values.sum
         logging.info(this, s"concurrent activations in system = $concurrentActivations, below limit = $systemOverloadLimit")
         concurrentActivations > systemOverloadLimit
     }
 
     Scheduler.scheduleWaitAtLeast(healthCheckInterval) { () =>
-        userActivationCounter = loadBalancer.getActiveUserActivationCounts
+        namespaceActivationCounter = loadBalancer.getActiveNamespaceActivationCounts
         Future.successful(Unit)
     }
 }
diff --git a/core/controller/src/main/scala/whisk/core/entitlement/Entitlement.scala b/core/controller/src/main/scala/whisk/core/entitlement/Entitlement.scala
index 6c205b5..ad4fd8f 100644
--- a/core/controller/src/main/scala/whisk/core/entitlement/Entitlement.scala
+++ b/core/controller/src/main/scala/whisk/core/entitlement/Entitlement.scala
@@ -117,20 +117,20 @@ protected[core] abstract class EntitlementProvider(config: WhiskConfig, loadBala
     protected def entitled(subject: Subject, right: Privilege, resource: Resource)(implicit transid: TransactionId): Future[Boolean]
 
     /**
-     * Checks action activation rate throttles for subject.
+     * Checks action activation rate throttles for an identity.
      *
-     * @param user the subject to check rate throttles for
-     * @return a promise that completes with success iff the subject is within their activation quota
+     * @param user the identity to check rate throttles for
+     * @return a promise that completes with success iff the user is within their activation quota
      */
     protected[core] def checkThrottles(user: Identity)(
         implicit transid: TransactionId): Future[Unit] = {
-        val subject = user.subject
-        logging.info(this, s"checking user '$subject' has not exceeded activation quota")
+
+        logging.info(this, s"checking user '${user.subject}' has not exceeded activation quota")
 
         checkSystemOverload(ACTIVATE) orElse {
-            checkThrottleOverload(!invokeRateThrottler.check(subject), tooManyRequests)
+            checkThrottleOverload(!invokeRateThrottler.check(user), tooManyRequests)
         } orElse {
-            checkThrottleOverload(!concurrentInvokeThrottler.check(subject), tooManyConcurrentRequests)
+            checkThrottleOverload(!concurrentInvokeThrottler.check(user), tooManyConcurrentRequests)
         } map {
             Future.failed(_)
         } getOrElse Future.successful({})
@@ -161,7 +161,7 @@ protected[core] abstract class EntitlementProvider(config: WhiskConfig, loadBala
      * resource for example, or explicit. The implicit check is computed here. The explicit check
      * is delegated to the service implementing this interface.
      *
-     * @param user the subject to check rights for
+     * @param user the subject identity to check rights for
      * @param right the privilege the subject is requesting (applies to the entire set of resources)
      * @param resources the set of resources the subject requests access to
      * @return a promise that completes with success iff the subject is permitted to access all of the requested resources
@@ -174,9 +174,9 @@ protected[core] abstract class EntitlementProvider(config: WhiskConfig, loadBala
             if (resources.nonEmpty) {
                 logging.info(this, s"checking user '$subject' has privilege '$right' for '${resources.mkString(",")}'")
                 checkSystemOverload(right) orElse {
-                    checkUserThrottle(subject, right, resources)
+                    checkUserThrottle(user, right, resources)
                 } orElse {
-                    checkConcurrentUserThrottle(subject, right, resources)
+                    checkConcurrentUserThrottle(user, right, resources)
                 } map {
                     Future.failed(_)
                 } getOrElse checkPrivilege(user, right, resources)
@@ -245,17 +245,17 @@ protected[core] abstract class EntitlementProvider(config: WhiskConfig, loadBala
      * While it is possible for the set of resources to contain more than one action or trigger, the plurality is ignored and treated
      * as one activation since these should originate from a single macro resources (e.g., a sequence).
      *
-     * @param subject the subject to check quota for
+     * @param user the subject identity to check rights for
      * @param right the privilege, if ACTIVATE then check quota else return None
      * @param resource the set of resources must contain at least one resource that can be activated else return None
      * @return None if subject is not throttled else a rejection
      */
-    private def checkUserThrottle(subject: Subject, right: Privilege, resources: Set[Resource])(
+    private def checkUserThrottle(user: Identity, right: Privilege, resources: Set[Resource])(
         implicit transid: TransactionId): Option[RejectRequest] = {
         def userThrottled = {
             val isInvocation = resources.exists(_.collection.path == Collection.ACTIONS)
             val isTrigger = resources.exists(_.collection.path == Collection.TRIGGERS)
-            (isInvocation && !invokeRateThrottler.check(subject)) || (isTrigger && !triggerRateThrottler.check(subject))
+            (isInvocation && !invokeRateThrottler.check(user)) || (isTrigger && !triggerRateThrottler.check(user))
         }
 
         checkThrottleOverload(right == ACTIVATE && userThrottled, tooManyRequests)
@@ -267,16 +267,16 @@ protected[core] abstract class EntitlementProvider(config: WhiskConfig, loadBala
      * While it is possible for the set of resources to contain more than one action, the plurality is ignored and treated
      * as one activation since these should originate from a single macro resources (e.g., a sequence).
      *
-     * @param subject the subject to check quota for
+     * @param user the subject identity to check rights for
      * @param right the privilege, if ACTIVATE then check quota else return None
      * @param resource the set of resources must contain at least one resource that can be activated else return None
      * @return None if subject is not throttled else a rejection
      */
-    private def checkConcurrentUserThrottle(subject: Subject, right: Privilege, resources: Set[Resource])(
+    private def checkConcurrentUserThrottle(user: Identity, right: Privilege, resources: Set[Resource])(
         implicit transid: TransactionId): Option[RejectRequest] = {
         def userThrottled = {
             val isInvocation = resources.exists(_.collection.path == Collection.ACTIONS)
-            (isInvocation && !concurrentInvokeThrottler.check(subject))
+            (isInvocation && !concurrentInvokeThrottler.check(user))
         }
 
         checkThrottleOverload(right == ACTIVATE && userThrottled, tooManyConcurrentRequests)
diff --git a/core/controller/src/main/scala/whisk/core/entitlement/RateThrottler.scala b/core/controller/src/main/scala/whisk/core/entitlement/RateThrottler.scala
index e5b22e2..ee32604 100644
--- a/core/controller/src/main/scala/whisk/core/entitlement/RateThrottler.scala
+++ b/core/controller/src/main/scala/whisk/core/entitlement/RateThrottler.scala
@@ -21,7 +21,8 @@ import scala.collection.concurrent.TrieMap
 
 import whisk.common.Logging
 import whisk.common.TransactionId
-import whisk.core.entity.Subject
+import whisk.core.entity.Identity
+import whisk.core.entity.UUID
 
 /**
  * A class tracking the rate of invocation (or any operation) by subject (any key really).
@@ -33,21 +34,22 @@ class RateThrottler(description: String, maxPerMinute: Int)(implicit logging: Lo
     logging.info(this, s"$description: maxPerMinute = $maxPerMinute")(TransactionId.controller)
 
     /**
-     * Maintains map of subject to operations rates.
+     * Maintains map of subject namespace to operations rates.
      */
-    private val rateMap = new TrieMap[Subject, RateInfo]
+    private val rateMap = new TrieMap[UUID, RateInfo]
 
     /**
      * Checks whether the operation should be allowed to proceed.
-     * Every `check` operation charges the subject for one operation.
+     * Every `check` operation charges the subject namespace for one operation.
      *
-     * @param subject the subject to check
-     * @return true iff subject is below allowed limit
+     * @param user the identity to check
+     * @return true iff subject namespace is below allowed limit
      */
-    def check(subject: Subject)(implicit transid: TransactionId): Boolean = {
-        val rate = rateMap.getOrElseUpdate(subject, new RateInfo(maxPerMinute))
+    def check(user: Identity)(implicit transid: TransactionId): Boolean = {
+        val uuid = user.uuid // this is namespace identifier
+        val rate = rateMap.getOrElseUpdate(uuid, new RateInfo(maxPerMinute))
         val belowLimit = rate.check()
-        logging.info(this, s"subject = ${subject.toString}, rate = ${rate.count()}, below limit = $belowLimit")
+        logging.debug(this, s"namespace = ${uuid.asString} rate = ${rate.count()}, below limit = $belowLimit")
         belowLimit
     }
 }
diff --git a/core/controller/src/main/scala/whisk/core/loadBalancer/LoadBalancerService.scala b/core/controller/src/main/scala/whisk/core/loadBalancer/LoadBalancerService.scala
index d1d5208..6534307 100644
--- a/core/controller/src/main/scala/whisk/core/loadBalancer/LoadBalancerService.scala
+++ b/core/controller/src/main/scala/whisk/core/loadBalancer/LoadBalancerService.scala
@@ -49,6 +49,8 @@ import whisk.core.database.NoDocumentException
 import whisk.core.entity.{ ActivationId, WhiskAction, WhiskActivation }
 import whisk.core.entity.InstanceId
 import whisk.core.entity.ExecutableWhiskAction
+import whisk.core.entity.UUID
+import whisk.core.entity.WhiskAction
 import whisk.core.entity.types.EntityStore
 import scala.annotation.tailrec
 
@@ -57,11 +59,11 @@ trait LoadBalancer {
     val activeAckTimeoutGrace = 1.minute
 
     /**
-     * Retrieves a per subject map of counts representing in-flight activations as seen by the load balancer
+     * Retrieves a per namespace id map of counts representing in-flight activations as seen by the load balancer
      *
-     * @return a map where the key is the subject and the long is total issued activations by that user
+     * @return a map where the key is the namespace id and the long is total issued activations by that namespace
      */
-    def getActiveUserActivationCounts: Map[String, Int]
+    def getActiveNamespaceActivationCounts: Map[UUID, Int]
 
     /**
      * Publishes activation message on internal bus for an invoker to pick up.
@@ -88,13 +90,12 @@ class LoadBalancerService(config: WhiskConfig, instance: InstanceId, entityStore
     private val blackboxFraction: Double = Math.max(0.0, Math.min(1.0, config.controllerBlackboxFraction))
     logging.info(this, s"blackboxFraction = $blackboxFraction")
 
-    override def getActiveUserActivationCounts: Map[String, Int] = activationBySubject.toMap mapValues { _.size }
+    override def getActiveNamespaceActivationCounts: Map[UUID, Int] = activationByNamespaceId.toMap mapValues { _.size }
 
     override def publish(action: ExecutableWhiskAction, msg: ActivationMessage)(
         implicit transid: TransactionId): Future[Future[Either[ActivationId, WhiskActivation]]] = {
         chooseInvoker(action, msg).flatMap { invokerName =>
-            val subject = msg.user.subject.asString
-            val entry = setupActivation(action, msg.activationId, subject, invokerName, transid)
+            val entry = setupActivation(action, msg.activationId, msg.user.uuid, invokerName, transid)
             sendActivationToInvoker(messageProducer, msg, invokerName).map { _ =>
                 entry.promise.future
             }
@@ -107,11 +108,11 @@ class LoadBalancerService(config: WhiskConfig, instance: InstanceId, entityStore
      * A map storing current activations based on ActivationId.
      * The promise value represents the obligation of writing the answer back.
      */
-    case class ActivationEntry(id: ActivationId, subject: String, invokerName: String, created: Instant, promise: Promise[Either[ActivationId, WhiskActivation]])
+    case class ActivationEntry(id: ActivationId, namespaceId: UUID, invokerName: String, created: Instant, promise: Promise[Either[ActivationId, WhiskActivation]])
     type TrieSet[T] = TrieMap[T, Unit]
     private val activationById = new TrieMap[ActivationId, ActivationEntry]
     private val activationByInvoker = new TrieMap[String, TrieSet[ActivationEntry]]
-    private val activationBySubject = new TrieMap[String, TrieSet[ActivationEntry]]
+    private val activationByNamespaceId = new TrieMap[UUID, TrieSet[ActivationEntry]]
 
     /**
      * Tries to fill in the result slot (i.e., complete the promise) when a completion message arrives.
@@ -122,10 +123,10 @@ class LoadBalancerService(config: WhiskConfig, instance: InstanceId, entityStore
     private def processCompletion(response: Either[ActivationId, WhiskActivation], tid: TransactionId, forced: Boolean): Unit = {
         val aid = response.fold(l => l, r => r.activationId)
         activationById.remove(aid) match {
-            case Some(entry @ ActivationEntry(_, subject, invokerIndex, _, p)) =>
+            case Some(entry @ ActivationEntry(_, namespaceId, invokerIndex, _, p)) =>
                 logging.info(this, s"${if (!forced) "received" else "forced"} active ack for '$aid'")(tid)
                 activationByInvoker.getOrElseUpdate(invokerIndex, new TrieSet[ActivationEntry]).remove(entry)
-                activationBySubject.getOrElseUpdate(subject, new TrieSet[ActivationEntry]).remove(entry)
+                activationByNamespaceId.getOrElseUpdate(namespaceId, new TrieSet[ActivationEntry]).remove(entry)
                 if (!forced) {
                     p.trySuccess(response)
                 } else {
@@ -141,7 +142,7 @@ class LoadBalancerService(config: WhiskConfig, instance: InstanceId, entityStore
     /**
      * Creates an activation entry and insert into various maps.
      */
-    private def setupActivation(action: ExecutableWhiskAction, activationId: ActivationId, subject: String, invokerName: String, transid: TransactionId): ActivationEntry = {
+    private def setupActivation(action: ExecutableWhiskAction, activationId: ActivationId, namespaceId: UUID, invokerName: String, transid: TransactionId): ActivationEntry = {
         // either create a new promise or reuse a previous one for this activation if it exists
         val timeout = action.limits.timeout.duration + activeAckTimeoutGrace
         val entry = activationById.getOrElseUpdate(activationId, {
@@ -157,12 +158,12 @@ class LoadBalancerService(config: WhiskConfig, instance: InstanceId, entityStore
                 processCompletion(Left(activationId), transid, forced = true)
             }
 
-            ActivationEntry(activationId, subject, invokerName, Instant.now(Clock.systemUTC()), promiseRef.get)
+            ActivationEntry(activationId, namespaceId, invokerName, Instant.now(Clock.systemUTC()), promiseRef.get)
         })
 
         // add the entry to our maps, for bookkeeping
         activationByInvoker.getOrElseUpdate(invokerName, new TrieSet[ActivationEntry]).put(entry, {})
-        activationBySubject.getOrElseUpdate(subject, new TrieSet[ActivationEntry]).put(entry, {})
+        activationByNamespaceId.getOrElseUpdate(namespaceId, new TrieSet[ActivationEntry]).put(entry, {})
         entry
     }
 
@@ -172,10 +173,10 @@ class LoadBalancerService(config: WhiskConfig, instance: InstanceId, entityStore
     private def clearInvokerState(invokerName: String) = {
         val actSet = activationByInvoker.getOrElseUpdate(invokerName, new TrieSet[ActivationEntry])
         actSet.keySet map {
-            case actEntry @ ActivationEntry(activationId, subject, invokerIndex, _, promise) =>
+            case actEntry @ ActivationEntry(activationId, namespaceId, invokerIndex, _, promise) =>
                 promise.tryFailure(new LoadBalancerException(s"Invoker $invokerIndex restarted"))
                 activationById.remove(activationId)
-                activationBySubject.get(subject) map { _.remove(actEntry) }
+                activationByNamespaceId.get(namespaceId) map { _.remove(actEntry) }
         }
         actSet.clear()
     }
diff --git a/docs/reference.md b/docs/reference.md
index 686cc2f..c6d826e 100644
--- a/docs/reference.md
+++ b/docs/reference.md
@@ -400,7 +400,7 @@ The following table lists the default limits for actions.
 | memory | a container is not allowed to allocate more than N MB of memory | per action | MB | 256 |
 | logs | a container is not allowed to write more than N MB to stdout | per action | MB | 10 |
 | concurrent | no more than N activations may be submitted per namespace either executing or queued for execution | per namespace | number | 100 |
-| minuteRate | no more than N activations may be submitted per namespace per minute | per user | number | 120 |
+| minuteRate | no more than N activations may be submitted per namespace per minute | per namespace | number | 120 |
 | codeSize | the maximum size of the actioncode | not configurable, limit per action | MB | 48 |
 | parameters | the maximum size of the parameters that can be attached | not configurable, limit per action/package/trigger | MB | 1 |
 
diff --git a/tests/src/test/scala/whisk/core/cli/test/WskWebActionsTests.scala b/tests/src/test/scala/whisk/core/cli/test/WskWebActionsTests.scala
index 5983a99..5a1a653 100644
--- a/tests/src/test/scala/whisk/core/cli/test/WskWebActionsTests.scala
+++ b/tests/src/test/scala/whisk/core/cli/test/WskWebActionsTests.scala
@@ -89,8 +89,7 @@ class WskWebActionsTestsV2 extends WskWebActionsTests with BeforeAndAfterAll {
 
             val file = Some(TestUtils.getTestActionFilename("echo.js"))
             assetHelper.withCleaner(wsk.action, actionName) {
-                (action, _) =>
-                    action.create(actionName, file, web = Some(true.toString))(wp)
+                (action, _) => action.create(actionName, file, web = Some(true.toString))(wp)
             }
 
             val url = getServiceApiHost(vanitySubdomain, true) + s"/default/$actionName.text/a?a=A"
@@ -148,8 +147,7 @@ trait WskWebActionsTests
             val file = Some(TestUtils.getTestActionFilename("echo.js"))
 
             assetHelper.withCleaner(wsk.action, name) {
-                (action, _) =>
-                    action.create(name, file, web = Some("true"))
+                (action, _) => action.create(name, file, web = Some("true"))
             }
 
             val host = getServiceURL()
@@ -241,11 +239,11 @@ trait WskWebActionsTests
             val url = host + s"$testRoutePath/$namespace/default/webaction"
 
             assetHelper.withCleaner(wsk.action, name) {
-                (action, _) =>
-                    action.create(name, file, web = Some("true"))
+                (action, _) => action.create(name, file, web = Some("true"))
             }
 
-            val responses = Seq(RestAssured.given().config(sslconfig).options(s"$url.http"),
+            val responses = Seq(
+                RestAssured.given().config(sslconfig).options(s"$url.http"),
                 RestAssured.given().config(sslconfig).get(s"$url.json"))
 
             responses.foreach { response =>
@@ -264,8 +262,7 @@ trait WskWebActionsTests
             val bodyContent = "This is the body"
 
             assetHelper.withCleaner(wsk.action, name) {
-                (action, _) =>
-                    action.create(name, file, web = Some("true"))
+                (action, _) => action.create(name, file, web = Some("true"))
             }
 
             val host = getServiceURL()
@@ -290,8 +287,7 @@ trait WskWebActionsTests
             val file = Some(TestUtils.getTestActionFilename("textBody.js"))
 
             assetHelper.withCleaner(wsk.action, name) {
-                (action, _) =>
-                    action.create(name, file, web = Some("true"))
+                (action, _) => action.create(name, file, web = Some("true"))
             }
 
             val host = getServiceURL()
diff --git a/tests/src/test/scala/whisk/core/controller/test/ControllerTestCommon.scala b/tests/src/test/scala/whisk/core/controller/test/ControllerTestCommon.scala
index f2e6656..0110050 100644
--- a/tests/src/test/scala/whisk/core/controller/test/ControllerTestCommon.scala
+++ b/tests/src/test/scala/whisk/core/controller/test/ControllerTestCommon.scala
@@ -199,7 +199,7 @@ class DegenerateLoadBalancerService(config: WhiskConfig)(implicit ec: ExecutionC
     // unit tests that need an activation via active ack/fast path should set this to value expected
     var whiskActivationStub: Option[(FiniteDuration, WhiskActivation)] = None
 
-    override def getActiveUserActivationCounts: Map[String, Int] = Map()
+    override def getActiveNamespaceActivationCounts: Map[UUID, Int] = Map.empty
 
     override def publish(action: ExecutableWhiskAction, msg: ActivationMessage)(implicit transid: TransactionId): Future[Future[Either[ActivationId, WhiskActivation]]] =
         Future.successful {
diff --git a/tests/src/test/scala/whisk/core/controller/test/RateThrottleTests.scala b/tests/src/test/scala/whisk/core/controller/test/RateThrottleTests.scala
index e404be8..62e0537 100644
--- a/tests/src/test/scala/whisk/core/controller/test/RateThrottleTests.scala
+++ b/tests/src/test/scala/whisk/core/controller/test/RateThrottleTests.scala
@@ -28,6 +28,7 @@ import common.StreamLogging
 import whisk.common.TransactionId
 import whisk.core.entitlement._
 import whisk.core.entity.Subject
+import whisk.core.entity.AuthKey
 
 /**
  * Tests rate throttle.
@@ -42,7 +43,7 @@ class RateThrottleTests
     with StreamLogging {
 
     implicit val transid = TransactionId.testing
-    val subject = Subject()
+    val subject = Subject().toIdentity(AuthKey())
 
     behavior of "Rate Throttle"
 
diff --git a/tests/src/test/scala/whisk/core/controller/test/WebActionsApiTests.scala b/tests/src/test/scala/whisk/core/controller/test/WebActionsApiTests.scala
index 307a31c..af57577 100644
--- a/tests/src/test/scala/whisk/core/controller/test/WebActionsApiTests.scala
+++ b/tests/src/test/scala/whisk/core/controller/test/WebActionsApiTests.scala
@@ -1131,7 +1131,7 @@ trait WebActionsApiTests extends ControllerTestCommon with BeforeAndAfterEach wi
             implicit val tid = transid()
             customOptions = false
 
-            Seq(s"$systemId/proxy/export_c.http", s"$systemId/proxy/export_c.json?a=b&c=d").
+            Seq(s"$systemId/proxy/export_c.http", s"$systemId/proxy/export_c.json").
                 foreach { path =>
                     allowedMethods.foreach { m =>
                         invocationsAllowed += 1

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