membphis commented on code in PR #12607: URL: https://github.com/apache/apisix/pull/12607#discussion_r2348452639
########## apisix/core.lua: ########## @@ -36,15 +39,96 @@ end config.type = config_provider +local function remove_etcd_prefix(key) + local prefix = "" + local local_conf = require("apisix.core.config_local").local_conf() + local role = table.try_read_attr(local_conf, "deployment", "role") + local provider = table.try_read_attr(local_conf, "deployment", "role_" .. + role, "config_provider") + if provider == "etcd" and local_conf.etcd and local_conf.etcd.prefix then + prefix = local_conf.etcd.prefix + end + return string_sub(key, #prefix + 1) +end + +local function parse_path(resource_full_path) + local resource_path_parts = ngx_re.split(resource_full_path, "#") + local resource_path = resource_path_parts[1] or resource_full_path + local resource_sub_path = resource_path_parts[2] or "" + return resource_path, resource_sub_path +end + +local function fetch_latest_conf(resource_path) + -- if resource path contains json path, extract out the prefix + -- for eg: extracts /routes/1 from /routes/1#plugins.abc + resource_path = parse_path(resource_path) + local resource_type, id + -- Handle both formats: + -- 1. /<etcd-prefix>/<resource_type>/<id> + -- 2. /<resource_type>/<id> + resource_path = remove_etcd_prefix(resource_path) + resource_type, id = resource_path:match("^/([^/]+)/([^/]+)$") + if not resource_type or not id then + log.error("invalid resource path: ", 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 + log.error("unsupported resource type: ", resource_type) + return nil + end + + local data = config.fetch_created_obj(key) + if not data then + log.error("failed to fetch configuration for type: ", key) + return nil + end + local resource = data:get(id) + if not resource then + -- this can happen if the resource was deleted + -- after the this function was called so we don't throw error + log.warn("resource not found: ", id, " in ", key, + "this can happen if the resource was deleted") + return nil + end + + return resource +end + +local function get_nodes_ver(resource_path) + local res_conf = fetch_latest_conf(resource_path) + local upstream = res_conf.value.upstream or res_conf.value + return upstream._nodes_ver +end + + +local function set_nodes_ver_and_nodes(resource_path, nodes_ver, nodes) + local res_conf = fetch_latest_conf(resource_path) + local upstream = res_conf.value.upstream or res_conf.value + upstream._nodes_ver = nodes_ver + upstream.nodes = nodes +end return { version = require("apisix.core.version"), log = log, config = config, config_util = require("apisix.core.config_util"), sleep = utils.sleep, + fetch_latest_conf = fetch_latest_conf, Review Comment: in my opinion: create a new `module`, it's name can be `resource` then we can use it by call `core.resource.get_nodes_ver`, what do you think? @Revolyssup -- 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: notifications-unsubscr...@apisix.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org