in apisix/upstream.lua [268:405]
function _M.set_by_route(route, api_ctx)
if api_ctx.upstream_conf then
return
end
local up_conf = api_ctx.matched_upstream
if not up_conf then
return 503, "missing upstream configuration in Route or Service"
end
if up_conf.service_name then
if not discovery then
return 503, "discovery is uninitialized"
end
if not up_conf.discovery_type then
return 503, "discovery server need appoint"
end
local dis = discovery[up_conf.discovery_type]
if not dis then
local err = "discovery " .. up_conf.discovery_type .. " is uninitialized"
return 503, err
end
local new_nodes, err = dis.nodes(up_conf.service_name, up_conf.discovery_args)
if not new_nodes then
return HTTP_CODE_UPSTREAM_UNAVAILABLE, "no valid upstream node: " .. (err or "nil")
end
local same = upstream_util.compare_upstream_node(up_conf, new_nodes)
if not same then
local pass, err = core.schema.check(core.schema.discovery_nodes, new_nodes)
if not pass then
return HTTP_CODE_UPSTREAM_UNAVAILABLE, "invalid nodes format: " .. err
end
local new_up_conf = core.table.clone(up_conf)
new_up_conf.nodes = new_nodes
new_up_conf.original_nodes = up_conf.nodes
core.log.info("discover new upstream from ", up_conf.service_name, ", type ",
up_conf.discovery_type, ": ",
core.json.delay_encode(new_up_conf, true))
local parent = up_conf.parent
if parent.value.upstream then
parent.value.upstream = new_up_conf
else
parent.value = new_up_conf
end
up_conf = new_up_conf
end
end
local id = up_conf.parent.value.id
local conf_version = up_conf.parent.modifiedIndex
set_directly(api_ctx, id, conf_version .. "#" .. tostring(up_conf), up_conf)
local nodes_count = up_conf.nodes and #up_conf.nodes or 0
if nodes_count == 0 then
release_checker(up_conf.parent)
return HTTP_CODE_UPSTREAM_UNAVAILABLE, "no valid upstream node"
end
if not is_http then
local ok, err = fill_node_info(up_conf, nil, true)
if not ok then
return 503, err
end
local scheme = up_conf.scheme
if scheme == "tls" then
local ok, err = set_stream_upstream_tls()
if not ok then
return 503, err
end
local sni = apisix_ssl.server_name()
if sni then
ngx_var.upstream_sni = sni
end
end
return
end
set_upstream_scheme(api_ctx, up_conf)
local ok, err = fill_node_info(up_conf, api_ctx.upstream_scheme, false)
if not ok then
return 503, err
end
local checker = fetch_healthchecker(up_conf)
api_ctx.up_checker = checker
local scheme = up_conf.scheme
if (scheme == "https" or scheme == "grpcs") and up_conf.tls then
local client_cert, client_key
if up_conf.tls.client_cert_id then
client_cert = api_ctx.upstream_ssl.cert
client_key = api_ctx.upstream_ssl.key
else
client_cert = up_conf.tls.client_cert
client_key = up_conf.tls.client_key
end
local sni = api_ctx.var.upstream_host
local cert, err = apisix_ssl.fetch_cert(sni, client_cert)
if not ok then
return 503, err
end
local key, err = apisix_ssl.fetch_pkey(sni, client_key)
if not ok then
return 503, err
end
if scheme == "grpcs" then
api_ctx.upstream_grpcs_cert = cert
api_ctx.upstream_grpcs_key = key
else
local ok, err = set_upstream_tls_client_param(cert, key)
if not ok then
return 503, err
end
end
end
return
end