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

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


The following commit(s) were added to refs/heads/master by this push:
     new 5de865c  Retry NoHttpResponseException for standalone mode in 
ApacheContainerClient (#4644)
5de865c is described below

commit 5de865c271ab6e82deacdf4d8dcd2f5025c02d97
Author: Chetan Mehrotra <[email protected]>
AuthorDate: Wed Sep 25 09:56:07 2019 +0530

    Retry NoHttpResponseException for standalone mode in ApacheContainerClient 
(#4644)
    
    Adding a new setting to enable retry of NoHttpResponseException based on 
configuration.
    
    This setting is enabled in standalone mode to workaround some Docker 
network issue where first call of `/init` fails due to this exception. Same 
init passes upon retry
---
 common/scala/src/main/resources/application.conf     |  8 ++++++++
 .../org/apache/openwhisk/core/WhiskConfig.scala      |  2 ++
 .../ApacheBlockingContainerClient.scala              | 12 +++++++++++-
 core/standalone/src/main/resources/standalone.conf   |  3 +++
 .../openwhisk/standalone/StandaloneServerTests.scala | 20 --------------------
 5 files changed, 24 insertions(+), 21 deletions(-)

diff --git a/common/scala/src/main/resources/application.conf 
b/common/scala/src/main/resources/application.conf
index f89a646..cfa7845 100644
--- a/common/scala/src/main/resources/application.conf
+++ b/common/scala/src/main/resources/application.conf
@@ -449,6 +449,14 @@ whisk {
         # for details
         require-api-key-annotation = true
     }
+
+    apache-client {
+        # By default Apache HTTP Client would not retry 
NoHttpResponseException cases
+        # For some setups like Standalone mode this setting may need to be 
enabled
+        # to work around some Docker network issue
+        # In general this setting should be left to its default disabled state
+        retry-no-http-response-exception = false
+    }
 }
 #placeholder for test overrides so that tests can override defaults in 
application.conf (todo: move all defaults to reference.conf)
 test {
diff --git 
a/common/scala/src/main/scala/org/apache/openwhisk/core/WhiskConfig.scala 
b/common/scala/src/main/scala/org/apache/openwhisk/core/WhiskConfig.scala
index 3b8e13f..b6fa765 100644
--- a/common/scala/src/main/scala/org/apache/openwhisk/core/WhiskConfig.scala
+++ b/common/scala/src/main/scala/org/apache/openwhisk/core/WhiskConfig.scala
@@ -263,4 +263,6 @@ object ConfigKeys {
 
   val whiskConfig = "whisk.config"
   val swaggerUi = "whisk.swagger-ui"
+
+  val apacheClientConfig = "whisk.apache-client"
 }
diff --git 
a/common/scala/src/main/scala/org/apache/openwhisk/core/containerpool/ApacheBlockingContainerClient.scala
 
b/common/scala/src/main/scala/org/apache/openwhisk/core/containerpool/ApacheBlockingContainerClient.scala
index f56d1eb..2cef635 100644
--- 
a/common/scala/src/main/scala/org/apache/openwhisk/core/containerpool/ApacheBlockingContainerClient.scala
+++ 
b/common/scala/src/main/scala/org/apache/openwhisk/core/containerpool/ApacheBlockingContainerClient.scala
@@ -22,7 +22,7 @@ import java.nio.charset.StandardCharsets
 import java.time.Instant
 
 import org.apache.commons.io.IOUtils
-import org.apache.http.HttpHeaders
+import org.apache.http.{HttpHeaders, NoHttpResponseException}
 import org.apache.http.client.config.RequestConfig
 import org.apache.http.client.methods.{HttpPost, HttpRequestBase}
 import org.apache.http.client.utils.{HttpClientUtils, URIBuilder}
@@ -34,9 +34,11 @@ import 
org.apache.http.impl.conn.PoolingHttpClientConnectionManager
 import org.apache.http.util.EntityUtils
 import spray.json._
 import org.apache.openwhisk.common.{Logging, TransactionId}
+import org.apache.openwhisk.core.ConfigKeys
 import org.apache.openwhisk.core.entity.ActivationResponse._
 import org.apache.openwhisk.core.entity.ByteSize
 import org.apache.openwhisk.core.entity.size.SizeLong
+import pureconfig.loadConfigOrThrow
 
 import scala.annotation.tailrec
 import scala.concurrent._
@@ -149,6 +151,11 @@ protected class ApacheBlockingContainerClient(hostname: 
String,
       //
       // NoRouteToHostException: route to target host is not known (yet).
       case t: NoRouteToHostException => Failure(RetryableConnectionError(t))
+
+      //In general with NoHttpResponseException it cannot be said if server 
has processed the request or not
+      //For some cases like in standalone mode setup it should be fine to retry
+      case t: NoHttpResponseException if 
ApacheBlockingContainerClient.clientConfig.retryNoHttpResponseException =>
+        Failure(RetryableConnectionError(t))
     } match {
       case Success(response) => response
       case Failure(t: RetryableConnectionError) if retry =>
@@ -201,7 +208,10 @@ protected class ApacheBlockingContainerClient(hostname: 
String,
     .build
 }
 
+case class ApacheClientConfig(retryNoHttpResponseException: Boolean)
+
 object ApacheBlockingContainerClient {
+  val clientConfig: ApacheClientConfig = 
loadConfigOrThrow[ApacheClientConfig](ConfigKeys.apacheClientConfig)
 
   /** A helper method to post one single request to a connection. Used for 
container tests. */
   def post(host: String, port: Int, endPoint: String, content: JsValue)(
diff --git a/core/standalone/src/main/resources/standalone.conf 
b/core/standalone/src/main/resources/standalone.conf
index 2887356..4d3463b 100644
--- a/core/standalone/src/main/resources/standalone.conf
+++ b/core/standalone/src/main/resources/standalone.conf
@@ -115,4 +115,7 @@ whisk {
       ]
     }
   }
+  apache-client {
+    retry-no-http-response-exception = true
+  }
 }
diff --git 
a/tests/src/test/scala/org/apache/openwhisk/standalone/StandaloneServerTests.scala
 
b/tests/src/test/scala/org/apache/openwhisk/standalone/StandaloneServerTests.scala
index 5699ec1..725033c 100644
--- 
a/tests/src/test/scala/org/apache/openwhisk/standalone/StandaloneServerTests.scala
+++ 
b/tests/src/test/scala/org/apache/openwhisk/standalone/StandaloneServerTests.scala
@@ -18,31 +18,11 @@
 package org.apache.openwhisk.standalone
 
 import common.WskProps
-import org.apache.commons.lang3.SystemUtils
 import org.junit.runner.RunWith
-import org.scalatest.Pending
 import org.scalatest.junit.JUnitRunner
 import system.basic.WskRestBasicTests
 
 @RunWith(classOf[JUnitRunner])
 class StandaloneServerTests extends WskRestBasicTests with 
StandaloneServerFixture {
   override implicit val wskprops = WskProps().copy(apihost = serverUrl)
-
-  //Following tests always fail on Mac but pass when standalone server is 
running on Linux
-  //It looks related to how networking works on Mac for Docker container
-  //For now ignoring there failure
-  private val ignoredTestsOnMac = Set(
-    "Wsk Action REST should create, and invoke an action that utilizes a 
docker container",
-    "Wsk Action REST should create, and invoke an action that utilizes 
dockerskeleton with native zip",
-    "Wsk Action REST should create and invoke a blocking action resulting in 
an application error response",
-    "Wsk Action REST should create an action, and invoke an action that 
returns an empty JSON object")
-
-  override def withFixture(test: NoArgTest) = {
-    val outcome = super.withFixture(test)
-    val result = if (outcome.isFailed && SystemUtils.IS_OS_MAC && 
ignoredTestsOnMac.contains(test.name)) {
-      println(s"Ignoring known failed test for Mac [${test.name}]")
-      Pending
-    } else outcome
-    result
-  }
 }

Reply via email to