This is an automated email from the ASF dual-hosted git repository.
spacewander pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/apisix.git
The following commit(s) were added to refs/heads/master by this push:
new 4783ad5 feat: support custom package, headers and body in openwhisk
plugin (#5923)
4783ad5 is described below
commit 4783ad550da66f5b22bae31bfa5ed1d57d4cdc8a
Author: encanto <[email protected]>
AuthorDate: Fri Jan 14 14:51:44 2022 +0800
feat: support custom package, headers and body in openwhisk plugin (#5923)
Co-authored-by: 罗泽轩 <[email protected]>
Co-authored-by: Your Name <[email protected]>
Co-authored-by: Zeping Bai <[email protected]>
---
apisix/plugins/openwhisk.lua | 34 ++++++-
ci/linux-ci-init-service.sh | 9 +-
t/plugin/openwhisk.t | 219 +++++++++++++++++++++++++++++++++++++++++--
3 files changed, 250 insertions(+), 12 deletions(-)
diff --git a/apisix/plugins/openwhisk.lua b/apisix/plugins/openwhisk.lua
index a8fe8c2..6f9a0a7 100644
--- a/apisix/plugins/openwhisk.lua
+++ b/apisix/plugins/openwhisk.lua
@@ -20,6 +20,8 @@ local http = require("resty.http")
local ngx_encode_base64 = ngx.encode_base64
local tostring = tostring
+local name_pattern = [[\A([\w]|[\w][\w@ .-]*[\[email protected]]+)\z]]
+
local schema = {
type = "object",
properties = {
@@ -29,8 +31,9 @@ local schema = {
default = true,
},
service_token = {type = "string"},
- namespace = {type = "string", maxLength = 256},
- action = {type = "string", maxLength = 256},
+ namespace = {type = "string", maxLength = 256, pattern = name_pattern},
+ package = {type = "string", maxLength = 256, pattern = name_pattern},
+ action = {type = "string", maxLength = 256, pattern = name_pattern},
result = {
type = "boolean",
default = true,
@@ -91,8 +94,9 @@ function _M.access(conf, ctx)
end
-- OpenWhisk action endpoint
+ local package = conf.package and conf.package .. "/" or ""
local endpoint = conf.api_host .. "/api/v1/namespaces/" .. conf.namespace
..
- "/actions/" .. conf.action
+ "/actions/" .. package .. conf.action
local httpc = http.new()
httpc:set_timeout(conf.timeout)
@@ -104,10 +108,30 @@ function _M.access(conf, ctx)
return 503
end
+ -- check if res.body is nil
+ if res.body == nil then
+ return res.status, res.body
+ end
+
+ -- parse OpenWhisk JSON response
+ -- OpenWhisk supports two types of responses, the user can return only
+ -- the response body, or set the status code and header.
+ local result, err = core.json.decode(res.body)
+
+ if not result then
+ core.log.error("failed to parse openwhisk response data: ", err)
+ return 503
+ end
+
-- setting response headers
- core.response.set_header(res.headers)
+ if result.headers ~= nil then
+ core.response.set_header(result.headers)
+ end
+
+ local code = result.statusCode or res.status
+ local body = result.body or res.body
+ return code, body
- return res.status, res.body
end
diff --git a/ci/linux-ci-init-service.sh b/ci/linux-ci-init-service.sh
index 6a7ffbb..5f46850 100755
--- a/ci/linux-ci-init-service.sh
+++ b/ci/linux-ci-init-service.sh
@@ -24,7 +24,14 @@ docker exec -i apache-apisix_kafka-server2_1
/opt/bitnami/kafka/bin/kafka-topics
docker pull openwhisk/action-nodejs-v14:nightly
docker run --rm -d --name openwhisk -p 3233:3233 -p 3232:3232 -v
/var/run/docker.sock:/var/run/docker.sock openwhisk/standalone:nightly
docker exec -i openwhisk waitready
-docker exec -i openwhisk bash -c "wsk action update test <(echo 'function
main(args){return {\"hello\":args.name || \"test\"}}') --kind nodejs:14"
+docker exec -i openwhisk bash -c "wsk package create pkg"
+docker exec -i openwhisk bash -c "wsk action update /guest/pkg/testpkg <(echo
'function main(args){return {\"hello\": \"world\"}}') --kind nodejs:14"
+docker exec -i openwhisk bash -c "wsk action update test <(echo 'function
main(args){return {\"hello\": \"test\"}}') --kind nodejs:14"
+docker exec -i openwhisk bash -c "wsk action update test-params <(echo
'function main(args){return {\"hello\": args.name || \"test\"}}') --kind
nodejs:14"
+docker exec -i openwhisk bash -c "wsk action update test-statuscode <(echo
'function main(args){return {\"statusCode\": 407}}') --kind nodejs:14"
+docker exec -i openwhisk bash -c "wsk action update test-headers <(echo
'function main(args){return {\"headers\": {\"test\":\"header\"}}}') --kind
nodejs:14"
+docker exec -i openwhisk bash -c "wsk action update test-body <(echo 'function
main(args){return {\"body\": {\"test\":\"body\"}}}') --kind nodejs:14"
+
docker exec -i rmqnamesrv rm /home/rocketmq/rocketmq-4.6.0/conf/tools.yml
docker exec -i rmqnamesrv /home/rocketmq/rocketmq-4.6.0/bin/mqadmin
updateTopic -n rocketmq_namesrv:9876 -t test -c DefaultCluster
diff --git a/t/plugin/openwhisk.t b/t/plugin/openwhisk.t
index e20fe5a..4d89bbe 100644
--- a/t/plugin/openwhisk.t
+++ b/t/plugin/openwhisk.t
@@ -99,7 +99,7 @@ property "api_host" validation failed: wrong type: expected
string, got number
"api_host": "http://127.0.0.1:3233",
"service_token":
"23bc46b1-71f6-4ed5-8c54-816aa4f8c502:123zO3xZCLrMN6v2BKK1dXYFpXlPkccOFqm12CdAsMgRU4VrNZ9lyGVCGuMDGIwP",
"namespace": "guest",
- "action": "test"
+ "action": "test-params"
}
},
"upstream": {
@@ -141,7 +141,42 @@ qr/"error":"The request content was malformed/
-=== TEST 7: hit route (with POST and correct request body)
+=== TEST 7: setup route with plugin
+--- config
+ location /t {
+ content_by_lua_block {
+ local t = require("lib.test_admin").test
+ local code, body = t('/apisix/admin/routes/1',
+ ngx.HTTP_PUT,
+ [[{
+ "plugins": {
+ "openwhisk": {
+ "api_host": "http://127.0.0.1:3233",
+ "service_token":
"23bc46b1-71f6-4ed5-8c54-816aa4f8c502:123zO3xZCLrMN6v2BKK1dXYFpXlPkccOFqm12CdAsMgRU4VrNZ9lyGVCGuMDGIwP",
+ "namespace": "guest",
+ "action": "test-params"
+ }
+ },
+ "upstream": {
+ "nodes": {},
+ "type": "roundrobin"
+ },
+ "uri": "/hello"
+ }]]
+ )
+
+ if code >= 300 then
+ ngx.status = code
+ end
+ ngx.say(body)
+ }
+ }
+--- response_body
+passed
+
+
+
+=== TEST 8: hit route (with POST and correct request body)
--- request
POST /hello
{"name": "world"}
@@ -152,7 +187,7 @@ Content-Type: application/json
-=== TEST 8: reset route to non-existent action
+=== TEST 9: reset route to non-existent action
--- config
location /t {
content_by_lua_block {
@@ -187,7 +222,7 @@ passed
-=== TEST 9: hit route (with non-existent action)
+=== TEST 10: hit route (with non-existent action)
--- request
POST /hello
{"name": "world"}
@@ -199,7 +234,7 @@ qr/"error":"The requested resource does not exist."/
-=== TEST 10: reset route to wrong api_host
+=== TEST 11: reset route to wrong api_host
--- config
location /t {
content_by_lua_block {
@@ -234,7 +269,7 @@ passed
-=== TEST 11: hit route (with wrong api_host)
+=== TEST 12: hit route (with wrong api_host)
--- request
POST /hello
{"name": "world"}
@@ -243,3 +278,175 @@ Content-Type: application/json
--- error_code: 503
--- error_log
failed to process openwhisk action, err:
+
+
+
+=== TEST 13: reset route to packaged action
+--- config
+ location /t {
+ content_by_lua_block {
+ local t = require("lib.test_admin").test
+ local code, body = t('/apisix/admin/routes/1',
+ ngx.HTTP_PUT,
+ [[{
+ "plugins": {
+ "openwhisk": {
+ "api_host": "http://127.0.0.1:3233",
+ "service_token":
"23bc46b1-71f6-4ed5-8c54-816aa4f8c502:123zO3xZCLrMN6v2BKK1dXYFpXlPkccOFqm12CdAsMgRU4VrNZ9lyGVCGuMDGIwP",
+ "namespace": "guest",
+ "package": "pkg",
+ "action": "testpkg"
+ }
+ },
+ "upstream": {
+ "nodes": {},
+ "type": "roundrobin"
+ },
+ "uri": "/hello"
+ }]]
+ )
+
+ if code >= 300 then
+ ngx.status = code
+ end
+ ngx.say(body)
+ }
+ }
+--- response_body
+passed
+
+
+
+=== TEST 14: hit route (with packaged action)
+--- request
+GET /hello
+--- response_body chomp
+{"hello":"world"}
+
+
+
+=== TEST 15: reset route to status code action
+--- config
+ location /t {
+ content_by_lua_block {
+ local t = require("lib.test_admin").test
+ local code, body = t('/apisix/admin/routes/1',
+ ngx.HTTP_PUT,
+ [[{
+ "plugins": {
+ "openwhisk": {
+ "api_host": "http://127.0.0.1:3233",
+ "service_token":
"23bc46b1-71f6-4ed5-8c54-816aa4f8c502:123zO3xZCLrMN6v2BKK1dXYFpXlPkccOFqm12CdAsMgRU4VrNZ9lyGVCGuMDGIwP",
+ "namespace": "guest",
+ "action": "test-statuscode"
+ }
+ },
+ "upstream": {
+ "nodes": {},
+ "type": "roundrobin"
+ },
+ "uri": "/hello"
+ }]]
+ )
+
+ if code >= 300 then
+ ngx.status = code
+ end
+ ngx.say(body)
+ }
+ }
+--- response_body
+passed
+
+
+
+=== TEST 16: hit route (with packaged action)
+--- request
+GET /hello
+--- error_code: 407
+
+
+
+=== TEST 17: reset route to headers action
+--- config
+ location /t {
+ content_by_lua_block {
+ local t = require("lib.test_admin").test
+ local code, body = t('/apisix/admin/routes/1',
+ ngx.HTTP_PUT,
+ [[{
+ "plugins": {
+ "openwhisk": {
+ "api_host": "http://127.0.0.1:3233",
+ "service_token":
"23bc46b1-71f6-4ed5-8c54-816aa4f8c502:123zO3xZCLrMN6v2BKK1dXYFpXlPkccOFqm12CdAsMgRU4VrNZ9lyGVCGuMDGIwP",
+ "namespace": "guest",
+ "action": "test-headers"
+ }
+ },
+ "upstream": {
+ "nodes": {},
+ "type": "roundrobin"
+ },
+ "uri": "/hello"
+ }]]
+ )
+
+ if code >= 300 then
+ ngx.status = code
+ end
+ ngx.say(body)
+ }
+ }
+--- response_body
+passed
+
+
+
+=== TEST 18: hit route (with headers action)
+--- request
+GET /hello
+--- response_headers
+test: header
+
+
+
+=== TEST 19: reset route to body action
+--- config
+ location /t {
+ content_by_lua_block {
+ local t = require("lib.test_admin").test
+ local code, body = t('/apisix/admin/routes/1',
+ ngx.HTTP_PUT,
+ [[{
+ "plugins": {
+ "openwhisk": {
+ "api_host": "http://127.0.0.1:3233",
+ "service_token":
"23bc46b1-71f6-4ed5-8c54-816aa4f8c502:123zO3xZCLrMN6v2BKK1dXYFpXlPkccOFqm12CdAsMgRU4VrNZ9lyGVCGuMDGIwP",
+ "namespace": "guest",
+ "action": "test-body"
+ }
+ },
+ "upstream": {
+ "nodes": {},
+ "type": "roundrobin"
+ },
+ "uri": "/hello"
+ }]]
+ )
+
+ if code >= 300 then
+ ngx.status = code
+ end
+ ngx.say(body)
+ }
+ }
+--- response_body
+passed
+
+
+
+=== TEST 20: hit route (with body action)
+--- request
+GET /hello
+--- response_body
+{"test":"body"}