This is an automated email from the ASF dual-hosted git repository.

AlinsRan 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 ca0c3187a fix(resource): support all plugin-bearing resource types in 
fetch_latest_conf (#13663)
ca0c3187a is described below

commit ca0c3187a6bfed7db6ae61725bad7bf699ac7b43
Author: AlinsRan <[email protected]>
AuthorDate: Tue Jul 7 13:33:56 2026 +0800

    fix(resource): support all plugin-bearing resource types in 
fetch_latest_conf (#13663)
---
 apisix/resource.lua                | 31 ++++++++-----
 t/plugin/ai-proxy-multi.balancer.t | 90 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 111 insertions(+), 10 deletions(-)

diff --git a/apisix/resource.lua b/apisix/resource.lua
index ae5dfc6e4..f99672221 100644
--- a/apisix/resource.lua
+++ b/apisix/resource.lua
@@ -22,6 +22,23 @@ local config_util = require("apisix.core.config_util")
 local require = require
 
 local _M = {}
+
+
+-- resource types whose config may attach plugins via `_meta.parent`
+-- (set by plugin.set_plugins_meta_parent) and thus reach fetch_latest_conf.
+-- Every type maps to its own "/<type>" top-level config key.
+local SUPPORTED_RESOURCE_TYPES = {
+    upstreams = true,
+    routes = true,
+    services = true,
+    stream_routes = true,
+    plugin_configs = true,
+    global_rules = true,
+    consumers = true,
+    consumer_groups = true,
+}
+
+
 local function remove_etcd_prefix(key)
     local prefix = ""
     local local_conf =  require("apisix.core.config_local").local_conf()
@@ -50,19 +67,13 @@ local function fetch_latest_conf(resource_path)
         return nil
     end
 
-    local key
-    if resource_type == "upstreams" then
-        key = "/upstreams"
-    elseif resource_type == "routes" then
-        key = "/routes"
-    elseif resource_type == "services" then
-        key = "/services"
-    elseif resource_type == "stream_routes" then
-        key = "/stream_routes"
-    else
+    -- all resource types that can carry plugins (and thus reach here via
+    -- _meta.parent) map their type to their own top-level config key
+    if not SUPPORTED_RESOURCE_TYPES[resource_type] then
         log.error("unsupported resource type: ", resource_type)
         return nil
     end
+    local key = "/" .. resource_type
 
     local data = core.config.fetch_created_obj(key)
     if not data then
diff --git a/t/plugin/ai-proxy-multi.balancer.t 
b/t/plugin/ai-proxy-multi.balancer.t
index aad79e8fb..84932b870 100644
--- a/t/plugin/ai-proxy-multi.balancer.t
+++ b/t/plugin/ai-proxy-multi.balancer.t
@@ -1181,3 +1181,93 @@ Host: openai_internal_error
 --- error_code: 500
 --- no_error_log
 [error]
+
+
+
+=== TEST 22: set plugin_config with ai-proxy-multi (2 instances) and route 
referencing it
+--- config
+    location /t {
+        content_by_lua_block {
+            local t = require("lib.test_admin").test
+            local code, body = t('/apisix/admin/plugin_configs/1',
+                 ngx.HTTP_PUT,
+                 [[{
+                    "plugins": {
+                        "ai-proxy-multi": {
+                            "instances": [
+                                {
+                                    "name": "openai",
+                                    "provider": "openai",
+                                    "weight": 4,
+                                    "auth": {
+                                        "header": {
+                                            "Authorization": "Bearer token"
+                                        }
+                                    },
+                                    "options": {
+                                        "model": "gpt-4"
+                                    },
+                                    "override": {
+                                        "endpoint": "http://127.0.0.1:6724";
+                                    }
+                                },
+                                {
+                                    "name": "deepseek",
+                                    "provider": "deepseek",
+                                    "weight": 1,
+                                    "auth": {
+                                        "header": {
+                                            "Authorization": "Bearer token"
+                                        }
+                                    },
+                                    "options": {
+                                        "model": "deepseek-chat"
+                                    },
+                                    "override": {
+                                        "endpoint": 
"http://127.0.0.1:6724/chat/completions";
+                                    }
+                                }
+                            ],
+                            "ssl_verify": false
+                        }
+                    }
+                }]]
+            )
+            if code >= 300 then
+                ngx.status = code
+                ngx.say(body)
+                return
+            end
+
+            code, body = t('/apisix/admin/routes/1',
+                 ngx.HTTP_PUT,
+                 [[{
+                    "uri": "/anything",
+                    "plugin_config_id": 1,
+                    "upstream": {
+                        "type": "roundrobin",
+                        "nodes": {
+                            "127.0.0.1:6724": 1
+                        }
+                    }
+                }]]
+            )
+            if code >= 300 then
+                ngx.status = code
+            end
+            ngx.say(body)
+        }
+    }
+--- response_body
+passed
+
+
+
+=== TEST 23: request via plugin_config_id succeeds (regression for 
multi-instance parent lookup)
+--- request
+POST /anything
+{ "messages": [ { "role": "system", "content": "You are a mathematician" }, { 
"role": "user", "content": "What is 1+1?"} ] }
+--- response_body_like eval
+qr/openai|deepseek/
+--- no_error_log
+failed to fetch the parent config

Reply via email to