You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@apisix.apache.org by sp...@apache.org on 2021/09/16 03:56:13 UTC

[apisix] branch master updated: feat: allow injecting logic to APISIX's method (#5068)

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 f373faf  feat: allow injecting logic to APISIX's method (#5068)
f373faf is described below

commit f373faf62f69ca6fd2cf5c11d4270ae7214f8131
Author: 罗泽轩 <sp...@gmail.com>
AuthorDate: Thu Sep 16 11:56:09 2021 +0800

    feat: allow injecting logic to APISIX's method (#5068)
---
 apisix/cli/ngx_tpl.lua           |  6 ++++++
 apisix/cli/ops.lua               |  3 +++
 conf/config-default.yaml         |  1 +
 docs/en/latest/plugin-develop.md | 15 ++++++++++++++
 example/my_hook.lua              | 29 ++++++++++++++++++++++++++
 t/cli/test_main.sh               | 45 +++++++++++++++++++++++++++++++++++++++-
 6 files changed, 98 insertions(+), 1 deletion(-)

diff --git a/apisix/cli/ngx_tpl.lua b/apisix/cli/ngx_tpl.lua
index 4bc02fc..07ad5ea 100644
--- a/apisix/cli/ngx_tpl.lua
+++ b/apisix/cli/ngx_tpl.lua
@@ -99,6 +99,9 @@ stream {
 
     init_by_lua_block {
         require "resty.core"
+        {% if lua_module_hook then %}
+        require "{* lua_module_hook *}"
+        {% end %}
         apisix = require("apisix")
         local dns_resolver = { {% for _, dns_addr in ipairs(dns_resolver or {}) do %} "{*dns_addr*}", {% end %} }
         local args = {
@@ -338,6 +341,9 @@ http {
 
     init_by_lua_block {
         require "resty.core"
+        {% if lua_module_hook then %}
+        require "{* lua_module_hook *}"
+        {% end %}
         apisix = require("apisix")
 
         local dns_resolver = { {% for _, dns_addr in ipairs(dns_resolver or {}) do %} "{*dns_addr*}", {% end %} }
diff --git a/apisix/cli/ops.lua b/apisix/cli/ops.lua
index ef0be7f..c670d1e 100644
--- a/apisix/cli/ops.lua
+++ b/apisix/cli/ops.lua
@@ -153,6 +153,9 @@ local config_schema = {
                 config_center = {
                     enum = {"etcd", "yaml"},
                 },
+                lua_module_hook = {
+                    pattern = "^[a-zA-Z._-]+$",
+                },
                 proxy_protocol = {
                     type = "object",
                     properties = {
diff --git a/conf/config-default.yaml b/conf/config-default.yaml
index 402296e..5232a28 100644
--- a/conf/config-default.yaml
+++ b/conf/config-default.yaml
@@ -50,6 +50,7 @@ apisix:
   # configurations to load third party code and/or override the builtin one.
   extra_lua_path: ""               # extend lua_package_path to load third party code
   extra_lua_cpath: ""              # extend lua_package_cpath to load third party code
+  #lua_module_hook: "my_project.my_hook"  # the hook module which will be used to inject third party code into APISIX
 
   proxy_cache:                     # Proxy Caching configuration
     cache_ttl: 10s                 # The default caching time if the upstream does not specify the cache time
diff --git a/docs/en/latest/plugin-develop.md b/docs/en/latest/plugin-develop.md
index f850a38..d0797c3 100644
--- a/docs/en/latest/plugin-develop.md
+++ b/docs/en/latest/plugin-develop.md
@@ -69,6 +69,21 @@ apisix:
 
 Now using `require "apisix.plugins.3rd-party"` will load your plugin, just like `require "apisix.plugins.jwt-auth"` will load the `jwt-auth` plugin.
 
+Sometimes you may want to override a method instead of a whole file. In this case, you can configure `lua_module_hook` in `conf/config.yaml`
+to introduce your hook.
+
+Assumed your configuration is:
+
+```yaml
+apisix:
+    ...
+    extra_lua_path: "/path/to/example/?.lua"
+    lua_module_hook: "my_hook"
+```
+
+The `example/my_hook.lua` will be loaded when APISIX starts, and you can use this hook to replace a method in APISIX.
+The example of [my_hook.lua](https://github.com/apache/apisix/blob/master/example/my_hook.lua) can be found under the `example` directory of this project.
+
 ## check dependencies
 
 if you have dependencies on external libraries, check the dependent items. if your plugin needs to use shared memory, it
diff --git a/example/my_hook.lua b/example/my_hook.lua
new file mode 100644
index 0000000..ef06f66
--- /dev/null
+++ b/example/my_hook.lua
@@ -0,0 +1,29 @@
+--
+-- 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.
+--
+local apisix = require("apisix")
+
+local old_http_init = apisix.http_init
+apisix.http_init = function (...)
+    ngx.log(ngx.EMERG, "my hook works in http")
+    old_http_init(...)
+end
+
+local old_stream_init = apisix.stream_init
+apisix.stream_init = function (...)
+    ngx.log(ngx.EMERG, "my hook works in stream")
+    old_stream_init(...)
+end
diff --git a/t/cli/test_main.sh b/t/cli/test_main.sh
index ec1476b..a4bb398 100755
--- a/t/cli/test_main.sh
+++ b/t/cli/test_main.sh
@@ -612,6 +612,49 @@ fi
 
 echo "passed: detect invalid extra_lua_path"
 
+# support hooking into APISIX methods
+echo '
+apisix:
+    lua_module_hook: "example/my_hook"
+' > conf/config.yaml
+
+out=$(make init 2>&1 || true)
+if ! echo "$out" | grep 'property "lua_module_hook" validation failed'; then
+    echo "failed: bad lua_module_hook should be rejected"
+    exit 1
+fi
+
+echo "passed: bad lua_module_hook should be rejected"
+
+echo '
+apisix:
+    extra_lua_path: "\$prefix/example/?.lua"
+    lua_module_hook: "my_hook"
+    stream_proxy:
+        only: false
+        tcp:
+            - addr: 9100
+' > conf/config.yaml
+
+rm logs/error.log
+make init
+make run
+
+sleep 0.5
+make stop
+
+if ! grep "my hook works in http" logs/error.log > /dev/null; then
+    echo "failed: hook can take effect"
+    exit 1
+fi
+
+if ! grep "my hook works in stream" logs/error.log > /dev/null; then
+    echo "failed: hook can take effect"
+    exit 1
+fi
+
+echo "passed: hook can take effect"
+
 # check restart with old nginx.pid exist
 echo "-1" > logs/nginx.pid
 out=$(./bin/apisix start 2>&1 || true)
@@ -621,7 +664,7 @@ if echo "$out" | grep "APISIX is running"; then
     exit 1
 fi
 
-rm logs/nginx.pid
+./bin/apisix stop
 echo "pass: ignore stale nginx.pid"
 
 # check the keepalive related parameter settings in the upstream