[GitHub] tysonnorris commented on a change in pull request #3812: ContainerClient + akka http alternative to HttpUtils
tysonnorris commented on a change in pull request #3812: ContainerClient + akka http alternative to HttpUtils URL: https://github.com/apache/incubator-openwhisk/pull/3812#discussion_r202558847 ## File path: common/scala/src/main/scala/whisk/core/containerpool/ContainerClient.scala ## @@ -0,0 +1,205 @@ +/* + * 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.containerpool + +import akka.actor.ActorSystem +import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport._ +import akka.http.scaladsl.marshalling.Marshal +import akka.http.scaladsl.model.HttpMethods +import akka.http.scaladsl.model.HttpRequest +import akka.http.scaladsl.model.HttpResponse +import akka.http.scaladsl.model.MessageEntity +import akka.http.scaladsl.unmarshalling.Unmarshal +import scala.concurrent.Await +import scala.concurrent.ExecutionContext +import scala.concurrent.Future +import scala.concurrent.Promise +import scala.concurrent.TimeoutException +import scala.concurrent.duration._ +import scala.util.Try +import scala.util.control.NoStackTrace +import spray.json._ +import whisk.common.Logging +import whisk.common.TransactionId +import whisk.core.entity.ActivationResponse.ContainerHttpError +import whisk.core.entity.ActivationResponse._ +import whisk.core.entity.ByteSize +import whisk.core.entity.size.SizeLong +import whisk.http.PoolingRestClient + +trait ContainerClient { + def close(): Unit + def post(endpoint: String, body: JsValue, retry: Boolean)( +implicit tid: TransactionId, +ec: ExecutionContext): Future[Either[ContainerHttpError, ContainerResponse]] + +} + +/** + * This HTTP client is used only in the invoker to communicate with the action container. + * It allows to POST a JSON object and receive JSON object back; that is the + * content type and the accept headers are both 'application/json. + * The reason we still use this class for the action container is a mysterious hang + * in the Akka http client where a future fails to properly timeout and we have not + * determined why that is. + * + * @param hostname the host name + * @param timeout the timeout in msecs to wait for a response + * @param maxResponse the maximum size in bytes the connection will accept + * @param queueSize once all connections are used, how big of queue to allow for additional requests + * @param retryInterval duration between retries for TCP connection errors + */ +protected class PoolingContainerClient( + hostname: String, + port: Int, + timeout: FiniteDuration, + maxResponse: ByteSize, + queueSize: Int, + retryInterval: FiniteDuration = 100.milliseconds)(implicit logging: Logging, as: ActorSystem) +extends PoolingRestClient("http", hostname, port, queueSize) +with ContainerClient { + + def close() = shutdown() + + /** + * Posts to hostname/endpoint the given JSON object. + * Waits up to timeout before aborting on a good connection. + * If the endpoint is not ready, retry up to timeout. + * Every retry reduces the available timeout so that this method should not + * wait longer than the total timeout (within a small slack allowance). + * + * @param endpoint the path the api call relative to hostname + * @param body the JSON value to post (this is usually a JSON objecT) + * @param retry whether or not to retry on connection failure + * @return Left(Error Message) or Right(Status Code, Response as UTF-8 String) + */ + def post(endpoint: String, body: JsValue, retry: Boolean)( +implicit tid: TransactionId, +ec: ExecutionContext): Future[Either[ContainerHttpError, ContainerResponse]] = { + +//create the request +val req = Marshal(body).to[MessageEntity].map { b => + HttpRequest(HttpMethods.POST, endpoint, entity = b) +} + +//Begin retry handling + +//Handle retries by: +// - tracking request as a promise +// - attaching a timeout to fail the promise +// - create a function to enqueue the request +// - retry (using same function) on StreamTcpException (only if retry == true) + +val promise = Promise[HttpResponse] + +// Timeout includes all retries. +as.scheduler.scheduleOnce(timeout) { + promise.tryFailure(new
[GitHub] tysonnorris commented on a change in pull request #3812: ContainerClient + akka http alternative to HttpUtils
tysonnorris commented on a change in pull request #3812: ContainerClient + akka http alternative to HttpUtils URL: https://github.com/apache/incubator-openwhisk/pull/3812#discussion_r202549203 ## File path: common/scala/src/main/scala/whisk/core/containerpool/ContainerClient.scala ## @@ -0,0 +1,205 @@ +/* + * 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.containerpool + +import akka.actor.ActorSystem +import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport._ +import akka.http.scaladsl.marshalling.Marshal +import akka.http.scaladsl.model.HttpMethods +import akka.http.scaladsl.model.HttpRequest +import akka.http.scaladsl.model.HttpResponse +import akka.http.scaladsl.model.MessageEntity +import akka.http.scaladsl.unmarshalling.Unmarshal +import scala.concurrent.Await +import scala.concurrent.ExecutionContext +import scala.concurrent.Future +import scala.concurrent.Promise +import scala.concurrent.TimeoutException +import scala.concurrent.duration._ +import scala.util.Try +import scala.util.control.NoStackTrace +import spray.json._ +import whisk.common.Logging +import whisk.common.TransactionId +import whisk.core.entity.ActivationResponse.ContainerHttpError +import whisk.core.entity.ActivationResponse._ +import whisk.core.entity.ByteSize +import whisk.core.entity.size.SizeLong +import whisk.http.PoolingRestClient + +trait ContainerClient { + def close(): Unit + def post(endpoint: String, body: JsValue, retry: Boolean)( +implicit tid: TransactionId, +ec: ExecutionContext): Future[Either[ContainerHttpError, ContainerResponse]] + +} + +/** + * This HTTP client is used only in the invoker to communicate with the action container. + * It allows to POST a JSON object and receive JSON object back; that is the + * content type and the accept headers are both 'application/json. + * The reason we still use this class for the action container is a mysterious hang + * in the Akka http client where a future fails to properly timeout and we have not + * determined why that is. + * + * @param hostname the host name + * @param timeout the timeout in msecs to wait for a response + * @param maxResponse the maximum size in bytes the connection will accept + * @param queueSize once all connections are used, how big of queue to allow for additional requests + * @param retryInterval duration between retries for TCP connection errors + */ +protected class PoolingContainerClient( + hostname: String, + port: Int, + timeout: FiniteDuration, + maxResponse: ByteSize, + queueSize: Int, + retryInterval: FiniteDuration = 100.milliseconds)(implicit logging: Logging, as: ActorSystem) +extends PoolingRestClient("http", hostname, port, queueSize) +with ContainerClient { + + def close() = shutdown() + + /** + * Posts to hostname/endpoint the given JSON object. + * Waits up to timeout before aborting on a good connection. + * If the endpoint is not ready, retry up to timeout. + * Every retry reduces the available timeout so that this method should not + * wait longer than the total timeout (within a small slack allowance). + * + * @param endpoint the path the api call relative to hostname + * @param body the JSON value to post (this is usually a JSON objecT) + * @param retry whether or not to retry on connection failure + * @return Left(Error Message) or Right(Status Code, Response as UTF-8 String) + */ + def post(endpoint: String, body: JsValue, retry: Boolean)( +implicit tid: TransactionId, +ec: ExecutionContext): Future[Either[ContainerHttpError, ContainerResponse]] = { + +//create the request +val req = Marshal(body).to[MessageEntity].map { b => + HttpRequest(HttpMethods.POST, endpoint, entity = b) +} + +//Begin retry handling + +//Handle retries by: +// - tracking request as a promise +// - attaching a timeout to fail the promise +// - create a function to enqueue the request +// - retry (using same function) on StreamTcpException (only if retry == true) + +val promise = Promise[HttpResponse] + +// Timeout includes all retries. +as.scheduler.scheduleOnce(timeout) { + promise.tryFailure(new
[GitHub] tysonnorris commented on a change in pull request #3812: ContainerClient + akka http alternative to HttpUtils
tysonnorris commented on a change in pull request #3812: ContainerClient + akka http alternative to HttpUtils URL: https://github.com/apache/incubator-openwhisk/pull/3812#discussion_r202549203 ## File path: common/scala/src/main/scala/whisk/core/containerpool/ContainerClient.scala ## @@ -0,0 +1,205 @@ +/* + * 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.containerpool + +import akka.actor.ActorSystem +import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport._ +import akka.http.scaladsl.marshalling.Marshal +import akka.http.scaladsl.model.HttpMethods +import akka.http.scaladsl.model.HttpRequest +import akka.http.scaladsl.model.HttpResponse +import akka.http.scaladsl.model.MessageEntity +import akka.http.scaladsl.unmarshalling.Unmarshal +import scala.concurrent.Await +import scala.concurrent.ExecutionContext +import scala.concurrent.Future +import scala.concurrent.Promise +import scala.concurrent.TimeoutException +import scala.concurrent.duration._ +import scala.util.Try +import scala.util.control.NoStackTrace +import spray.json._ +import whisk.common.Logging +import whisk.common.TransactionId +import whisk.core.entity.ActivationResponse.ContainerHttpError +import whisk.core.entity.ActivationResponse._ +import whisk.core.entity.ByteSize +import whisk.core.entity.size.SizeLong +import whisk.http.PoolingRestClient + +trait ContainerClient { + def close(): Unit + def post(endpoint: String, body: JsValue, retry: Boolean)( +implicit tid: TransactionId, +ec: ExecutionContext): Future[Either[ContainerHttpError, ContainerResponse]] + +} + +/** + * This HTTP client is used only in the invoker to communicate with the action container. + * It allows to POST a JSON object and receive JSON object back; that is the + * content type and the accept headers are both 'application/json. + * The reason we still use this class for the action container is a mysterious hang + * in the Akka http client where a future fails to properly timeout and we have not + * determined why that is. + * + * @param hostname the host name + * @param timeout the timeout in msecs to wait for a response + * @param maxResponse the maximum size in bytes the connection will accept + * @param queueSize once all connections are used, how big of queue to allow for additional requests + * @param retryInterval duration between retries for TCP connection errors + */ +protected class PoolingContainerClient( + hostname: String, + port: Int, + timeout: FiniteDuration, + maxResponse: ByteSize, + queueSize: Int, + retryInterval: FiniteDuration = 100.milliseconds)(implicit logging: Logging, as: ActorSystem) +extends PoolingRestClient("http", hostname, port, queueSize) +with ContainerClient { + + def close() = shutdown() + + /** + * Posts to hostname/endpoint the given JSON object. + * Waits up to timeout before aborting on a good connection. + * If the endpoint is not ready, retry up to timeout. + * Every retry reduces the available timeout so that this method should not + * wait longer than the total timeout (within a small slack allowance). + * + * @param endpoint the path the api call relative to hostname + * @param body the JSON value to post (this is usually a JSON objecT) + * @param retry whether or not to retry on connection failure + * @return Left(Error Message) or Right(Status Code, Response as UTF-8 String) + */ + def post(endpoint: String, body: JsValue, retry: Boolean)( +implicit tid: TransactionId, +ec: ExecutionContext): Future[Either[ContainerHttpError, ContainerResponse]] = { + +//create the request +val req = Marshal(body).to[MessageEntity].map { b => + HttpRequest(HttpMethods.POST, endpoint, entity = b) +} + +//Begin retry handling + +//Handle retries by: +// - tracking request as a promise +// - attaching a timeout to fail the promise +// - create a function to enqueue the request +// - retry (using same function) on StreamTcpException (only if retry == true) + +val promise = Promise[HttpResponse] + +// Timeout includes all retries. +as.scheduler.scheduleOnce(timeout) { + promise.tryFailure(new
[GitHub] rabbah edited a comment on issue #131: wsk property get does not work if api host is not set
rabbah edited a comment on issue #131: wsk property get does not work if api host is not set URL: https://github.com/apache/incubator-openwhisk-cli/issues/131#issuecomment-405099083 the default bluemix host is gone but you still have to provide an api host to see the config/properties so this bug is still an open defect. The workaround is to add a bogus host like this `--apihost xxx`. 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: us...@infra.apache.org With regards, Apache Git Services
[GitHub] rabbah commented on issue #131: wsk property get does not work if api host is not set
rabbah commented on issue #131: wsk property get does not work if api host is not set URL: https://github.com/apache/incubator-openwhisk-cli/issues/131#issuecomment-405099083 the default bluemix host is gone but you still have to provide an api host to see the parameters so this bug is still an open defect. The workaround is to add a bogus host like this `--apihost xxx`. 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: us...@infra.apache.org With regards, Apache Git Services
[GitHub] rabbah opened a new issue #97: remove references to bluemix
rabbah opened a new issue #97: remove references to bluemix URL: https://github.com/apache/incubator-openwhisk-client-go/issues/97 https://github.com/apache/incubator-openwhisk-client-go/blob/df79c14dab895db6f2371fb5dbe734a4a1185ceb/whisk/client.go#L83 and in the readme file here https://github.com/apache/incubator-openwhisk-client-go/search?q=bluemix_q=bluemix 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: us...@infra.apache.org With regards, Apache Git Services
[GitHub] rabbah closed pull request #3879: Adding enforceEmptyErrorStream check to testEcho
rabbah closed pull request #3879: Adding enforceEmptyErrorStream check to testEcho URL: https://github.com/apache/incubator-openwhisk/pull/3879 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/tests/src/test/scala/actionContainers/BasicActionRunnerTests.scala b/tests/src/test/scala/actionContainers/BasicActionRunnerTests.scala index 07d028dc8a..4b3d8938d5 100644 --- a/tests/src/test/scala/actionContainers/BasicActionRunnerTests.scala +++ b/tests/src/test/scala/actionContainers/BasicActionRunnerTests.scala @@ -238,7 +238,8 @@ trait BasicActionRunnerTests extends ActionProxyContainerTestUtils { checkStreams(out, err, { case (o, e) => o should include("hello stdout") -e should include("hello stderr") +// some languages may not support printing to stderr +if (!config.skipTest) e should include("hello stderr") }, argss.length) } 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: us...@infra.apache.org With regards, Apache Git Services
[GitHub] codecov-io edited a comment on issue #3879: Adding enforceEmptyErrorStream check to testEcho
codecov-io edited a comment on issue #3879: Adding enforceEmptyErrorStream check to testEcho URL: https://github.com/apache/incubator-openwhisk/pull/3879#issuecomment-405082077 # [Codecov](https://codecov.io/gh/apache/incubator-openwhisk/pull/3879?src=pr=h1) Report > Merging [#3879](https://codecov.io/gh/apache/incubator-openwhisk/pull/3879?src=pr=desc) into [master](https://codecov.io/gh/apache/incubator-openwhisk/commit/ae2ba8497c45bef38eeff8643e95687b307f67ff?src=pr=desc) will **decrease** coverage by `4.78%`. > The diff coverage is `n/a`. [![Impacted file tree graph](https://codecov.io/gh/apache/incubator-openwhisk/pull/3879/graphs/tree.svg?token=l0YmsiSAso=650=150=pr)](https://codecov.io/gh/apache/incubator-openwhisk/pull/3879?src=pr=tree) ```diff @@Coverage Diff @@ ## master#3879 +/- ## == - Coverage 75.81% 71.03% -4.79% == Files 146 146 Lines6902 6902 Branches 428 428 == - Hits 5233 4903 -330 - Misses 1669 1999 +330 ``` | [Impacted Files](https://codecov.io/gh/apache/incubator-openwhisk/pull/3879?src=pr=tree) | Coverage Δ | | |---|---|---| | [...core/database/cosmosdb/RxObservableImplicits.scala](https://codecov.io/gh/apache/incubator-openwhisk/pull/3879/diff?src=pr=tree#diff-Y29tbW9uL3NjYWxhL3NyYy9tYWluL3NjYWxhL3doaXNrL2NvcmUvZGF0YWJhc2UvY29zbW9zZGIvUnhPYnNlcnZhYmxlSW1wbGljaXRzLnNjYWxh) | `0% <0%> (-100%)` | :arrow_down: | | [...core/database/cosmosdb/CosmosDBArtifactStore.scala](https://codecov.io/gh/apache/incubator-openwhisk/pull/3879/diff?src=pr=tree#diff-Y29tbW9uL3NjYWxhL3NyYy9tYWluL3NjYWxhL3doaXNrL2NvcmUvZGF0YWJhc2UvY29zbW9zZGIvQ29zbW9zREJBcnRpZmFjdFN0b3JlLnNjYWxh) | `0% <0%> (-95.08%)` | :arrow_down: | | [...sk/core/database/cosmosdb/CosmosDBViewMapper.scala](https://codecov.io/gh/apache/incubator-openwhisk/pull/3879/diff?src=pr=tree#diff-Y29tbW9uL3NjYWxhL3NyYy9tYWluL3NjYWxhL3doaXNrL2NvcmUvZGF0YWJhc2UvY29zbW9zZGIvQ29zbW9zREJWaWV3TWFwcGVyLnNjYWxh) | `0% <0%> (-92.6%)` | :arrow_down: | | [...whisk/core/database/cosmosdb/CosmosDBSupport.scala](https://codecov.io/gh/apache/incubator-openwhisk/pull/3879/diff?src=pr=tree#diff-Y29tbW9uL3NjYWxhL3NyYy9tYWluL3NjYWxhL3doaXNrL2NvcmUvZGF0YWJhc2UvY29zbW9zZGIvQ29zbW9zREJTdXBwb3J0LnNjYWxh) | `0% <0%> (-81.82%)` | :arrow_down: | | [...abase/cosmosdb/CosmosDBArtifactStoreProvider.scala](https://codecov.io/gh/apache/incubator-openwhisk/pull/3879/diff?src=pr=tree#diff-Y29tbW9uL3NjYWxhL3NyYy9tYWluL3NjYWxhL3doaXNrL2NvcmUvZGF0YWJhc2UvY29zbW9zZGIvQ29zbW9zREJBcnRpZmFjdFN0b3JlUHJvdmlkZXIuc2NhbGE=) | `0% <0%> (-58.83%)` | :arrow_down: | | [...la/whisk/core/database/cosmosdb/CosmosDBUtil.scala](https://codecov.io/gh/apache/incubator-openwhisk/pull/3879/diff?src=pr=tree#diff-Y29tbW9uL3NjYWxhL3NyYy9tYWluL3NjYWxhL3doaXNrL2NvcmUvZGF0YWJhc2UvY29zbW9zZGIvQ29zbW9zREJVdGlsLnNjYWxh) | `92% <0%> (-4%)` | :arrow_down: | -- [Continue to review full report at Codecov](https://codecov.io/gh/apache/incubator-openwhisk/pull/3879?src=pr=continue). > **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta) > `Δ = absolute (impact)`, `ø = not affected`, `? = missing data` > Powered by [Codecov](https://codecov.io/gh/apache/incubator-openwhisk/pull/3879?src=pr=footer). Last update [ae2ba84...8411ef4](https://codecov.io/gh/apache/incubator-openwhisk/pull/3879?src=pr=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments). 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: us...@infra.apache.org With regards, Apache Git Services
[GitHub] markusthoemmes commented on a change in pull request #3812: ContainerClient + akka http alternative to HttpUtils
markusthoemmes commented on a change in pull request #3812: ContainerClient + akka http alternative to HttpUtils URL: https://github.com/apache/incubator-openwhisk/pull/3812#discussion_r198376954 ## File path: common/scala/src/main/scala/whisk/core/containerpool/ContainerClient.scala ## @@ -0,0 +1,205 @@ +/* + * 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.containerpool + +import akka.actor.ActorSystem +import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport._ +import akka.http.scaladsl.marshalling.Marshal +import akka.http.scaladsl.model.HttpMethods +import akka.http.scaladsl.model.HttpRequest +import akka.http.scaladsl.model.HttpResponse +import akka.http.scaladsl.model.MessageEntity +import akka.http.scaladsl.unmarshalling.Unmarshal +import scala.concurrent.Await +import scala.concurrent.ExecutionContext +import scala.concurrent.Future +import scala.concurrent.Promise +import scala.concurrent.TimeoutException +import scala.concurrent.duration._ +import scala.util.Try +import scala.util.control.NoStackTrace +import spray.json._ +import whisk.common.Logging +import whisk.common.TransactionId +import whisk.core.entity.ActivationResponse.ContainerHttpError +import whisk.core.entity.ActivationResponse._ +import whisk.core.entity.ByteSize +import whisk.core.entity.size.SizeLong +import whisk.http.PoolingRestClient + +trait ContainerClient { + def close(): Unit + def post(endpoint: String, body: JsValue, retry: Boolean)( +implicit tid: TransactionId, +ec: ExecutionContext): Future[Either[ContainerHttpError, ContainerResponse]] + +} + +/** + * This HTTP client is used only in the invoker to communicate with the action container. + * It allows to POST a JSON object and receive JSON object back; that is the + * content type and the accept headers are both 'application/json. + * The reason we still use this class for the action container is a mysterious hang + * in the Akka http client where a future fails to properly timeout and we have not + * determined why that is. + * + * @param hostname the host name + * @param timeout the timeout in msecs to wait for a response + * @param maxResponse the maximum size in bytes the connection will accept + * @param queueSize once all connections are used, how big of queue to allow for additional requests + * @param retryInterval duration between retries for TCP connection errors + */ +protected class PoolingContainerClient( + hostname: String, + port: Int, + timeout: FiniteDuration, + maxResponse: ByteSize, + queueSize: Int, + retryInterval: FiniteDuration = 100.milliseconds)(implicit logging: Logging, as: ActorSystem) +extends PoolingRestClient("http", hostname, port, queueSize) +with ContainerClient { + + def close() = shutdown() + + /** + * Posts to hostname/endpoint the given JSON object. + * Waits up to timeout before aborting on a good connection. + * If the endpoint is not ready, retry up to timeout. + * Every retry reduces the available timeout so that this method should not + * wait longer than the total timeout (within a small slack allowance). + * + * @param endpoint the path the api call relative to hostname + * @param body the JSON value to post (this is usually a JSON objecT) + * @param retry whether or not to retry on connection failure + * @return Left(Error Message) or Right(Status Code, Response as UTF-8 String) + */ + def post(endpoint: String, body: JsValue, retry: Boolean)( +implicit tid: TransactionId, +ec: ExecutionContext): Future[Either[ContainerHttpError, ContainerResponse]] = { + +//create the request +val req = Marshal(body).to[MessageEntity].map { b => + HttpRequest(HttpMethods.POST, endpoint, entity = b) +} + +//Begin retry handling + +//Handle retries by: +// - tracking request as a promise +// - attaching a timeout to fail the promise +// - create a function to enqueue the request +// - retry (using same function) on StreamTcpException (only if retry == true) + +val promise = Promise[HttpResponse] + +// Timeout includes all retries. +as.scheduler.scheduleOnce(timeout) { + promise.tryFailure(new
[GitHub] markusthoemmes commented on a change in pull request #3812: ContainerClient + akka http alternative to HttpUtils
markusthoemmes commented on a change in pull request #3812: ContainerClient + akka http alternative to HttpUtils URL: https://github.com/apache/incubator-openwhisk/pull/3812#discussion_r202540170 ## File path: common/scala/src/main/scala/whisk/core/containerpool/ContainerClient.scala ## @@ -0,0 +1,240 @@ +/* + * 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.containerpool + +import akka.actor.ActorSystem +import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport._ +import akka.http.scaladsl.marshalling.Marshal +import akka.http.scaladsl.model.HttpMethods +import akka.http.scaladsl.model.HttpRequest +import akka.http.scaladsl.model.HttpResponse +import akka.http.scaladsl.model.MessageEntity +import akka.http.scaladsl.model.StatusCodes +import akka.http.scaladsl.model.headers.Connection +import akka.http.scaladsl.unmarshalling.Unmarshal +import akka.stream.scaladsl.Sink +import akka.stream.scaladsl.Source +import akka.util.ByteString +import scala.concurrent.Await +import scala.concurrent.ExecutionContext +import scala.concurrent.Future +import scala.concurrent.Promise +import scala.concurrent.TimeoutException +import scala.concurrent.duration._ +import scala.util.Try +import scala.util.control.NoStackTrace +import spray.json._ +import whisk.common.Logging +import whisk.common.TransactionId +import whisk.core.entity.ActivationResponse.ContainerHttpError +import whisk.core.entity.ActivationResponse._ +import whisk.core.entity.ByteSize +import whisk.core.entity.size.SizeLong +import whisk.http.PoolingRestClient + +trait ContainerClient { + def close(): Unit + def post(endpoint: String, body: JsValue, retry: Boolean)( +implicit tid: TransactionId): Future[Either[ContainerHttpError, ContainerResponse]] + +} + +/** + * This HTTP client is used only in the invoker to communicate with the action container. + * It allows to POST a JSON object and receive JSON object back; that is the + * content type and the accept headers are both 'application/json. + * The reason we still use this class for the action container is a mysterious hang + * in the Akka http client where a future fails to properly timeout and we have not + * determined why that is. + * + * @param hostname the host name + * @param timeout the timeout in msecs to wait for a response + * @param maxResponse the maximum size in bytes the connection will accept + * @param queueSize once all connections are used, how big of queue to allow for additional requests + * @param retryInterval duration between retries for TCP connection errors + */ +protected class PoolingContainerClient( + hostname: String, + port: Int, + timeout: FiniteDuration, + maxResponse: ByteSize, + queueSize: Int, + retryInterval: FiniteDuration = 100.milliseconds)(implicit logging: Logging, as: ActorSystem) +extends PoolingRestClient("http", hostname, port, queueSize) +with ContainerClient { + + def close() = shutdown() + + /** + * Posts to hostname/endpoint the given JSON object. + * Waits up to timeout before aborting on a good connection. + * If the endpoint is not ready, retry up to timeout. + * Every retry reduces the available timeout so that this method should not + * wait longer than the total timeout (within a small slack allowance). + * + * @param endpoint the path the api call relative to hostname + * @param body the JSON value to post (this is usually a JSON objecT) + * @param retry whether or not to retry on connection failure + * @return Left(Error Message) or Right(Status Code, Response as UTF-8 String) + */ + def post(endpoint: String, body: JsValue, retry: Boolean)( +implicit tid: TransactionId): Future[Either[ContainerHttpError, ContainerResponse]] = { + +//create the request +val req = Marshal(body).to[MessageEntity].map { b => + //DO NOT reuse the connection (in case of paused containers) + //For details on Connection: Close handling, see: + // - https://doc.akka.io/docs/akka-http/current/common/http-model.html#http-headers + // - http://github.com/akka/akka-http/tree/v10.1.3/akka-http-core/src/test/scala/akka/http/impl/engine/rendering/ResponseRendererSpec.scala#L470-L571 +
[GitHub] markusthoemmes commented on a change in pull request #3812: ContainerClient + akka http alternative to HttpUtils
markusthoemmes commented on a change in pull request #3812: ContainerClient + akka http alternative to HttpUtils URL: https://github.com/apache/incubator-openwhisk/pull/3812#discussion_r198375689 ## File path: common/scala/src/main/scala/whisk/core/containerpool/ContainerClient.scala ## @@ -0,0 +1,205 @@ +/* + * 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.containerpool + +import akka.actor.ActorSystem +import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport._ +import akka.http.scaladsl.marshalling.Marshal +import akka.http.scaladsl.model.HttpMethods +import akka.http.scaladsl.model.HttpRequest +import akka.http.scaladsl.model.HttpResponse +import akka.http.scaladsl.model.MessageEntity +import akka.http.scaladsl.unmarshalling.Unmarshal +import scala.concurrent.Await +import scala.concurrent.ExecutionContext +import scala.concurrent.Future +import scala.concurrent.Promise +import scala.concurrent.TimeoutException +import scala.concurrent.duration._ +import scala.util.Try +import scala.util.control.NoStackTrace +import spray.json._ +import whisk.common.Logging +import whisk.common.TransactionId +import whisk.core.entity.ActivationResponse.ContainerHttpError +import whisk.core.entity.ActivationResponse._ +import whisk.core.entity.ByteSize +import whisk.core.entity.size.SizeLong +import whisk.http.PoolingRestClient + +trait ContainerClient { + def close(): Unit Review comment: Could we implement `java.lang.AutoCloseable` instead? Gives you the niceness of integrating into the `try with resource` world (although that's not needed here). 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: us...@infra.apache.org With regards, Apache Git Services
[GitHub] markusthoemmes commented on a change in pull request #3812: ContainerClient + akka http alternative to HttpUtils
markusthoemmes commented on a change in pull request #3812: ContainerClient + akka http alternative to HttpUtils URL: https://github.com/apache/incubator-openwhisk/pull/3812#discussion_r202540190 ## File path: common/scala/src/main/scala/whisk/core/containerpool/ContainerClient.scala ## @@ -0,0 +1,240 @@ +/* + * 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.containerpool + +import akka.actor.ActorSystem +import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport._ +import akka.http.scaladsl.marshalling.Marshal +import akka.http.scaladsl.model.HttpMethods +import akka.http.scaladsl.model.HttpRequest +import akka.http.scaladsl.model.HttpResponse +import akka.http.scaladsl.model.MessageEntity +import akka.http.scaladsl.model.StatusCodes +import akka.http.scaladsl.model.headers.Connection +import akka.http.scaladsl.unmarshalling.Unmarshal +import akka.stream.scaladsl.Sink +import akka.stream.scaladsl.Source +import akka.util.ByteString +import scala.concurrent.Await +import scala.concurrent.ExecutionContext +import scala.concurrent.Future +import scala.concurrent.Promise +import scala.concurrent.TimeoutException +import scala.concurrent.duration._ +import scala.util.Try +import scala.util.control.NoStackTrace +import spray.json._ +import whisk.common.Logging +import whisk.common.TransactionId +import whisk.core.entity.ActivationResponse.ContainerHttpError +import whisk.core.entity.ActivationResponse._ +import whisk.core.entity.ByteSize +import whisk.core.entity.size.SizeLong +import whisk.http.PoolingRestClient + +trait ContainerClient { + def close(): Unit + def post(endpoint: String, body: JsValue, retry: Boolean)( +implicit tid: TransactionId): Future[Either[ContainerHttpError, ContainerResponse]] + +} + +/** + * This HTTP client is used only in the invoker to communicate with the action container. + * It allows to POST a JSON object and receive JSON object back; that is the + * content type and the accept headers are both 'application/json. + * The reason we still use this class for the action container is a mysterious hang + * in the Akka http client where a future fails to properly timeout and we have not + * determined why that is. + * + * @param hostname the host name + * @param timeout the timeout in msecs to wait for a response + * @param maxResponse the maximum size in bytes the connection will accept + * @param queueSize once all connections are used, how big of queue to allow for additional requests + * @param retryInterval duration between retries for TCP connection errors + */ +protected class PoolingContainerClient( + hostname: String, + port: Int, + timeout: FiniteDuration, + maxResponse: ByteSize, + queueSize: Int, + retryInterval: FiniteDuration = 100.milliseconds)(implicit logging: Logging, as: ActorSystem) +extends PoolingRestClient("http", hostname, port, queueSize) +with ContainerClient { + + def close() = shutdown() + + /** + * Posts to hostname/endpoint the given JSON object. + * Waits up to timeout before aborting on a good connection. + * If the endpoint is not ready, retry up to timeout. + * Every retry reduces the available timeout so that this method should not + * wait longer than the total timeout (within a small slack allowance). + * + * @param endpoint the path the api call relative to hostname + * @param body the JSON value to post (this is usually a JSON objecT) + * @param retry whether or not to retry on connection failure + * @return Left(Error Message) or Right(Status Code, Response as UTF-8 String) + */ + def post(endpoint: String, body: JsValue, retry: Boolean)( +implicit tid: TransactionId): Future[Either[ContainerHttpError, ContainerResponse]] = { + +//create the request +val req = Marshal(body).to[MessageEntity].map { b => + //DO NOT reuse the connection (in case of paused containers) + //For details on Connection: Close handling, see: + // - https://doc.akka.io/docs/akka-http/current/common/http-model.html#http-headers + // - http://github.com/akka/akka-http/tree/v10.1.3/akka-http-core/src/test/scala/akka/http/impl/engine/rendering/ResponseRendererSpec.scala#L470-L571 +
[GitHub] markusthoemmes commented on a change in pull request #3812: ContainerClient + akka http alternative to HttpUtils
markusthoemmes commented on a change in pull request #3812: ContainerClient + akka http alternative to HttpUtils URL: https://github.com/apache/incubator-openwhisk/pull/3812#discussion_r198378345 ## File path: common/scala/src/main/scala/whisk/core/containerpool/ContainerClient.scala ## @@ -0,0 +1,205 @@ +/* + * 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.containerpool + +import akka.actor.ActorSystem +import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport._ +import akka.http.scaladsl.marshalling.Marshal +import akka.http.scaladsl.model.HttpMethods +import akka.http.scaladsl.model.HttpRequest +import akka.http.scaladsl.model.HttpResponse +import akka.http.scaladsl.model.MessageEntity +import akka.http.scaladsl.unmarshalling.Unmarshal +import scala.concurrent.Await +import scala.concurrent.ExecutionContext +import scala.concurrent.Future +import scala.concurrent.Promise +import scala.concurrent.TimeoutException +import scala.concurrent.duration._ +import scala.util.Try +import scala.util.control.NoStackTrace +import spray.json._ +import whisk.common.Logging +import whisk.common.TransactionId +import whisk.core.entity.ActivationResponse.ContainerHttpError +import whisk.core.entity.ActivationResponse._ +import whisk.core.entity.ByteSize +import whisk.core.entity.size.SizeLong +import whisk.http.PoolingRestClient + +trait ContainerClient { + def close(): Unit + def post(endpoint: String, body: JsValue, retry: Boolean)( +implicit tid: TransactionId, +ec: ExecutionContext): Future[Either[ContainerHttpError, ContainerResponse]] + +} + +/** + * This HTTP client is used only in the invoker to communicate with the action container. + * It allows to POST a JSON object and receive JSON object back; that is the + * content type and the accept headers are both 'application/json. + * The reason we still use this class for the action container is a mysterious hang + * in the Akka http client where a future fails to properly timeout and we have not + * determined why that is. + * + * @param hostname the host name + * @param timeout the timeout in msecs to wait for a response + * @param maxResponse the maximum size in bytes the connection will accept + * @param queueSize once all connections are used, how big of queue to allow for additional requests + * @param retryInterval duration between retries for TCP connection errors + */ +protected class PoolingContainerClient( + hostname: String, + port: Int, + timeout: FiniteDuration, + maxResponse: ByteSize, + queueSize: Int, + retryInterval: FiniteDuration = 100.milliseconds)(implicit logging: Logging, as: ActorSystem) +extends PoolingRestClient("http", hostname, port, queueSize) +with ContainerClient { + + def close() = shutdown() + + /** + * Posts to hostname/endpoint the given JSON object. + * Waits up to timeout before aborting on a good connection. + * If the endpoint is not ready, retry up to timeout. + * Every retry reduces the available timeout so that this method should not + * wait longer than the total timeout (within a small slack allowance). + * + * @param endpoint the path the api call relative to hostname + * @param body the JSON value to post (this is usually a JSON objecT) + * @param retry whether or not to retry on connection failure + * @return Left(Error Message) or Right(Status Code, Response as UTF-8 String) + */ + def post(endpoint: String, body: JsValue, retry: Boolean)( +implicit tid: TransactionId, +ec: ExecutionContext): Future[Either[ContainerHttpError, ContainerResponse]] = { + +//create the request +val req = Marshal(body).to[MessageEntity].map { b => + HttpRequest(HttpMethods.POST, endpoint, entity = b) +} + +//Begin retry handling + +//Handle retries by: +// - tracking request as a promise +// - attaching a timeout to fail the promise +// - create a function to enqueue the request +// - retry (using same function) on StreamTcpException (only if retry == true) + +val promise = Promise[HttpResponse] + +// Timeout includes all retries. +as.scheduler.scheduleOnce(timeout) { + promise.tryFailure(new
[GitHub] mpmunasinghe commented on issue #3879: Adding enforceEmptyErrorStream check to testEcho
mpmunasinghe commented on issue #3879: Adding enforceEmptyErrorStream check to testEcho URL: https://github.com/apache/incubator-openwhisk/pull/3879#issuecomment-405084761 @markusthoemmes for the moment ballerina doesn't write to stderr. 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: us...@infra.apache.org With regards, Apache Git Services
[GitHub] markusthoemmes commented on issue #3879: Adding enforceEmptyErrorStream check to testEcho
markusthoemmes commented on issue #3879: Adding enforceEmptyErrorStream check to testEcho URL: https://github.com/apache/incubator-openwhisk/pull/3879#issuecomment-405084176 Thanks for the contribution! Do you have an example of which runtime doesn't allow to write to stderr? 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: us...@infra.apache.org With regards, Apache Git Services
[GitHub] codecov-io commented on issue #3879: Adding enforceEmptyErrorStream check to testEcho
codecov-io commented on issue #3879: Adding enforceEmptyErrorStream check to testEcho URL: https://github.com/apache/incubator-openwhisk/pull/3879#issuecomment-405082077 # [Codecov](https://codecov.io/gh/apache/incubator-openwhisk/pull/3879?src=pr=h1) Report > Merging [#3879](https://codecov.io/gh/apache/incubator-openwhisk/pull/3879?src=pr=desc) into [master](https://codecov.io/gh/apache/incubator-openwhisk/commit/ae2ba8497c45bef38eeff8643e95687b307f67ff?src=pr=desc) will **decrease** coverage by `4.78%`. > The diff coverage is `n/a`. [![Impacted file tree graph](https://codecov.io/gh/apache/incubator-openwhisk/pull/3879/graphs/tree.svg?token=l0YmsiSAso=pr=150=650)](https://codecov.io/gh/apache/incubator-openwhisk/pull/3879?src=pr=tree) ```diff @@Coverage Diff @@ ## master#3879 +/- ## == - Coverage 75.81% 71.03% -4.79% == Files 146 146 Lines6902 6902 Branches 428 428 == - Hits 5233 4903 -330 - Misses 1669 1999 +330 ``` | [Impacted Files](https://codecov.io/gh/apache/incubator-openwhisk/pull/3879?src=pr=tree) | Coverage Δ | | |---|---|---| | [...core/database/cosmosdb/RxObservableImplicits.scala](https://codecov.io/gh/apache/incubator-openwhisk/pull/3879/diff?src=pr=tree#diff-Y29tbW9uL3NjYWxhL3NyYy9tYWluL3NjYWxhL3doaXNrL2NvcmUvZGF0YWJhc2UvY29zbW9zZGIvUnhPYnNlcnZhYmxlSW1wbGljaXRzLnNjYWxh) | `0% <0%> (-100%)` | :arrow_down: | | [...core/database/cosmosdb/CosmosDBArtifactStore.scala](https://codecov.io/gh/apache/incubator-openwhisk/pull/3879/diff?src=pr=tree#diff-Y29tbW9uL3NjYWxhL3NyYy9tYWluL3NjYWxhL3doaXNrL2NvcmUvZGF0YWJhc2UvY29zbW9zZGIvQ29zbW9zREJBcnRpZmFjdFN0b3JlLnNjYWxh) | `0% <0%> (-95.08%)` | :arrow_down: | | [...sk/core/database/cosmosdb/CosmosDBViewMapper.scala](https://codecov.io/gh/apache/incubator-openwhisk/pull/3879/diff?src=pr=tree#diff-Y29tbW9uL3NjYWxhL3NyYy9tYWluL3NjYWxhL3doaXNrL2NvcmUvZGF0YWJhc2UvY29zbW9zZGIvQ29zbW9zREJWaWV3TWFwcGVyLnNjYWxh) | `0% <0%> (-92.6%)` | :arrow_down: | | [...whisk/core/database/cosmosdb/CosmosDBSupport.scala](https://codecov.io/gh/apache/incubator-openwhisk/pull/3879/diff?src=pr=tree#diff-Y29tbW9uL3NjYWxhL3NyYy9tYWluL3NjYWxhL3doaXNrL2NvcmUvZGF0YWJhc2UvY29zbW9zZGIvQ29zbW9zREJTdXBwb3J0LnNjYWxh) | `0% <0%> (-81.82%)` | :arrow_down: | | [...abase/cosmosdb/CosmosDBArtifactStoreProvider.scala](https://codecov.io/gh/apache/incubator-openwhisk/pull/3879/diff?src=pr=tree#diff-Y29tbW9uL3NjYWxhL3NyYy9tYWluL3NjYWxhL3doaXNrL2NvcmUvZGF0YWJhc2UvY29zbW9zZGIvQ29zbW9zREJBcnRpZmFjdFN0b3JlUHJvdmlkZXIuc2NhbGE=) | `0% <0%> (-58.83%)` | :arrow_down: | | [...la/whisk/core/database/cosmosdb/CosmosDBUtil.scala](https://codecov.io/gh/apache/incubator-openwhisk/pull/3879/diff?src=pr=tree#diff-Y29tbW9uL3NjYWxhL3NyYy9tYWluL3NjYWxhL3doaXNrL2NvcmUvZGF0YWJhc2UvY29zbW9zZGIvQ29zbW9zREJVdGlsLnNjYWxh) | `92% <0%> (-4%)` | :arrow_down: | -- [Continue to review full report at Codecov](https://codecov.io/gh/apache/incubator-openwhisk/pull/3879?src=pr=continue). > **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta) > `Δ = absolute (impact)`, `ø = not affected`, `? = missing data` > Powered by [Codecov](https://codecov.io/gh/apache/incubator-openwhisk/pull/3879?src=pr=footer). Last update [ae2ba84...2241811](https://codecov.io/gh/apache/incubator-openwhisk/pull/3879?src=pr=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments). 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: us...@infra.apache.org With regards, Apache Git Services
[GitHub] mpmunasinghe opened a new pull request #3879: Adding enforceEmptyErrorStream check to testEcho
mpmunasinghe opened a new pull request #3879: Adding enforceEmptyErrorStream check to testEcho URL: https://github.com/apache/incubator-openwhisk/pull/3879 Some language runtimes doesn't write to standard error. Hence testEcho should be able to avoid checking for standard error. ## Description ## Related issue and scope - [ ] I opened an issue to propose and discuss this change (#) ## My changes affect the following components - [ ] API - [ ] Controller - [ ] Message Bus (e.g., Kafka) - [ ] Loadbalancer - [ ] Invoker - [ ] Intrinsic actions (e.g., sequences, conductors) - [ ] Data stores (e.g., CouchDB) - [x] Tests - [ ] Deployment - [ ] CLI - [ ] General tooling - [ ] Documentation ## Types of changes - [ ] Bug fix (generally a non-breaking change which closes an issue). - [ ] Enhancement or new feature (adds new functionality). - [x] Breaking change (a bug fix or enhancement which changes existing behavior). ## Checklist: - [x] I signed an [Apache CLA](https://github.com/apache/incubator-openwhisk/blob/master/CONTRIBUTING.md). - [x] I reviewed the [style guides](https://github.com/apache/incubator-openwhisk/wiki/Contributing:-Git-guidelines#code-readiness) and followed the recommendations (Travis CI will check :). - [ ] I added tests to cover my changes. - [ ] My changes require further changes to the documentation. - [ ] I updated the documentation where necessary. 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: us...@infra.apache.org With regards, Apache Git Services