-
Notifications
You must be signed in to change notification settings - Fork 2.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(plugin): azure serverless functions #5479
Conversation
a744b18
to
96f2fa0
Compare
96f2fa0
to
3712d80
Compare
apisix/plugins/azure-functions.lua
Outdated
function _M.access(conf, ctx) | ||
local uri_args = core.request.get_uri_args(ctx) | ||
local headers = core.request.headers(ctx) or {} | ||
local req_body, _ = core.request.get_body() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What if the request body are large and we cannot load it into memory totally?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The body will be missing when it is larger than client_body_buffer_size (8k by default)
We can read the body by ourselves via ngx.req.socket? See https://github.com/openresty/lua-resty-upload/blob/master/lib/resty/upload.lua
We can do it in the next PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just realize it uses core.request.get_body
, which will read data from file if need. BTW, we should check the err returned by this function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks for pointing it out @tokers!
@spacewander even if it reads the content from a file, it reads everything in one go
apisix/apisix/core/request.lua
Lines 172 to 181 in 2c12b36
local function get_file(file_name) | |
local f, err = io_open(file_name, 'r') | |
if not f then | |
return nil, err | |
end | |
local req_body = f:read("*all") | |
f:close() | |
return req_body | |
end |
I think we should use chunked transfer encoding here to proxy the request with a large body size. WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think normally people don't need to submit big data to azure functions. We can keep this function unchanged for now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree, but it's better to add some hints in the document. @bisakhmondal @spacewander
apisix/plugins/azure-functions.lua
Outdated
local res, err = httpc:request_uri(conf.function_uri, params) | ||
|
||
if not res or err then | ||
return core.response.exit(500, "failed to process azure function, err: " .. err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return core.response.exit(500, "failed to process azure function, err: " .. err) | |
core.log.error("failed to process azure function, err: " .. err) | |
return 503 |
I think it will be safer not to return an internal error to the client.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ack
conf/config-default.yaml
Outdated
@@ -340,6 +340,7 @@ plugins: # plugin list (sorted by priority) | |||
- response-rewrite # priority: 899 | |||
#- dubbo-proxy # priority: 507 | |||
- grpc-transcode # priority: 506 | |||
- azure-functions # priority: 505 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Better to put it ahead of serverless-post-function
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What should be the priority value, negative?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
priority: -1900?
t/plugin/azure-functions.t
Outdated
add_block_preprocessor(sub { | ||
my ($block) = @_; | ||
|
||
if (!defined $block->additional_http_config) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can use http_config
to inject HTTP config, see https://github.com/apache/apisix/blob/master/t/discovery/consul_kv.t
And I suggest you put azure-demo
as
Line 33 in 2c12b36
function _M.hello() |
There is no need to introduce a new server.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Gotcha
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done, Is it okay now?
apisix/plugins/azure-functions.lua
Outdated
headers["x-functions-key"] = conf.authorization.apikey or "" | ||
headers["x-functions-clientid"] = conf.authorization.clientid or "" | ||
else | ||
headers["x-functions-key"] = getenv(env_key.API) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to expose the AZURE_FUNCTIONS_APIKEY via env AZURE_FUNCTIONS_APIKEY
, if this plugin is enabled. Nginx will hide all environment variables by default.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You mean like this env AZURE_FUNCTIONS_APIKEY="key" make run
?
Or you are suggesting to update something?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I change my mind. Maybe it could be easier to pass this argument via plugin metadata.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Metadata won't be a great fit, IMHO. There might be multiple instances of plugins linked to different routes and we can't force users to use the same key they put into the metadata schema(must be the master key, instead of function-specific keys). This clearly violates principle of Least Access Privileges, isn't it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed env vars and added metadata as a fallback option
method = ngx.req.get_method(), | ||
body = req_body, | ||
query = uri_args, | ||
headers = headers, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need to remove the host header? Otherwise, the host of APISIX will be used.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done, It was the root of many problem.
t/plugin/azure-functions.t
Outdated
=== TEST 5: http2 check response body and headers | ||
--- http2 | ||
--- exec | ||
curl -XGET --http2 --http2-prior-knowledge localhost:1984/azure |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can use regular --- request
to send http2 request, see
https://github.com/openresty/test-nginx/blob/9d5a20f884d67974f9eafeed5a1540cd32945fb2/lib/Test/Nginx/Socket.pm#L2310
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice, it is. Updated
Co-authored-by: 罗泽轩 <spacewanderlzx@gmail.com>
I have a question, should we standardize the naming of all serverless plugins? such as |
@bzp2010 |
What this PR does / why we need it:
Pre-submission checklist: