lordcheng10 opened a new issue, #14123:
URL: https://github.com/apache/apisix/issues/14123

   ### Current Behavior
   
   `graphql-limit-count` chooses a node for automatic schema introspection in 
`apisix/plugins/graphql-limit-count/introspection.lua::first_node`. The 
function sorts every configured upstream address but does not check the node 
weight.
   
   APISIX allows upstream nodes with `weight = 0` to keep a node configured 
while disabling it for normal traffic. If such a node sorts first, GraphQL 
introspection is still sent to it. A disabled or unavailable node can therefore 
make the plugin fail to obtain the schema even though an enabled upstream node 
is available.
   
   This affects both supported upstream node representations:
   
   - map: `{["127.0.0.1:1000"] = 0, ["127.0.0.1:2000"] = 1}`
   - array: `{{host = "127.0.0.1", port = 1000, weight = 0}, {host = 
"127.0.0.1", port = 2000, weight = 1}}`
   
   In both cases current `master` selects `127.0.0.1:1000`.
   
   ### Expected Behavior
   
   Automatic GraphQL schema introspection should select only enabled upstream 
nodes (`weight > 0`), matching the effective upstream used for proxied traffic. 
If every configured node has zero weight, introspection should report that no 
usable upstream node is available instead of contacting a disabled node.
   
   ### Steps to Reproduce
   
   1. Check out APISIX master commit `ae87b942337a7e6897eb153c4f7cfb6ac1ecf3c8`.
   2. Reach the file-local selector through the shipped module (the existing 
`graphql-limit-count2.t` tests use the same upvalue technique):
   
      ```lua
      local introspection =
          require("apisix.plugins.graphql-limit-count.introspection")
   
      local function upvalue(fn, wanted)
          local i = 1
          while true do
              local name, value = debug.getupvalue(fn, i)
              if not name then
                  return nil
              end
              if name == wanted then
                  return value
              end
              i = i + 1
          end
      end
   
      local resolve_endpoint = upvalue(introspection.get, "resolve_endpoint")
      local first_node = upvalue(resolve_endpoint, "first_node")
   
      ngx.say(first_node({
          ["127.0.0.1:1000"] = 0,
          ["127.0.0.1:2000"] = 1,
      }, "http"))
      ```
   3. The current output is `127.0.0.1:1000`; the enabled node is 
`127.0.0.1:2000`.
   4. The same result occurs with the array-form upstream shown above.
   5. In a service using `graphql-limit-count` with automatic introspection, 
leave the zero-weight node unavailable and send the first GraphQL request. The 
schema fetch targets the disabled node and fails instead of using the enabled 
node.
   
   ### Environment
   
   - APISIX version: master at `ae87b942337a7e6897eb153c4f7cfb6ac1ecf3c8`
   - Operating system: `Darwin chenlindeMacBook-Pro.local 25.3.0 Darwin Kernel 
Version 25.3.0; arm64`
   - OpenResty / Nginx version: not installed on the analysis host; the 
deterministic selector was reproduced against the actual APISIX Lua module with 
embedded Lua 5.4 (Lupa 2.8)
   - etcd version: not applicable to the selector-level reproducer
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to