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

markusthoemmes 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 a8b75e9  Generate TransactionId in nginx rather than controller. 
(#3199)
a8b75e9 is described below

commit a8b75e9871d860406d71bdf5d2c7a534d54c8dc9
Author: Christian Bickel <git...@cbickel.de>
AuthorDate: Thu May 3 12:53:10 2018 +0200

    Generate TransactionId in nginx rather than controller. (#3199)
    
    - Move from a numeric TransactionId to a random string.
    - Add ability to take a header's value as the TransactionId (like 
`X-Request-Id`).
    - Add `X-Request-Id` header from nginx (and return it to the user).
---
 ansible/group_vars/all                             |  2 +-
 ansible/roles/controller/tasks/deploy.yml          |  2 +-
 ansible/roles/invoker/tasks/deploy.yml             |  1 +
 ansible/roles/nginx/templates/nginx.conf.j2        |  8 +-
 common/scala/src/main/resources/application.conf   |  3 +-
 .../main/scala/whisk/common/TransactionId.scala    | 90 +++++++++-------------
 .../src/main/scala/whisk/core/WhiskConfig.scala    |  1 -
 .../main/scala/whisk/http/BasicHttpService.scala   | 51 ++++++++----
 .../src/main/scala/whisk/http/ErrorResponse.scala  |  2 +-
 .../scala/whisk/core/controller/Controller.scala   |  2 -
 .../scala/whisk/core/controller/Triggers.scala     |  7 +-
 .../main/scala/whisk/core/invoker/Invoker.scala    |  4 +-
 .../scala/whisk/core/invoker/InvokerServer.scala   | 28 -------
 .../test/scala/whisk/common/SchedulerTests.scala   |  2 +-
 .../containerpool/test/ContainerProxyTests.scala   | 40 ++++------
 .../controller/test/ControllerTestCommon.scala     |  6 +-
 .../core/controller/test/PackagesApiTests.scala    | 16 ++--
 .../core/controller/test/WebActionsApiTests.scala  |  2 +-
 .../scala/whisk/core/database/test/DbUtils.scala   | 10 ++-
 .../core/database/test/DocumentHandlerTests.scala  | 24 +++---
 .../test/behavior/ArtifactStoreBehaviorBase.scala  |  5 +-
 .../scala/whisk/core/entity/test/SchemaTests.scala |  8 +-
 22 files changed, 137 insertions(+), 177 deletions(-)

diff --git a/ansible/group_vars/all b/ansible/group_vars/all
index f04807b..977d6ed 100644
--- a/ansible/group_vars/all
+++ b/ansible/group_vars/all
@@ -97,7 +97,7 @@ jmx:
   enabled: "{{ jmxremote_enabled | default('true') }}"
 
 transactions:
-  stride: "{{ groups['controllers'] | length }}"
+  header: "{{ transactions_header | default('X-Request-ID') }}"
 
 registry:
   confdir: "{{ config_root_dir }}/registry"
diff --git a/ansible/roles/controller/tasks/deploy.yml 
b/ansible/roles/controller/tasks/deploy.yml
index 8173f00..8a839d4 100644
--- a/ansible/roles/controller/tasks/deploy.yml
+++ b/ansible/roles/controller/tasks/deploy.yml
@@ -201,7 +201,7 @@
       "CONFIG_whisk_spi_LoadBalancerProvider": "{{ controller.loadbalancer.spi 
}}"
       "CONFIG_logback_log_level": "{{ controller.loglevel }}"
 
-      "CONFIG_whisk_transactions_stride": "{{ transactions.stride | default() 
}}"
+      "CONFIG_whisk_transactions_header": "{{ transactions.header }}"
 
 - name: create seed nodes list
   set_fact:
diff --git a/ansible/roles/invoker/tasks/deploy.yml 
b/ansible/roles/invoker/tasks/deploy.yml
index 2643b54..b542d78 100644
--- a/ansible/roles/invoker/tasks/deploy.yml
+++ b/ansible/roles/invoker/tasks/deploy.yml
@@ -227,6 +227,7 @@
         -e CONFIG_whisk_timeLimit_max='{{ limit_action_time_max | default() }}'
         -e CONFIG_whisk_timeLimit_std='{{ limit_action_time_std | default() }}'
         -e CONFIG_whisk_activation_payload_max='{{ limit_activation_payload | 
default() }}'
+        -e CONFIG_whisk_transactions_header='{{ transactions.header }}'
         -v /sys/fs/cgroup:/sys/fs/cgroup
         -v /run/runc:/run/runc
         -v {{ whisk_logs_dir }}/invoker{{ 
groups['invokers'].index(inventory_hostname) }}:/logs
diff --git a/ansible/roles/nginx/templates/nginx.conf.j2 
b/ansible/roles/nginx/templates/nginx.conf.j2
index 8b2f07b..a8632d9 100644
--- a/ansible/roles/nginx/templates/nginx.conf.j2
+++ b/ansible/roles/nginx/templates/nginx.conf.j2
@@ -15,7 +15,7 @@ http {
     rewrite_log on;
 {# change log format to display the upstream information #}
     log_format combined-upstream '$remote_addr - $remote_user [$time_local] '
-        '$request $status $body_bytes_sent '
+        '[#tid_$request_id] $request $status $body_bytes_sent '
         '$http_referer $http_user_agent $upstream_addr';
     access_log /logs/nginx_access.log combined-upstream;
 
@@ -59,6 +59,12 @@ http {
     }
 
     proxy_set_header X-OW-EXTRA-LOGGING $extra_logging;
+    # Set the request id generated by nginx as tid-header to the upstream.
+    # This tid is either the request-id generated by ngix or a tid, sent by 
the caller.
+    proxy_set_header {{ transactions.header }} $request_id;
+
+    # Send the tid always back as header.
+    add_header {{ transactions.header }} $request_id always;
 
 {# Turn off sending information about the server to the client #}
     server_tokens off;
diff --git a/common/scala/src/main/resources/application.conf 
b/common/scala/src/main/resources/application.conf
index f665edb..ea4bd46 100644
--- a/common/scala/src/main/resources/application.conf
+++ b/common/scala/src/main/resources/application.conf
@@ -131,8 +131,7 @@ whisk {
 
     # transaction ID related configuration
     transactions {
-        stride = 1
-        stride = ${?CONTROLLER_INSTANCES}
+        header = "X-Request-ID"
     }
     # action runtimes configuration
     runtimes {
diff --git a/common/scala/src/main/scala/whisk/common/TransactionId.scala 
b/common/scala/src/main/scala/whisk/common/TransactionId.scala
index 1f901a1..cb16a42 100644
--- a/common/scala/src/main/scala/whisk/common/TransactionId.scala
+++ b/common/scala/src/main/scala/whisk/common/TransactionId.scala
@@ -17,20 +17,15 @@
 
 package whisk.common
 
-import java.time.Clock
-import java.time.Duration
-import java.time.Instant
-import java.util.concurrent.atomic.AtomicInteger
+import java.time.{Clock, Duration, Instant}
 
-import scala.math.BigDecimal.int2bigDecimal
-import scala.util.Try
-import akka.event.Logging.{DebugLevel, InfoLevel, WarningLevel}
-import akka.event.Logging.LogLevel
+import akka.event.Logging.{DebugLevel, InfoLevel, LogLevel, WarningLevel}
+import akka.http.scaladsl.model.headers.RawHeader
+import pureconfig.loadConfigOrThrow
 import spray.json._
-
 import whisk.core.ConfigKeys
 
-import pureconfig._
+import scala.util.Try
 
 /**
  * A transaction id for tracking operations in the system that are specific to 
a request.
@@ -39,11 +34,9 @@ import pureconfig._
  */
 case class TransactionId private (meta: TransactionMetadata) extends AnyVal {
   def id = meta.id
-  override def toString = {
-    if (meta.id > 0) s"#tid_${meta.id}"
-    else if (meta.id < 0) s"#sid_${-meta.id}"
-    else "??"
-  }
+  override def toString = s"#tid_${meta.id}"
+
+  def toHeader = RawHeader(TransactionId.generatorConfig.header, meta.id)
 
   /**
    * Method to count events.
@@ -190,8 +183,9 @@ case class StartMarker(val start: Instant, startMarker: 
LogMarkerToken)
  * @param id the transaction identifier; it is positive for client requests,
  *           negative for system operation and zero when originator is not 
known
  * @param start the timestamp when the request processing commenced
+ * @param extraLogging enables logging, if set to true
  */
-protected case class TransactionMetadata(val id: Long, val start: Instant, val 
extraLogging: Boolean = false)
+protected case class TransactionMetadata(val id: String, val start: Instant, 
val extraLogging: Boolean = false)
 
 object TransactionId {
 
@@ -200,58 +194,44 @@ object TransactionId {
   val metricsKamonTags: Boolean = 
sys.env.get("METRICS_KAMON_TAGS").getOrElse("False").toBoolean
   val metricsLog: Boolean = 
sys.env.get("METRICS_LOG").getOrElse("True").toBoolean
 
-  val unknown = TransactionId(0)
-  val testing = TransactionId(-1) // Common id for for unit testing
-  val invoker = TransactionId(-100) // Invoker startup/shutdown or GC activity
-  val invokerWarmup = TransactionId(-101) // Invoker warmup thread that makes 
stem-cell containers
-  val invokerNanny = TransactionId(-102) // Invoker nanny thread
-  val dispatcher = TransactionId(-110) // Kafka message dispatcher
-  val loadbalancer = TransactionId(-120) // Loadbalancer thread
-  val invokerHealth = TransactionId(-121) // Invoker supervision
-  val controller = TransactionId(-130) // Controller startup
-  val dbBatcher = TransactionId(-140) // Database batcher
-
-  def apply(tid: BigDecimal, extraLogging: Boolean = false): TransactionId = {
-    Try {
-      val now = Instant.now(Clock.systemUTC())
-      TransactionId(TransactionMetadata(tid.toLong, now, extraLogging))
-    } getOrElse unknown
+  val generatorConfig = 
loadConfigOrThrow[TransactionGeneratorConfig](ConfigKeys.transactions)
+
+  val systemPrefix = "sid_"
+
+  val unknown = TransactionId(systemPrefix + "unknown")
+  val testing = TransactionId(systemPrefix + "testing") // Common id for for 
unit testing
+  val invoker = TransactionId(systemPrefix + "invoker") // Invoker 
startup/shutdown or GC activity
+  val invokerWarmup = TransactionId(systemPrefix + "invokerWarmup") // Invoker 
warmup thread that makes stem-cell containers
+  val invokerNanny = TransactionId(systemPrefix + "invokerNanny") // Invoker 
nanny thread
+  val dispatcher = TransactionId(systemPrefix + "dispatcher") // Kafka message 
dispatcher
+  val loadbalancer = TransactionId(systemPrefix + "loadbalancer") // 
Loadbalancer thread
+  val invokerHealth = TransactionId(systemPrefix + "invokerHealth") // Invoker 
supervision
+  val controller = TransactionId(systemPrefix + "controller") // Controller 
startup
+  val dbBatcher = TransactionId(systemPrefix + "dbBatcher") // Database batcher
+
+  def apply(tid: String, extraLogging: Boolean = false): TransactionId = {
+    val now = Instant.now(Clock.systemUTC())
+    TransactionId(TransactionMetadata(tid, now, extraLogging))
   }
 
   implicit val serdes = new RootJsonFormat[TransactionId] {
     def write(t: TransactionId) = {
       if (t.meta.extraLogging)
-        JsArray(JsNumber(t.meta.id), JsNumber(t.meta.start.toEpochMilli), 
JsBoolean(t.meta.extraLogging))
+        JsArray(JsString(t.meta.id), JsNumber(t.meta.start.toEpochMilli), 
JsBoolean(t.meta.extraLogging))
       else
-        JsArray(JsNumber(t.meta.id), JsNumber(t.meta.start.toEpochMilli))
+        JsArray(JsString(t.meta.id), JsNumber(t.meta.start.toEpochMilli))
     }
 
     def read(value: JsValue) =
       Try {
         value match {
-          case JsArray(Vector(JsNumber(id), JsNumber(start))) =>
-            TransactionId(TransactionMetadata(id.longValue, 
Instant.ofEpochMilli(start.longValue), false))
-          case JsArray(Vector(JsNumber(id), JsNumber(start), 
JsBoolean(extraLogging))) =>
-            TransactionId(TransactionMetadata(id.longValue, 
Instant.ofEpochMilli(start.longValue), extraLogging))
+          case JsArray(Vector(JsString(id), JsNumber(start))) =>
+            TransactionId(TransactionMetadata(id, 
Instant.ofEpochMilli(start.longValue), false))
+          case JsArray(Vector(JsString(id), JsNumber(start), 
JsBoolean(extraLogging))) =>
+            TransactionId(TransactionMetadata(id, 
Instant.ofEpochMilli(start.longValue), extraLogging))
         }
       } getOrElse unknown
   }
 }
 
-/**
- * A thread-safe transaction counter.
- */
-trait TransactionCounter {
-  case class TransactionCounterConfig(stride: Int)
-
-  val transCounterConfig = 
loadConfigOrThrow[TransactionCounterConfig](ConfigKeys.transactions)
-  val stride = transCounterConfig.stride
-  val instanceOrdinal: Int
-
-  // seed the counter so transids do not overlap: instanceOrdinal + n * 
stride, start at n = 1
-  private lazy val cnt = new AtomicInteger(instanceOrdinal + stride)
-
-  def transid(extraLogging: Boolean = false): TransactionId = {
-    TransactionId(cnt.addAndGet(stride), extraLogging)
-  }
-}
+case class TransactionGeneratorConfig(header: String)
diff --git a/common/scala/src/main/scala/whisk/core/WhiskConfig.scala 
b/common/scala/src/main/scala/whisk/core/WhiskConfig.scala
index 231341f..0c937ae 100644
--- a/common/scala/src/main/scala/whisk/core/WhiskConfig.scala
+++ b/common/scala/src/main/scala/whisk/core/WhiskConfig.scala
@@ -240,7 +240,6 @@ object ConfigKeys {
   val kubernetesTimeouts = s"$kubernetes.timeouts"
 
   val transactions = "whisk.transactions"
-  val stride = s"$transactions.stride"
 
   val logStore = "whisk.logstore"
   val splunk = s"$logStore.splunk"
diff --git a/common/scala/src/main/scala/whisk/http/BasicHttpService.scala 
b/common/scala/src/main/scala/whisk/http/BasicHttpService.scala
index ece541b..586d7dc 100644
--- a/common/scala/src/main/scala/whisk/http/BasicHttpService.scala
+++ b/common/scala/src/main/scala/whisk/http/BasicHttpService.scala
@@ -17,27 +17,29 @@
 
 package whisk.http
 
-import scala.collection.immutable.Seq
-import scala.concurrent.{Await, Future}
-import scala.concurrent.duration.DurationInt
+import java.util.concurrent.ThreadLocalRandom
+
 import akka.actor.ActorSystem
 import akka.event.Logging
 import akka.http.scaladsl.Http
-import akka.http.scaladsl.model._
-import akka.http.scaladsl.model.HttpRequest
-import akka.http.scaladsl.server._
+import akka.http.scaladsl.model.{HttpRequest, _}
 import akka.http.scaladsl.server.RouteResult.Rejected
+import akka.http.scaladsl.server._
 import akka.http.scaladsl.server.directives._
 import akka.stream.ActorMaterializer
 import spray.json._
 import whisk.common._
 import whisk.core.WhiskConfig
 
+import scala.collection.immutable.Seq
+import scala.concurrent.duration.DurationInt
+import scala.concurrent.{Await, Future}
+
 /**
  * This trait extends the Akka Directives and Actor with logging and 
transaction counting
  * facilities common to all OpenWhisk REST services.
  */
-trait BasicHttpService extends Directives with TransactionCounter {
+trait BasicHttpService extends Directives {
 
   val OW_EXTRA_LOGGING_HEADER = "X-OW-EXTRA-LOGGING"
 
@@ -72,13 +74,15 @@ trait BasicHttpService extends Directives with 
TransactionCounter {
    */
   def route: Route = {
     assignId { implicit transid =>
-      DebuggingDirectives.logRequest(logRequestInfo _) {
-        DebuggingDirectives.logRequestResult(logResponseInfo _) {
-          BasicDirectives.mapRequest(_.removeHeader(OW_EXTRA_LOGGING_HEADER)) {
-            handleRejections(BasicHttpService.customRejectionHandler) {
-              prioritizeRejections {
-                toStrictEntity(30.seconds) {
-                  routes
+      respondWithHeader(transid.toHeader) {
+        DebuggingDirectives.logRequest(logRequestInfo _) {
+          DebuggingDirectives.logRequestResult(logResponseInfo _) {
+            
BasicDirectives.mapRequest(_.removeHeader(OW_EXTRA_LOGGING_HEADER)) {
+              handleRejections(BasicHttpService.customRejectionHandler) {
+                prioritizeRejections {
+                  toStrictEntity(30.seconds) {
+                    routes
+                  }
                 }
               }
             }
@@ -88,6 +92,10 @@ trait BasicHttpService extends Directives with 
TransactionCounter {
     }
   }
 
+  // Scala random should be enough here, as the generation for the tid is only 
a fallback. In addition the tid only has
+  // to be unique within a few minutes.
+  private val dict = ('A' to 'Z') ++ ('a' to 'z') ++ ('0' to '9')
+
   /** Assigns transaction id to every request. */
   protected def assignId = 
HeaderDirectives.optionalHeaderValueByName(OW_EXTRA_LOGGING_HEADER) flatMap { 
headerValue =>
     val extraLogging = headerValue match {
@@ -97,7 +105,20 @@ trait BasicHttpService extends Directives with 
TransactionCounter {
       case Some(value) => value.toLowerCase == "on"
       case None        => false
     }
-    extract(_ => transid(extraLogging))
+    extract { req =>
+      val tid =
+        req.request.headers
+          .find(_.name == TransactionId.generatorConfig.header)
+          .map(_.value)
+          .filterNot(_.startsWith(TransactionId.systemPrefix))
+          .getOrElse {
+            // As this is only a fallback, because the tid should be generated 
by nginx, this shouldn't be used.
+            // Therefore we didn't take a deep look into performance here.
+            (0 until 32).map(_ => 
dict(ThreadLocalRandom.current().nextInt(dict.size))).mkString("")
+          }
+
+      TransactionId(tid, extraLogging)
+    }
   }
 
   /** Generates log entry for every request. */
diff --git a/common/scala/src/main/scala/whisk/http/ErrorResponse.scala 
b/common/scala/src/main/scala/whisk/http/ErrorResponse.scala
index 97d2008..40685c0 100644
--- a/common/scala/src/main/scala/whisk/http/ErrorResponse.scala
+++ b/common/scala/src/main/scala/whisk/http/ErrorResponse.scala
@@ -253,7 +253,7 @@ object ErrorResponse extends Directives with 
DefaultJsonProtocol {
     def read(v: JsValue) =
       Try {
         v.asJsObject.getFields("error", "code") match {
-          case Seq(JsString(error), JsNumber(code)) =>
+          case Seq(JsString(error), JsString(code)) =>
             ErrorResponse(error, TransactionId(code))
           case Seq(JsString(error)) =>
             ErrorResponse(error, TransactionId.unknown)
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 340df96..c1c7390 100644
--- a/core/controller/src/main/scala/whisk/core/controller/Controller.scala
+++ b/core/controller/src/main/scala/whisk/core/controller/Controller.scala
@@ -82,8 +82,6 @@ class Controller(val instance: InstanceId,
                  implicit val logging: Logging)
     extends BasicRasService {
 
-  override val instanceOrdinal = instance.toInt
-
   TransactionId.controller.mark(
     this,
     LoggingMarkers.CONTROLLER_STARTUP(instance.toInt),
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 8bf2de7..760ae04 100644
--- a/core/controller/src/main/scala/whisk/core/controller/Triggers.scala
+++ b/core/controller/src/main/scala/whisk/core/controller/Triggers.scala
@@ -383,7 +383,8 @@ trait WhiskTriggersApi extends WhiskCollectionAPI {
    * @param args the arguments to post to the action
    * @return a future with the HTTP response from the action activation
    */
-  private def postActivation(user: Identity, rule: ReducedRule, args: 
JsObject): Future[HttpResponse] = {
+  private def postActivation(user: Identity, rule: ReducedRule, args: 
JsObject)(
+    implicit transid: TransactionId): Future[HttpResponse] = {
     // Build the url to invoke an action mapped to the rule
     val actionUrl = baseControllerPath / rule.action.path.root.asString / 
"actions"
 
@@ -394,7 +395,9 @@ trait WhiskTriggersApi extends WhiskCollectionAPI {
     val request = HttpRequest(
       method = POST,
       uri = url.withPath(actionUrl ++ actionPath),
-      headers = 
List(Authorization(BasicHttpCredentials(user.authkey.uuid.asString, 
user.authkey.key.asString))),
+      headers = List(
+        Authorization(BasicHttpCredentials(user.authkey.uuid.asString, 
user.authkey.key.asString)),
+        transid.toHeader),
       entity = HttpEntity(MediaTypes.`application/json`, args.compactPrint))
 
     singleRequest(request)
diff --git a/core/invoker/src/main/scala/whisk/core/invoker/Invoker.scala 
b/core/invoker/src/main/scala/whisk/core/invoker/Invoker.scala
index 58a4d1d..4a69d3c 100644
--- a/core/invoker/src/main/scala/whisk/core/invoker/Invoker.scala
+++ b/core/invoker/src/main/scala/whisk/core/invoker/Invoker.scala
@@ -39,7 +39,7 @@ import whisk.core.connector.PingMessage
 import whisk.core.entity._
 import whisk.core.entity.ExecManifest
 import whisk.core.entity.InstanceId
-import whisk.http.BasicHttpService
+import whisk.http.{BasicHttpService, BasicRasService}
 import whisk.spi.SpiLoader
 import whisk.utils.ExecutionContextFactory
 import whisk.common.TransactionId
@@ -185,7 +185,7 @@ object Invoker {
     })
 
     val port = config.servicePort.toInt
-    BasicHttpService.startHttpService(new InvokerServer().route, port)(
+    BasicHttpService.startHttpService(new BasicRasService {}.route, port)(
       actorSystem,
       ActorMaterializer.create(actorSystem))
   }
diff --git a/core/invoker/src/main/scala/whisk/core/invoker/InvokerServer.scala 
b/core/invoker/src/main/scala/whisk/core/invoker/InvokerServer.scala
deleted file mode 100644
index 2b45fca..0000000
--- a/core/invoker/src/main/scala/whisk/core/invoker/InvokerServer.scala
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package whisk.core.invoker
-
-import whisk.http.BasicRasService
-
-/**
- * Implements web server to handle certain REST API calls.
- * Currently provides a health ping route, only.
- */
-class InvokerServer() extends BasicRasService {
-  override val instanceOrdinal = 1
-}
diff --git a/tests/src/test/scala/whisk/common/SchedulerTests.scala 
b/tests/src/test/scala/whisk/common/SchedulerTests.scala
index 14d325b..35eaf68 100644
--- a/tests/src/test/scala/whisk/common/SchedulerTests.scala
+++ b/tests/src/test/scala/whisk/common/SchedulerTests.scala
@@ -127,7 +127,7 @@ class SchedulerTests extends FlatSpec with Matchers with 
WskActorSystem with Str
 
     waitForCalls()
     stream.toString.split(" ").drop(1).mkString(" ") shouldBe {
-      s"[ERROR] [#sid_1] [Scheduler] halted because $msg\n"
+      s"[ERROR] [$transid] [Scheduler] halted because $msg\n"
     }
   }
 
diff --git 
a/tests/src/test/scala/whisk/core/containerpool/test/ContainerProxyTests.scala 
b/tests/src/test/scala/whisk/core/containerpool/test/ContainerProxyTests.scala
index fcde7e7..205834e 100644
--- 
a/tests/src/test/scala/whisk/core/containerpool/test/ContainerProxyTests.scala
+++ 
b/tests/src/test/scala/whisk/core/containerpool/test/ContainerProxyTests.scala
@@ -19,41 +19,29 @@ package whisk.core.containerpool.test
 
 import java.time.Instant
 
-import scala.concurrent.Future
-import scala.concurrent.Promise
-import scala.concurrent.duration._
-import org.junit.runner.RunWith
-import org.scalatest.BeforeAndAfterAll
-import org.scalatest.FlatSpecLike
-import org.scalatest.Matchers
-import org.scalatest.junit.JUnitRunner
-import akka.actor.ActorRef
-import akka.actor.ActorSystem
-import akka.actor.FSM
-import akka.actor.FSM.CurrentState
-import akka.actor.FSM.SubscribeTransitionCallBack
-import akka.actor.FSM.Transition
+import akka.actor.FSM.{CurrentState, SubscribeTransitionCallBack, Transition}
+import akka.actor.{ActorRef, ActorSystem, FSM}
 import akka.stream.scaladsl.Source
-import akka.testkit.ImplicitSender
-import akka.testkit.TestKit
+import akka.testkit.{ImplicitSender, TestKit}
 import akka.util.ByteString
-import common.LoggedFunction
-import common.StreamLogging
-
-import scala.concurrent.ExecutionContext
-import spray.json._
+import common.{LoggedFunction, StreamLogging}
+import org.junit.runner.RunWith
+import org.scalatest.junit.JUnitRunner
+import org.scalatest.{BeforeAndAfterAll, FlatSpecLike, Matchers}
 import spray.json.DefaultJsonProtocol._
-import whisk.common.Logging
-import whisk.common.TransactionId
+import spray.json._
+import whisk.common.{Logging, TransactionId}
 import whisk.core.connector.ActivationMessage
 import whisk.core.containerpool._
 import whisk.core.containerpool.logging.LogCollectingException
+import whisk.core.entity.ExecManifest.{ImageName, RuntimeManifest}
 import whisk.core.entity._
-import whisk.core.entity.ExecManifest.RuntimeManifest
-import whisk.core.entity.ExecManifest.ImageName
 import whisk.core.entity.size._
 import whisk.http.Messages
 
+import scala.concurrent.duration._
+import scala.concurrent.{ExecutionContext, Future, Promise}
+
 @RunWith(classOf[JUnitRunner])
 class ContainerProxyTests
     extends TestKit(ActorSystem("ContainerProxys"))
@@ -79,7 +67,7 @@ class ContainerProxyTests
   val action = ExecutableWhiskAction(EntityPath("actionSpace"), 
EntityName("actionName"), exec)
 
   // create a transaction id to set the start time and control queue time
-  val messageTransId = TransactionId(BigDecimal(TransactionId.testing.meta.id))
+  val messageTransId = TransactionId(TransactionId.testing.meta.id)
 
   val initInterval = {
     val now = messageTransId.meta.start.plusMillis(50) // this is the queue 
time for cold start
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 e9df1d5..fdceb14 100644
--- a/tests/src/test/scala/whisk/core/controller/test/ControllerTestCommon.scala
+++ b/tests/src/test/scala/whisk/core/controller/test/ControllerTestCommon.scala
@@ -30,7 +30,6 @@ import akka.http.scaladsl.testkit.ScalatestRouteTest
 import akka.http.scaladsl.testkit.RouteTestTimeout
 import spray.json.DefaultJsonProtocol
 import spray.json.JsString
-import whisk.common.TransactionCounter
 import whisk.common.TransactionId
 import whisk.core.WhiskConfig
 import whisk.core.connector.ActivationMessage
@@ -52,15 +51,12 @@ protected trait ControllerTestCommon
     with BeforeAndAfterAll
     with ScalatestRouteTest
     with Matchers
-    with TransactionCounter
     with DbUtils
     with ExecHelpers
     with WhiskServices
     with StreamLogging {
 
-  override val instanceOrdinal = 0
-  override val instance = InstanceId(instanceOrdinal)
-  val activeAckTopicIndex = InstanceId(instanceOrdinal)
+  val activeAckTopicIndex = InstanceId(0)
 
   implicit val routeTestTimeout = RouteTestTimeout(90 seconds)
 
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 c0e2e40..706ca9c 100644
--- a/tests/src/test/scala/whisk/core/controller/test/PackagesApiTests.scala
+++ b/tests/src/test/scala/whisk/core/controller/test/PackagesApiTests.scala
@@ -17,19 +17,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.model.StatusCodes._
 import akka.http.scaladsl.server.Route
+import org.junit.runner.RunWith
+import org.scalatest.junit.JUnitRunner
 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
+import whisk.core.entity._
+import whisk.http.{ErrorResponse, Messages}
+
+import scala.language.postfixOps
 
 /**
  * Tests Packages API.
@@ -750,7 +750,7 @@ class PackagesApiTests extends ControllerTestCommon with 
WhiskPackagesApi {
       status should be(Conflict)
       val response = responseAs[ErrorResponse]
       response.error should include("Package not empty (contains 1 entity)")
-      response.code.id should be >= 1L
+      response.code.id should not be empty
     }
   }
 
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 97d5999..0dd5848 100644
--- a/tests/src/test/scala/whisk/core/controller/test/WebActionsApiTests.scala
+++ b/tests/src/test/scala/whisk/core/controller/test/WebActionsApiTests.scala
@@ -334,7 +334,7 @@ trait WebActionsApiBaseTests extends ControllerTestCommon 
with BeforeAndAfterEac
       error.fields.get("error").get shouldBe JsString(m)
     }
     error.fields.get("code") shouldBe defined
-    error.fields.get("code").get shouldBe an[JsNumber]
+    error.fields.get("code").get shouldBe an[JsString]
   }
 
   Seq(None, Some(WhiskAuthHelpers.newIdentity())).foreach { creds =>
diff --git a/tests/src/test/scala/whisk/core/database/test/DbUtils.scala 
b/tests/src/test/scala/whisk/core/database/test/DbUtils.scala
index 7cf9074..b341bae 100644
--- a/tests/src/test/scala/whisk/core/database/test/DbUtils.scala
+++ b/tests/src/test/scala/whisk/core/database/test/DbUtils.scala
@@ -18,6 +18,7 @@
 package whisk.core.database.test
 
 import java.util.concurrent.TimeoutException
+import java.util.concurrent.atomic.AtomicInteger
 
 import scala.collection.mutable.ListBuffer
 import scala.concurrent.Await
@@ -31,7 +32,6 @@ import scala.util.Success
 import scala.util.Try
 import spray.json._
 import spray.json.DefaultJsonProtocol._
-import whisk.common.TransactionCounter
 import whisk.common.TransactionId
 import whisk.core.database._
 import whisk.core.database.memory.MemoryArtifactStore
@@ -45,13 +45,15 @@ import whisk.core.entity.types.EntityStore
  * operations with those that flow through the cache. To mitigate this, use 
unique asset
  * names in tests, and defer all cleanup to the end of a test suite.
  */
-trait DbUtils extends TransactionCounter {
+trait DbUtils {
   implicit val dbOpTimeout = 15 seconds
-  override val instanceOrdinal = 0
-  val instance = InstanceId(instanceOrdinal)
+  val instance = InstanceId(0)
   val docsToDelete = ListBuffer[(ArtifactStore[_], DocInfo)]()
   case class RetryOp() extends Throwable
 
+  val cnt = new AtomicInteger(0)
+  def transid() = TransactionId(cnt.incrementAndGet().toString)
+
   /**
    * Retry an operation 'step()' awaiting its result up to 'timeout'.
    * Attempt the operation up to 'count' times. The future from the
diff --git 
a/tests/src/test/scala/whisk/core/database/test/DocumentHandlerTests.scala 
b/tests/src/test/scala/whisk/core/database/test/DocumentHandlerTests.scala
index c68fffd..20dc280 100644
--- a/tests/src/test/scala/whisk/core/database/test/DocumentHandlerTests.scala
+++ b/tests/src/test/scala/whisk/core/database/test/DocumentHandlerTests.scala
@@ -17,14 +17,16 @@
 
 package whisk.core.database.test
 
+import java.util.concurrent.atomic.AtomicInteger
+
+import common.WskActorSystem
 import org.junit.runner.RunWith
-import org.scalatest.{FlatSpec, Matchers, OptionValues}
+import org.scalatest.concurrent.ScalaFutures
 import org.scalatest.junit.JUnitRunner
+import org.scalatest.{FlatSpec, Matchers, OptionValues}
+import spray.json.DefaultJsonProtocol._
 import spray.json._
-import DefaultJsonProtocol._
-import common.WskActorSystem
-import org.scalatest.concurrent.ScalaFutures
-import whisk.common.{TransactionCounter, TransactionId}
+import whisk.common.TransactionId
 import whisk.core.database.SubjectHandler.SubjectView
 import whisk.core.database.WhisksHandler.ROOT_NS
 import whisk.core.database._
@@ -33,14 +35,10 @@ import whisk.core.entity._
 import scala.concurrent.Future
 
 @RunWith(classOf[JUnitRunner])
-class DocumentHandlerTests
-    extends FlatSpec
-    with Matchers
-    with ScalaFutures
-    with OptionValues
-    with TransactionCounter
-    with WskActorSystem {
-  override val instanceOrdinal = 0
+class DocumentHandlerTests extends FlatSpec with Matchers with ScalaFutures 
with OptionValues with WskActorSystem {
+
+  val cnt = new AtomicInteger(0)
+  def transid() = TransactionId(cnt.incrementAndGet().toString)
 
   behavior of "WhisksHandler computeFields"
 
diff --git 
a/tests/src/test/scala/whisk/core/database/test/behavior/ArtifactStoreBehaviorBase.scala
 
b/tests/src/test/scala/whisk/core/database/test/behavior/ArtifactStoreBehaviorBase.scala
index e13e420..e22063d 100644
--- 
a/tests/src/test/scala/whisk/core/database/test/behavior/ArtifactStoreBehaviorBase.scala
+++ 
b/tests/src/test/scala/whisk/core/database/test/behavior/ArtifactStoreBehaviorBase.scala
@@ -24,7 +24,7 @@ import common.{StreamLogging, WskActorSystem}
 import org.scalatest.concurrent.{IntegrationPatience, ScalaFutures}
 import org.scalatest.{BeforeAndAfterAll, BeforeAndAfterEach, FlatSpec, 
Matchers}
 import spray.json.{JsObject, JsValue}
-import whisk.common.{TransactionCounter, TransactionId}
+import whisk.common.TransactionId
 import whisk.core.database.test.DbUtils
 import whisk.core.database.{ArtifactStore, StaleParameter}
 import whisk.core.entity._
@@ -35,7 +35,6 @@ import scala.util.Random
 trait ArtifactStoreBehaviorBase
     extends FlatSpec
     with ScalaFutures
-    with TransactionCounter
     with Matchers
     with StreamLogging
     with DbUtils
@@ -44,8 +43,6 @@ trait ArtifactStoreBehaviorBase
     with BeforeAndAfterEach
     with BeforeAndAfterAll {
 
-  override val instanceOrdinal = 0
-
   //Bring in sync the timeout used by ScalaFutures and DBUtils
   implicit override val patienceConfig: PatienceConfig = 
PatienceConfig(timeout = dbOpTimeout)
 
diff --git a/tests/src/test/scala/whisk/core/entity/test/SchemaTests.scala 
b/tests/src/test/scala/whisk/core/entity/test/SchemaTests.scala
index d6111d0..99fe131 100644
--- a/tests/src/test/scala/whisk/core/entity/test/SchemaTests.scala
+++ b/tests/src/test/scala/whisk/core/entity/test/SchemaTests.scala
@@ -72,12 +72,12 @@ class SchemaTests extends FlatSpec with BeforeAndAfter with 
ExecHelpers with Mat
   behavior of "TransactionId"
 
   it should "serdes a transaction id without extraLogging parameter" in {
-    val txIdWithoutParameter = TransactionId(4711)
+    val txIdWithoutParameter = TransactionId("4711")
 
     // test serialization
     val serializedTxIdWithoutParameter = 
TransactionId.serdes.write(txIdWithoutParameter)
     serializedTxIdWithoutParameter match {
-      case JsArray(Vector(JsNumber(id), JsNumber(_))) =>
+      case JsArray(Vector(JsString(id), JsNumber(_))) =>
         assert(id == txIdWithoutParameter.meta.id)
       case _ => withClue(serializedTxIdWithoutParameter) { assert(false) }
     }
@@ -89,12 +89,12 @@ class SchemaTests extends FlatSpec with BeforeAndAfter with 
ExecHelpers with Mat
   }
 
   it should "serdes a transaction id with extraLogging parameter" in {
-    val txIdWithParameter = TransactionId(4711, true)
+    val txIdWithParameter = TransactionId("4711", true)
 
     // test serialization
     val serializedTxIdWithParameter = 
TransactionId.serdes.write(txIdWithParameter)
     serializedTxIdWithParameter match {
-      case JsArray(Vector(JsNumber(id), JsNumber(_), JsBoolean(extraLogging))) 
=>
+      case JsArray(Vector(JsString(id), JsNumber(_), JsBoolean(extraLogging))) 
=>
         assert(id == txIdWithParameter.meta.id)
         assert(extraLogging)
       case _ => withClue(serializedTxIdWithParameter) { assert(false) }

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

Reply via email to