This is an automated email from the ASF dual-hosted git repository. rabbah 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 5891f21 remove experimental web actions support 5891f21 is described below commit 5891f21435e8868a00806d4ecaeb01810545de74 Author: David Cariello <drcar...@us.ibm.com> AuthorDate: Wed Aug 30 19:17:11 2017 -0500 remove experimental web actions support --- .../scala/whisk/core/controller/RestAPIs.scala | 8 +- .../scala/whisk/core/controller/WebActions.scala | 20 +-- tests/src/test/scala/common/Wsk.scala | 93 ------------ .../whisk/core/cli/test/WskWebActionsTests.scala | 163 +++++++++------------ .../core/controller/test/WebActionsApiTests.scala | 25 +--- 5 files changed, 80 insertions(+), 229 deletions(-) diff --git a/core/controller/src/main/scala/whisk/core/controller/RestAPIs.scala b/core/controller/src/main/scala/whisk/core/controller/RestAPIs.scala index 5d4fc74..57b03ea 100644 --- a/core/controller/src/main/scala/whisk/core/controller/RestAPIs.scala +++ b/core/controller/src/main/scala/whisk/core/controller/RestAPIs.scala @@ -178,9 +178,9 @@ class RestAPIVersion(config: WhiskConfig, apiPath: String, apiVersion: String)( // web actions are distinct to separate the cors header // and allow the actions themselves to respond to options basicAuth(validateCredentials) { user => - web.routes(user) ~ webexp.routes(user) + web.routes(user) } ~ { - web.routes() ~ webexp.routes() + web.routes() } ~ options { sendCorsHeaders { complete(OK) @@ -197,8 +197,8 @@ class RestAPIVersion(config: WhiskConfig, apiPath: String, apiVersion: String)( private val triggers = new TriggersApi(apiPath, apiVersion) private val activations = new ActivationsApi(apiPath, apiVersion) private val rules = new RulesApi(apiPath, apiVersion) - private val webexp = new WebActionsApi(Seq("experimental", "web"), WebApiDirectives.exp) - private val web = new WebActionsApi(Seq("web"), WebApiDirectives.web) + private val WebApiDirectives = new WebApiDirectives() + private val web = new WebActionsApi(Seq("web"), this.WebApiDirectives) class NamespacesApi( val apiPath: String, diff --git a/core/controller/src/main/scala/whisk/core/controller/WebActions.scala b/core/controller/src/main/scala/whisk/core/controller/WebActions.scala index c963863..e527e8b 100644 --- a/core/controller/src/main/scala/whisk/core/controller/WebActions.scala +++ b/core/controller/src/main/scala/whisk/core/controller/WebActions.scala @@ -59,7 +59,7 @@ import whisk.http.ErrorResponse.terminate import whisk.http.Messages import whisk.utils.JsHelpers._ -protected[controller] sealed class WebApiDirectives private (prefix: String) { +protected[controller] sealed class WebApiDirectives (prefix: String = "__ow_") { // enforce the presence of an extension (e.g., .http) in the URI path val enforceExtension = false @@ -78,20 +78,6 @@ protected[controller] sealed class WebApiDirectives private (prefix: String) { protected final def fields(f: String) = s"$prefix$f" } -// field names for /web with raw-http action -protected[controller] object WebApiDirectives { - // field names for /web - val web = new WebApiDirectives("__ow_") - - // field names used for /experimental/web - val exp = new WebApiDirectives("__ow_meta_") { - override val enforceExtension = true - override val method = fields("verb") - override val namespace = fields("namespace") - override val statusCode = "code" - } -} - private case class Context( propertyMap: WebApiDirectives, method: HttpMethod, @@ -372,7 +358,7 @@ trait WhiskWebActionsApi /** * Adds route to web based activations. Actions invoked this way are anonymous in that the * caller is not authenticated. The intended action must be named in the path as a fully qualified - * name as in /experimental/web/some-namespace/some-package/some-action. The package is optional + * name as in /web/some-namespace/some-package/some-action. The package is optional * in that the action may be in the default package, in which case, the string "default" must be used. * If the action doesn't exist (or the namespace is not valid) NotFound is generated. Following the * action name, an "extension" is required to specify the desired content type for the response. This @@ -380,7 +366,7 @@ trait WhiskWebActionsApi * an text/html response. * * Optionally, the result form the action may be projected based on a named property. As in - * /experimental/web/some-namespace/some-package/some-action/some-property. If the property + * /web/some-namespace/some-package/some-action/some-property. If the property * does not exist in the result then a NotFound error is generated. A path of properties may * be supplied to project nested properties. * diff --git a/tests/src/test/scala/common/Wsk.scala b/tests/src/test/scala/common/Wsk.scala index c648d9f..c04cb94 100644 --- a/tests/src/test/scala/common/Wsk.scala +++ b/tests/src/test/scala/common/Wsk.scala @@ -97,7 +97,6 @@ class Wsk() extends RunWskCmd { implicit val pkg = new WskPackage implicit val namespace = new WskNamespace implicit val api = new WskApi - implicit val apiexperimental = new WskApiExperimental } trait FullyQualifiedNames { @@ -787,98 +786,6 @@ class WskPackage() } } -class WskApiExperimental extends RunWskCmd { - protected val noun = "api-experimental" - - /** - * Creates and API endpoint. Parameters mirror those available in the CLI. - * - * @param expectedExitCode (optional) the expected exit code for the command - * if the code is anything but DONTCARE_EXIT, assert the code is as expected - */ - def create( - basepath: Option[String] = None, - relpath: Option[String] = None, - operation: Option[String] = None, - action: Option[String] = None, - apiname: Option[String] = None, - swagger: Option[String] = None, - expectedExitCode: Int = SUCCESS_EXIT)( - implicit wp: WskProps): RunResult = { - val params = Seq(noun, "create", "--auth", wp.authKey) ++ - { basepath map { b => Seq(b) } getOrElse Seq() } ++ - { relpath map { r => Seq(r) } getOrElse Seq() } ++ - { operation map { o => Seq(o) } getOrElse Seq() } ++ - { action map { aa => Seq(aa) } getOrElse Seq() } ++ - { apiname map { a => Seq("--apiname", a) } getOrElse Seq() } ++ - { swagger map { s => Seq("--config-file", s) } getOrElse Seq() } - cli(wp.overrides ++ params, expectedExitCode, showCmd = true) - } - - /** - * Retrieve a list of API endpoints. Parameters mirror those available in the CLI. - * - * @param expectedExitCode (optional) the expected exit code for the command - * if the code is anything but DONTCARE_EXIT, assert the code is as expected - */ - def list( - basepathOrApiName: Option[String] = None, - relpath: Option[String] = None, - operation: Option[String] = None, - limit: Option[Int] = None, - since: Option[Instant] = None, - full: Option[Boolean] = None, - nameSort: Option[Boolean] = None, - expectedExitCode: Int = SUCCESS_EXIT)( - implicit wp: WskProps): RunResult = { - val params = Seq(noun, "list", "--auth", wp.authKey) ++ - { basepathOrApiName map { b => Seq(b) } getOrElse Seq() } ++ - { relpath map { r => Seq(r) } getOrElse Seq() } ++ - { operation map { o => Seq(o) } getOrElse Seq() } ++ - { limit map { l => Seq("--limit", l.toString) } getOrElse Seq() } ++ - { since map { i => Seq("--since", i.toEpochMilli.toString) } getOrElse Seq() } ++ - { full map { r => Seq("--full") } getOrElse Seq() } ++ - { nameSort map { n => Seq("--name-sort") } getOrElse Seq() } - cli(wp.overrides ++ params, expectedExitCode, showCmd = true) - } - - /** - * Retieves an API's configuration. Parameters mirror those available in the CLI. - * Runs a command wsk [params] where the arguments come in as a sequence. - * - * @param expectedExitCode (optional) the expected exit code for the command - * if the code is anything but DONTCARE_EXIT, assert the code is as expected - */ - def get( - basepathOrApiName: Option[String] = None, - full: Option[Boolean] = None, - expectedExitCode: Int = SUCCESS_EXIT)( - implicit wp: WskProps): RunResult = { - val params = Seq(noun, "get", "--auth", wp.authKey) ++ - { basepathOrApiName map { b => Seq(b) } getOrElse Seq() } ++ - { full map { f => if (f) Seq("--full") else Seq() } getOrElse Seq() } - cli(wp.overrides ++ params, expectedExitCode, showCmd = true) - } - - /** - * Delete an entire API or a subset of API endpoints. Parameters mirror those available in the CLI. - * - * @param expectedExitCode (optional) the expected exit code for the command - * if the code is anything but DONTCARE_EXIT, assert the code is as expected - */ - def delete( - basepathOrApiName: String, - relpath: Option[String] = None, - operation: Option[String] = None, - expectedExitCode: Int = SUCCESS_EXIT)( - implicit wp: WskProps): RunResult = { - val params = Seq(noun, "delete", "--auth", wp.authKey, basepathOrApiName) ++ - { relpath map { r => Seq(r) } getOrElse Seq() } ++ - { operation map { o => Seq(o) } getOrElse Seq() } - cli(wp.overrides ++ params, expectedExitCode, showCmd = true) - } -} - class WskApi() extends RunWskCmd { protected val noun = "api" diff --git a/tests/src/test/scala/whisk/core/cli/test/WskWebActionsTests.scala b/tests/src/test/scala/whisk/core/cli/test/WskWebActionsTests.scala index 1c23f0a..14daf1a 100644 --- a/tests/src/test/scala/whisk/core/cli/test/WskWebActionsTests.scala +++ b/tests/src/test/scala/whisk/core/cli/test/WskWebActionsTests.scala @@ -47,94 +47,14 @@ import whisk.core.entity.Subject * Tests web actions. */ @RunWith(classOf[JUnitRunner]) -class WskWebActionsTestsV1 extends WskWebActionsTests { - override val testRoutePath = "/api/v1/experimental/web" -} - -@RunWith(classOf[JUnitRunner]) -class WskWebActionsTestsV2 extends WskWebActionsTests with BeforeAndAfterAll { - override val testRoutePath = "/api/v1/web" - - private val subdomainRegex = Seq.fill(WhiskProperties.getPartsInVanitySubdomain)("[a-zA-Z0-9]+").mkString("-") - - private val (vanitySubdomain, vanityNamespace, makeTestSubject) = { - if (namespace.matches(subdomainRegex)) { - (namespace, namespace, false) - } else { - val s = Subject().asString.toLowerCase // this will generate two confirming parts - (s, s.replace("-", "_"), true) - } - } - - private val wskPropsForSubdomainTest = if (makeTestSubject) { - getAdditionalTestSubject(vanityNamespace) // create new subject for the test - } else { - WskProps() - } - - override def afterAll() = { - if (makeTestSubject) { - disposeAdditionalTestSubject(vanityNamespace) - } - } - - "test subdomain" should "have conforming parts" in { - vanitySubdomain should fullyMatch regex subdomainRegex.r - vanitySubdomain.length should be <= 63 - } - - "vanity subdomain" should "access a web action via namespace subdomain" in withAssetCleaner(wskPropsForSubdomainTest) { - (wp, assetHelper) => - val actionName = "webaction" - val file = Some(TestUtils.getTestActionFilename("echo.js")) - - assetHelper.withCleaner(wsk.action, actionName) { - (action, _) => action.create(actionName, file, web = Some(true.toString))(wp) - } - - val url = getServiceApiHost(vanitySubdomain, true) + s"/default/$actionName.text/a?a=A" - println(s"url: $url") - - // try the rest assured path first, failing that, try curl with explicit resolve - Try { - val response = RestAssured.given().config(sslconfig).get(url) - val responseCode = response.statusCode - responseCode shouldBe 200 - response.body.asString shouldBe "A" - } match { - case Failure(t) => - println(s"RestAssured path failed, trying curl: $t") - implicit val tid = TransactionId.testing - implicit val logger = new PrintStreamLogging(Console.out) - val host = getServiceApiHost(vanitySubdomain, false) - // if the edge host is a name, try to resolve it, otherwise, it should be an ip address already - val edgehost = WhiskProperties.getEdgeHost - val ip = Try(java.net.InetAddress.getByName(edgehost).getHostAddress) getOrElse "???" - println(s"edge: $edgehost, ip: $ip") - val cmd = Seq("curl", "-k", url, "--resolve", s"$host:$ip") - val (stdout, stderr, exitCode) = SimpleExec.syncRunCmd(cmd) - withClue(s"\n$stderr\n") { - stdout shouldBe "A" - exitCode shouldBe 0 - } - - case _ => - } - } -} - -trait WskWebActionsTests - extends TestHelpers - with WskTestHelpers - with RestUtil { - +class WskWebActionsTests extends TestHelpers with WskTestHelpers with RestUtil with BeforeAndAfterAll { val MAX_URL_LENGTH = 8192 // 8K matching nginx default val wsk = new Wsk private implicit val wskprops = WskProps() val namespace = wsk.namespace.whois() - protected val testRoutePath: String + protected val testRoutePath: String = "/api/v1/web" behavior of "Wsk Web Actions" @@ -184,11 +104,7 @@ trait WskWebActionsTests val name = "webaction" val file = Some(TestUtils.getTestActionFilename("echo.js")) val host = getServiceURL() - val url = if (testRoutePath == "/api/v1/experimental/web") { - s"$host$testRoutePath/$namespace/default/$name.text/__ow_meta_namespace" - } else { - s"$host$testRoutePath/$namespace/default/$name.text/__ow_user" - } + val url = s"$host$testRoutePath/$namespace/default/$name.text/__ow_user" assetHelper.withCleaner(wsk.action, name) { (action, _) => @@ -261,11 +177,7 @@ trait WskWebActionsTests val file = Some(TestUtils.getTestActionFilename("echo.js")) val bodyContent = "This is the body" val host = getServiceURL() - val url = if (testRoutePath == "/api/v1/experimental/web") { - s"$host$testRoutePath/$namespace/default/$name.text/__ow_meta_body" - } else { - s"$host$testRoutePath/$namespace/default/$name.text/__ow_body" - } + val url = s"$host$testRoutePath/$namespace/default/webaction.text/__ow_body" assetHelper.withCleaner(wsk.action, name) { (action, _) => action.create(name, file, web = Some("true")) @@ -336,4 +248,71 @@ trait WskWebActionsTests response.header("Content-type") shouldBe "application/json" response.body.asString.parseJson.asJsObject shouldBe JsObject("status" -> "success".toJson) } + + private val subdomainRegex = Seq.fill(WhiskProperties.getPartsInVanitySubdomain)("[a-zA-Z0-9]+").mkString("-") + + private val (vanitySubdomain, vanityNamespace, makeTestSubject) = { + if (namespace.matches(subdomainRegex)) { + (namespace, namespace, false) + } else { + val s = Subject().asString.toLowerCase // this will generate two confirming parts + (s, s.replace("-", "_"), true) + } + } + + private val wskPropsForSubdomainTest = if (makeTestSubject) { + getAdditionalTestSubject(vanityNamespace) // create new subject for the test + } else { + WskProps() + } + + override def afterAll() = { + if (makeTestSubject) { + disposeAdditionalTestSubject(vanityNamespace) + } + } + + "test subdomain" should "have conforming parts" in { + vanitySubdomain should fullyMatch regex subdomainRegex.r + vanitySubdomain.length should be <= 63 + } + + "vanity subdomain" should "access a web action via namespace subdomain" in withAssetCleaner(wskPropsForSubdomainTest) { + (wp, assetHelper) => + val actionName = "webaction" + + val file = Some(TestUtils.getTestActionFilename("echo.js")) + assetHelper.withCleaner(wsk.action, actionName) { + (action, _) => action.create(actionName, file, web = Some(true.toString))(wp) + } + + val url = getServiceApiHost(vanitySubdomain, true) + s"/default/$actionName.text/a?a=A" + println(s"url: $url") + + // try the rest assured path first, failing that, try curl with explicit resolve + Try { + val response = RestAssured.given().config(sslconfig).get(url) + val responseCode = response.statusCode + responseCode shouldBe 200 + response.body.asString shouldBe "A" + } match { + case Failure(t) => + println(s"RestAssured path failed, trying curl: $t") + implicit val tid = TransactionId.testing + implicit val logger = new PrintStreamLogging(Console.out) + val host = getServiceApiHost(vanitySubdomain, false) + // if the edge host is a name, try to resolve it, otherwise, it should be an ip address already + val edgehost = WhiskProperties.getEdgeHost + val ip = Try(java.net.InetAddress.getByName(edgehost).getHostAddress) getOrElse "???" + println(s"edge: $edgehost, ip: $ip") + val cmd = Seq("curl", "-k", url, "--resolve", s"$host:$ip") + val (stdout, stderr, exitCode) = SimpleExec.syncRunCmd(cmd) + withClue(s"\n$stderr\n") { + stdout shouldBe "A" + exitCode shouldBe 0 + } + + case _ => + } + } } 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 79ca5a0..446d881 100644 --- a/tests/src/test/scala/whisk/core/controller/test/WebActionsApiTests.scala +++ b/tests/src/test/scala/whisk/core/controller/test/WebActionsApiTests.scala @@ -79,30 +79,9 @@ import whisk.http.Messages */ @RunWith(classOf[JUnitRunner]) -class WebActionsApiTestsV1 extends FlatSpec with Matchers with WebActionsApiTests { - override lazy val webInvokePathSegments = Seq("experimental", "web") - override lazy val webApiDirectives = WebApiDirectives.exp - - "properties" should "match verion" in { - webApiDirectives.method shouldBe "__ow_meta_verb" - webApiDirectives.headers shouldBe "__ow_meta_headers" - webApiDirectives.path shouldBe "__ow_meta_path" - webApiDirectives.namespace shouldBe "__ow_meta_namespace" - webApiDirectives.query shouldBe "__ow_meta_query" - webApiDirectives.body shouldBe "__ow_meta_body" - webApiDirectives.statusCode shouldBe "code" - webApiDirectives.enforceExtension shouldBe true - webApiDirectives.reservedProperties shouldBe { - Set("__ow_meta_verb", "__ow_meta_headers", "__ow_meta_path", "__ow_meta_namespace", - "__ow_meta_query", "__ow_meta_body") - } - } -} - -@RunWith(classOf[JUnitRunner]) -class WebActionsApiTestsV2 extends FlatSpec with Matchers with WebActionsApiTests { +class WebActionsApiPropertiesTests extends FlatSpec with Matchers with WebActionsApiTests { override lazy val webInvokePathSegments = Seq("web") - override lazy val webApiDirectives = WebApiDirectives.web + override lazy val webApiDirectives = new WebApiDirectives() "properties" should "match verion" in { webApiDirectives.method shouldBe "__ow_method" -- To stop receiving notification emails like this one, please contact ['"commits@openwhisk.apache.org" <commits@openwhisk.apache.org>'].